From 059ea519bcbb226390ee931b6acdbda2dbf0dd1c Mon Sep 17 00:00:00 2001 From: rogerman Date: Sat, 30 Sep 2017 23:54:05 -0700 Subject: [PATCH] Cocoa Port: Vastly improve the ability to take screenshots of the NDS displays. - The old Tools > Save Screenshot As has been replaced with the new Screenshot Capture Tool. - The new Screenshot Capture Tool allows screenshots to be configured to render with the same layout features as a display view. - Screenshot captures now both render and save to file on their own independent threads. - Screenshots are now captured using the Take Screenshot button, and files are now automatically named based on ROM name and timestamp. - All of these features means that users can now rapidly take screenshots with their own custom layouts, all with little to no slowdown to the emulation. - Also do a bunch of code cleanup and refactoring as a side-effect of adding these new features. --- .../src/frontend/cocoa/ClientDisplayView.cpp | 754 +-- .../src/frontend/cocoa/ClientDisplayView.h | 135 +- .../project.pbxproj | 10 + .../project.pbxproj | 14 + .../src/frontend/cocoa/DefaultUserPrefs.plist | 20 + .../src/frontend/cocoa/OGLDisplayOutput.cpp | 49 +- desmume/src/frontend/cocoa/OGLDisplayOutput.h | 6 +- desmume/src/frontend/cocoa/cocoa_GPU.h | 2 - desmume/src/frontend/cocoa/cocoa_GPU.mm | 19 +- desmume/src/frontend/cocoa/cocoa_globals.h | 3 +- desmume/src/frontend/cocoa/cocoa_output.h | 9 +- desmume/src/frontend/cocoa/cocoa_output.mm | 288 +- .../English.lproj/DisplayWindow.xib | 1173 +--- .../English.lproj/MainMenu.strings | Bin 383606 -> 406004 bytes .../translations/English.lproj/MainMenu.xib | 4700 ++++++++++++++++- .../cocoa/userinterface/DisplayViewCALayer.h | 45 +- .../cocoa/userinterface/DisplayViewCALayer.mm | 87 +- .../userinterface/DisplayWindowController.h | 12 +- .../userinterface/DisplayWindowController.mm | 202 +- .../userinterface/EmuControllerDelegate.h | 16 +- .../userinterface/EmuControllerDelegate.mm | 264 +- .../cocoa/userinterface/MacMetalDisplayView.h | 92 +- .../userinterface/MacMetalDisplayView.mm | 685 ++- .../cocoa/userinterface/MacOGLDisplayView.h | 44 +- .../cocoa/userinterface/MacOGLDisplayView.mm | 337 +- .../userinterface/MacScreenshotCaptureTool.h | 97 + .../userinterface/MacScreenshotCaptureTool.mm | 346 ++ .../cocoa/userinterface/appDelegate.h | 22 - .../cocoa/userinterface/appDelegate.mm | 275 +- 29 files changed, 6691 insertions(+), 3015 deletions(-) create mode 100644 desmume/src/frontend/cocoa/userinterface/MacScreenshotCaptureTool.h create mode 100644 desmume/src/frontend/cocoa/userinterface/MacScreenshotCaptureTool.mm diff --git a/desmume/src/frontend/cocoa/ClientDisplayView.cpp b/desmume/src/frontend/cocoa/ClientDisplayView.cpp index 8c0ead7cf..e3d61feeb 100644 --- a/desmume/src/frontend/cocoa/ClientDisplayView.cpp +++ b/desmume/src/frontend/cocoa/ClientDisplayView.cpp @@ -20,11 +20,11 @@ #include -ClientDisplayView::ClientDisplayView() +ClientDisplayPresenter::ClientDisplayPresenter() { _fetchObject = NULL; - ClientDisplayViewProperties defaultProperty; + ClientDisplayPresenterProperties defaultProperty; defaultProperty.normalWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH; defaultProperty.normalHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2.0; defaultProperty.clientWidth = defaultProperty.normalWidth; @@ -40,21 +40,18 @@ ClientDisplayView::ClientDisplayView() __InstanceInit(defaultProperty); } -ClientDisplayView::ClientDisplayView(const ClientDisplayViewProperties &props) +ClientDisplayPresenter::ClientDisplayPresenter(const ClientDisplayPresenterProperties &props) { __InstanceInit(props); } -ClientDisplayView::~ClientDisplayView() +ClientDisplayPresenter::~ClientDisplayPresenter() { delete this->_vf[NDSDisplayID_Main]; delete this->_vf[NDSDisplayID_Touch]; free_aligned(this->_vfMasterDstBuffer); this->_vfMasterDstBufferSize = 0; - delete this->_initialTouchInMajorDisplay; - this->_initialTouchInMajorDisplay = NULL; - if (this->_ftLibrary != NULL) { FT_Done_FreeType(this->_ftLibrary); @@ -64,11 +61,10 @@ ClientDisplayView::~ClientDisplayView() pthread_mutex_destroy(&this->_mutexHUDString); } -void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props) +void ClientDisplayPresenter::__InstanceInit(const ClientDisplayPresenterProperties &props) { _stagedProperty = props; _renderProperty = _stagedProperty; - _initialTouchInMajorDisplay = new InitialTouchPressMap; _useDeposterize = false; _pixelScaler = VideoFilterTypeID_None; @@ -81,12 +77,10 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props) _selectedSourceForDisplay[NDSDisplayID_Main] = NDSDisplayID_Main; _selectedSourceForDisplay[NDSDisplayID_Touch] = NDSDisplayID_Touch; - _displayViewID = 0; - _useVerticalSync = false; _scaleFactor = 1.0; _hudObjectScale = 1.0; - _isHUDVisible = true; + _isHUDVisible = false; _showVideoFPS = true; _showRender3DFPS = false; _showFrameIndex = false; @@ -113,14 +107,11 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props) _outHudString = _hudString; _hudInputString = "<^>vABXYLRSsgf x:000 y:000"; _hudNeedsUpdate = true; - _viewNeedsFlush = false; - _allowViewUpdates = true; - _allowViewFlushes = true; FT_Error error = FT_Init_FreeType(&_ftLibrary); if (error) { - printf("ClientDisplayView: FreeType failed to init!\n"); + printf("ClientDisplayPresenter: FreeType failed to init!\n"); } memset(_glyphInfo, 0, sizeof(_glyphInfo)); @@ -148,7 +139,12 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props) pthread_mutex_init(&_mutexHUDString, NULL); } -void ClientDisplayView::_UpdateHUDString() +void ClientDisplayPresenter::Init() +{ + // Do nothing. This is implementation dependent. +} + +void ClientDisplayPresenter::_UpdateHUDString() { std::ostringstream ss; ss << "\x01"; // This represents the text box. It must always be the first character. @@ -212,7 +208,7 @@ void ClientDisplayView::_UpdateHUDString() pthread_mutex_unlock(&this->_mutexHUDString); } -void ClientDisplayView::_SetHUDShowInfoItem(bool &infoItemFlag, const bool visibleState) +void ClientDisplayPresenter::_SetHUDShowInfoItem(bool &infoItemFlag, const bool visibleState) { if (infoItemFlag == visibleState) { @@ -223,43 +219,12 @@ void ClientDisplayView::_SetHUDShowInfoItem(bool &infoItemFlag, const bool visib this->_UpdateHUDString(); } -void ClientDisplayView::Init() -{ - // Do nothing. This is implementation dependent. -} - -int64_t ClientDisplayView::GetDisplayViewID() -{ - return this->_displayViewID; -} - -void ClientDisplayView::SetDisplayViewID(int64_t displayViewID) -{ - // This implementation-dependent value will never be used internally. - this->_displayViewID = displayViewID; -} - -bool ClientDisplayView::GetViewNeedsFlush() -{ - return this->_viewNeedsFlush; -} - -bool ClientDisplayView::GetUseVerticalSync() const -{ - return this->_useVerticalSync; -} - -void ClientDisplayView::SetUseVerticalSync(const bool useVerticalSync) -{ - this->_useVerticalSync = useVerticalSync; -} - -double ClientDisplayView::GetScaleFactor() const +double ClientDisplayPresenter::GetScaleFactor() const { return this->_scaleFactor; } -void ClientDisplayView::SetScaleFactor(const double scaleFactor) +void ClientDisplayPresenter::SetScaleFactor(const double scaleFactor) { const bool willChangeScaleFactor = (this->_scaleFactor != scaleFactor); this->_scaleFactor = scaleFactor; @@ -273,19 +238,19 @@ void ClientDisplayView::SetScaleFactor(const double scaleFactor) } } -void ClientDisplayView::_UpdateClientSize() +void ClientDisplayPresenter::_UpdateClientSize() { pthread_mutex_lock(&this->_mutexHUDString); this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); } -void ClientDisplayView::_UpdateViewScale() +void ClientDisplayPresenter::_UpdateViewScale() { double checkWidth = this->_renderProperty.normalWidth; double checkHeight = this->_renderProperty.normalHeight; - ClientDisplayView::ConvertNormalToTransformedBounds(1.0, this->_renderProperty.rotation, checkWidth, checkHeight); - this->_renderProperty.viewScale = ClientDisplayView::GetMaxScalarWithinBounds(checkWidth, checkHeight, this->_renderProperty.clientWidth, this->_renderProperty.clientHeight); + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, this->_renderProperty.rotation, checkWidth, checkHeight); + this->_renderProperty.viewScale = ClientDisplayPresenter::GetMaxScalarWithinBounds(checkWidth, checkHeight, this->_renderProperty.clientWidth, this->_renderProperty.clientHeight); this->_hudObjectScale = this->_renderProperty.clientWidth / this->_renderProperty.normalWidth; if (this->_hudObjectScale > 2.0) @@ -297,21 +262,21 @@ void ClientDisplayView::_UpdateViewScale() } // NDS screen layout -const ClientDisplayViewProperties& ClientDisplayView::GetViewProperties() const +const ClientDisplayPresenterProperties& ClientDisplayPresenter::GetPresenterProperties() const { return this->_renderProperty; } -void ClientDisplayView::CommitViewProperties(const ClientDisplayViewProperties &props) +void ClientDisplayPresenter::CommitPresenterProperties(const ClientDisplayPresenterProperties &props) { this->_stagedProperty = props; } -void ClientDisplayView::SetupViewProperties() +void ClientDisplayPresenter::SetupPresenterProperties() { // Validate the staged properties. this->_stagedProperty.gapDistance = (double)DS_DISPLAY_UNSCALED_GAP * this->_stagedProperty.gapScale; - ClientDisplayView::CalculateNormalSize(this->_stagedProperty.mode, this->_stagedProperty.layout, this->_stagedProperty.gapScale, this->_stagedProperty.normalWidth, this->_stagedProperty.normalHeight); + ClientDisplayPresenter::CalculateNormalSize(this->_stagedProperty.mode, this->_stagedProperty.layout, this->_stagedProperty.gapScale, this->_stagedProperty.normalWidth, this->_stagedProperty.normalHeight); const bool didNormalSizeChange = (this->_renderProperty.mode != this->_stagedProperty.mode) || (this->_renderProperty.layout != this->_stagedProperty.layout) || @@ -354,91 +319,91 @@ void ClientDisplayView::SetupViewProperties() this->_UpdateClientSize(); } - this->UpdateView(); + this->UpdateLayout(); } -double ClientDisplayView::GetRotation() const +double ClientDisplayPresenter::GetRotation() const { return this->_renderProperty.rotation; } -double ClientDisplayView::GetViewScale() const +double ClientDisplayPresenter::GetViewScale() const { return this->_renderProperty.viewScale; } -ClientDisplayMode ClientDisplayView::GetMode() const +ClientDisplayMode ClientDisplayPresenter::GetMode() const { return this->_renderProperty.mode; } -ClientDisplayLayout ClientDisplayView::GetLayout() const +ClientDisplayLayout ClientDisplayPresenter::GetLayout() const { return this->_renderProperty.layout; } -ClientDisplayOrder ClientDisplayView::GetOrder() const +ClientDisplayOrder ClientDisplayPresenter::GetOrder() const { return this->_renderProperty.order; } -double ClientDisplayView::GetGapScale() const +double ClientDisplayPresenter::GetGapScale() const { return this->_renderProperty.gapScale; } -double ClientDisplayView::GetGapDistance() const +double ClientDisplayPresenter::GetGapDistance() const { return this->_renderProperty.gapDistance; } -ClientDisplaySource ClientDisplayView::GetDisplayVideoSource(const NDSDisplayID displayID) const +ClientDisplaySource ClientDisplayPresenter::GetDisplayVideoSource(const NDSDisplayID displayID) const { return this->_displaySourceSelect[displayID]; } -void ClientDisplayView::SetDisplayVideoSource(const NDSDisplayID displayID, ClientDisplaySource displaySrc) +void ClientDisplayPresenter::SetDisplayVideoSource(const NDSDisplayID displayID, ClientDisplaySource displaySrc) { this->_displaySourceSelect[displayID] = displaySrc; } -NDSDisplayID ClientDisplayView::GetSelectedDisplaySourceForDisplay(const NDSDisplayID displayID) const +NDSDisplayID ClientDisplayPresenter::GetSelectedDisplaySourceForDisplay(const NDSDisplayID displayID) const { return this->_selectedSourceForDisplay[displayID]; } -bool ClientDisplayView::IsSelectedDisplayEnabled(const NDSDisplayID displayID) const +bool ClientDisplayPresenter::IsSelectedDisplayEnabled(const NDSDisplayID displayID) const { return this->_isSelectedDisplayEnabled[displayID]; } // NDS screen filters -bool ClientDisplayView::GetSourceDeposterize() +bool ClientDisplayPresenter::GetSourceDeposterize() { return this->_useDeposterize; } -void ClientDisplayView::SetSourceDeposterize(const bool useDeposterize) +void ClientDisplayPresenter::SetSourceDeposterize(const bool useDeposterize) { this->_useDeposterize = useDeposterize; } -OutputFilterTypeID ClientDisplayView::GetOutputFilter() const +OutputFilterTypeID ClientDisplayPresenter::GetOutputFilter() const { return this->_outputFilter; } -void ClientDisplayView::SetOutputFilter(const OutputFilterTypeID filterID) +void ClientDisplayPresenter::SetOutputFilter(const OutputFilterTypeID filterID) { this->_outputFilter = filterID; } -VideoFilterTypeID ClientDisplayView::GetPixelScaler() const +VideoFilterTypeID ClientDisplayPresenter::GetPixelScaler() const { return this->_pixelScaler; } -void ClientDisplayView::SetPixelScaler(const VideoFilterTypeID filterID) +void ClientDisplayPresenter::SetPixelScaler(const VideoFilterTypeID filterID) { std::string cpuTypeIDString = std::string( VideoFilter::GetTypeStringByID(filterID) ); const VideoFilterTypeID newFilterID = (cpuTypeIDString != std::string(VIDEOFILTERTYPE_UNKNOWN_STRING)) ? filterID : VideoFilterTypeID_None; @@ -465,23 +430,23 @@ void ClientDisplayView::SetPixelScaler(const VideoFilterTypeID filterID) free_aligned(oldMasterBuffer); } -VideoFilter* ClientDisplayView::GetPixelScalerObject(const NDSDisplayID displayID) +VideoFilter* ClientDisplayPresenter::GetPixelScalerObject(const NDSDisplayID displayID) { return this->_vf[displayID]; } // HUD appearance -const char* ClientDisplayView::GetHUDFontPath() const +const char* ClientDisplayPresenter::GetHUDFontPath() const { return this->_lastFontFilePath; } -void ClientDisplayView::SetHUDFontPath(const char *filePath) +void ClientDisplayPresenter::SetHUDFontPath(const char *filePath) { this->_lastFontFilePath = filePath; } -void ClientDisplayView::LoadHUDFont() +void ClientDisplayPresenter::LoadHUDFont() { if (this->_lastFontFilePath == NULL) { @@ -494,12 +459,12 @@ void ClientDisplayView::LoadHUDFont() error = FT_New_Face(this->_ftLibrary, this->_lastFontFilePath, 0, &fontFace); if (error == FT_Err_Unknown_File_Format) { - printf("ClientDisplayView: FreeType failed to load font face because it is in an unknown format from:\n%s\n", this->_lastFontFilePath); + printf("ClientDisplayPresenter: FreeType failed to load font face because it is in an unknown format from:\n%s\n", this->_lastFontFilePath); return; } else if (error) { - printf("ClientDisplayView: FreeType failed to load font face with an unknown error from:\n%s\n", this->_lastFontFilePath); + printf("ClientDisplayPresenter: FreeType failed to load font face with an unknown error from:\n%s\n", this->_lastFontFilePath); return; } @@ -508,12 +473,12 @@ void ClientDisplayView::LoadHUDFont() FT_Done_Face(fontFace); } -void ClientDisplayView::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo) +void ClientDisplayPresenter::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo) { // Do nothing. This is implementation dependent. } -void ClientDisplayView::SetHUDInfo(const ClientFrameInfo &clientFrameInfo, const NDSFrameInfo &ndsFrameInfo) +void ClientDisplayPresenter::SetHUDInfo(const ClientFrameInfo &clientFrameInfo, const NDSFrameInfo &ndsFrameInfo) { this->_clientFrameInfo.videoFPS = clientFrameInfo.videoFPS; this->_ndsFrameInfo.copyFrom(ndsFrameInfo); @@ -521,7 +486,7 @@ void ClientDisplayView::SetHUDInfo(const ClientFrameInfo &clientFrameInfo, const this->_UpdateHUDString(); } -const std::string& ClientDisplayView::GetHUDString() +const std::string& ClientDisplayPresenter::GetHUDString() { pthread_mutex_lock(&this->_mutexHUDString); this->_outHudString = this->_hudString; @@ -530,110 +495,110 @@ const std::string& ClientDisplayView::GetHUDString() return this->_outHudString; } -float ClientDisplayView::GetHUDObjectScale() const +float ClientDisplayPresenter::GetHUDObjectScale() const { return this->_hudObjectScale; } -void ClientDisplayView::SetHUDObjectScale(float objectScale) +void ClientDisplayPresenter::SetHUDObjectScale(float objectScale) { this->_hudObjectScale = objectScale; } -bool ClientDisplayView::GetHUDVisibility() const +bool ClientDisplayPresenter::GetHUDVisibility() const { return this->_isHUDVisible; } -void ClientDisplayView::SetHUDVisibility(const bool visibleState) +void ClientDisplayPresenter::SetHUDVisibility(const bool visibleState) { this->_isHUDVisible = visibleState; - this->UpdateView(); + this->UpdateLayout(); } -bool ClientDisplayView::GetHUDShowVideoFPS() const +bool ClientDisplayPresenter::GetHUDShowVideoFPS() const { return this->_showVideoFPS; } -void ClientDisplayView::SetHUDShowVideoFPS(const bool visibleState) +void ClientDisplayPresenter::SetHUDShowVideoFPS(const bool visibleState) { this->_SetHUDShowInfoItem(this->_showVideoFPS, visibleState); - this->UpdateView(); + this->UpdateLayout(); } -bool ClientDisplayView::GetHUDShowRender3DFPS() const +bool ClientDisplayPresenter::GetHUDShowRender3DFPS() const { return this->_showRender3DFPS; } -void ClientDisplayView::SetHUDShowRender3DFPS(const bool visibleState) +void ClientDisplayPresenter::SetHUDShowRender3DFPS(const bool visibleState) { this->_SetHUDShowInfoItem(this->_showRender3DFPS, visibleState); - this->UpdateView(); + this->UpdateLayout(); } -bool ClientDisplayView::GetHUDShowFrameIndex() const +bool ClientDisplayPresenter::GetHUDShowFrameIndex() const { return this->_showFrameIndex; } -void ClientDisplayView::SetHUDShowFrameIndex(const bool visibleState) +void ClientDisplayPresenter::SetHUDShowFrameIndex(const bool visibleState) { this->_SetHUDShowInfoItem(this->_showFrameIndex, visibleState); - this->UpdateView(); + this->UpdateLayout(); } -bool ClientDisplayView::GetHUDShowLagFrameCount() const +bool ClientDisplayPresenter::GetHUDShowLagFrameCount() const { return this->_showLagFrameCount; } -void ClientDisplayView::SetHUDShowLagFrameCount(const bool visibleState) +void ClientDisplayPresenter::SetHUDShowLagFrameCount(const bool visibleState) { this->_SetHUDShowInfoItem(this->_showLagFrameCount, visibleState); - this->UpdateView(); + this->UpdateLayout(); } -bool ClientDisplayView::GetHUDShowCPULoadAverage() const +bool ClientDisplayPresenter::GetHUDShowCPULoadAverage() const { return this->_showCPULoadAverage; } -void ClientDisplayView::SetHUDShowCPULoadAverage(const bool visibleState) +void ClientDisplayPresenter::SetHUDShowCPULoadAverage(const bool visibleState) { this->_SetHUDShowInfoItem(this->_showCPULoadAverage, visibleState); - this->UpdateView(); + this->UpdateLayout(); } -bool ClientDisplayView::GetHUDShowRTC() const +bool ClientDisplayPresenter::GetHUDShowRTC() const { return this->_showRTC; } -void ClientDisplayView::SetHUDShowRTC(const bool visibleState) +void ClientDisplayPresenter::SetHUDShowRTC(const bool visibleState) { this->_SetHUDShowInfoItem(this->_showRTC, visibleState); - this->UpdateView(); + this->UpdateLayout(); } -bool ClientDisplayView::GetHUDShowInput() const +bool ClientDisplayPresenter::GetHUDShowInput() const { return this->_showInputs; } -void ClientDisplayView::SetHUDShowInput(const bool visibleState) +void ClientDisplayPresenter::SetHUDShowInput(const bool visibleState) { this->_SetHUDShowInfoItem(this->_showInputs, visibleState); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetHUDColorVideoFPS() const +uint32_t ClientDisplayPresenter::GetHUDColorVideoFPS() const { return this->_hudColorVideoFPS; } -void ClientDisplayView::SetHUDColorVideoFPS(uint32_t color32) +void ClientDisplayPresenter::SetHUDColorVideoFPS(uint32_t color32) { this->_hudColorVideoFPS = color32; @@ -641,15 +606,15 @@ void ClientDisplayView::SetHUDColorVideoFPS(uint32_t color32) this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetHUDColorRender3DFPS() const +uint32_t ClientDisplayPresenter::GetHUDColorRender3DFPS() const { return this->_hudColorRender3DFPS; } -void ClientDisplayView::SetHUDColorRender3DFPS(uint32_t color32) +void ClientDisplayPresenter::SetHUDColorRender3DFPS(uint32_t color32) { this->_hudColorRender3DFPS = color32; @@ -657,15 +622,15 @@ void ClientDisplayView::SetHUDColorRender3DFPS(uint32_t color32) this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetHUDColorFrameIndex() const +uint32_t ClientDisplayPresenter::GetHUDColorFrameIndex() const { return this->_hudColorFrameIndex; } -void ClientDisplayView::SetHUDColorFrameIndex(uint32_t color32) +void ClientDisplayPresenter::SetHUDColorFrameIndex(uint32_t color32) { this->_hudColorFrameIndex = color32; @@ -673,15 +638,15 @@ void ClientDisplayView::SetHUDColorFrameIndex(uint32_t color32) this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetHUDColorLagFrameCount() const +uint32_t ClientDisplayPresenter::GetHUDColorLagFrameCount() const { return this->_hudColorLagFrameCount; } -void ClientDisplayView::SetHUDColorLagFrameCount(uint32_t color32) +void ClientDisplayPresenter::SetHUDColorLagFrameCount(uint32_t color32) { this->_hudColorLagFrameCount = color32; @@ -689,15 +654,15 @@ void ClientDisplayView::SetHUDColorLagFrameCount(uint32_t color32) this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetHUDColorCPULoadAverage() const +uint32_t ClientDisplayPresenter::GetHUDColorCPULoadAverage() const { return this->_hudColorCPULoadAverage; } -void ClientDisplayView::SetHUDColorCPULoadAverage(uint32_t color32) +void ClientDisplayPresenter::SetHUDColorCPULoadAverage(uint32_t color32) { this->_hudColorCPULoadAverage = color32; @@ -705,15 +670,15 @@ void ClientDisplayView::SetHUDColorCPULoadAverage(uint32_t color32) this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetHUDColorRTC() const +uint32_t ClientDisplayPresenter::GetHUDColorRTC() const { return this->_hudColorRTC; } -void ClientDisplayView::SetHUDColorRTC(uint32_t color32) +void ClientDisplayPresenter::SetHUDColorRTC(uint32_t color32) { this->_hudColorRTC = color32; @@ -721,15 +686,15 @@ void ClientDisplayView::SetHUDColorRTC(uint32_t color32) this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetHUDColorInputPendingAndApplied() const +uint32_t ClientDisplayPresenter::GetHUDColorInputPendingAndApplied() const { return this->_hudColorInputAppliedAndPending; } -void ClientDisplayView::SetHUDColorInputPendingAndApplied(uint32_t color32) +void ClientDisplayPresenter::SetHUDColorInputPendingAndApplied(uint32_t color32) { this->_hudColorInputAppliedAndPending = color32; @@ -737,15 +702,15 @@ void ClientDisplayView::SetHUDColorInputPendingAndApplied(uint32_t color32) this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetHUDColorInputAppliedOnly() const +uint32_t ClientDisplayPresenter::GetHUDColorInputAppliedOnly() const { return this->_hudColorInputAppliedOnly; } -void ClientDisplayView::SetHUDColorInputAppliedOnly(uint32_t color32) +void ClientDisplayPresenter::SetHUDColorInputAppliedOnly(uint32_t color32) { this->_hudColorInputAppliedOnly = color32; @@ -753,15 +718,15 @@ void ClientDisplayView::SetHUDColorInputAppliedOnly(uint32_t color32) this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetHUDColorInputPendingOnly() const +uint32_t ClientDisplayPresenter::GetHUDColorInputPendingOnly() const { return this->_hudColorInputPendingOnly; } -void ClientDisplayView::SetHUDColorInputPendingOnly(uint32_t color32) +void ClientDisplayPresenter::SetHUDColorInputPendingOnly(uint32_t color32) { this->_hudColorInputPendingOnly = color32; @@ -769,10 +734,10 @@ void ClientDisplayView::SetHUDColorInputPendingOnly(uint32_t color32) this->_hudNeedsUpdate = true; pthread_mutex_unlock(&this->_mutexHUDString); - this->UpdateView(); + this->UpdateLayout(); } -uint32_t ClientDisplayView::GetInputColorUsingStates(bool pendingState, bool appliedState) +uint32_t ClientDisplayPresenter::GetInputColorUsingStates(bool pendingState, bool appliedState) { uint32_t color = this->_hudColorInputAppliedAndPending; @@ -796,7 +761,7 @@ uint32_t ClientDisplayView::GetInputColorUsingStates(bool pendingState, bool app return color; } -bool ClientDisplayView::HUDNeedsUpdate() +bool ClientDisplayPresenter::HUDNeedsUpdate() { pthread_mutex_lock(&this->_mutexHUDString); const bool needsUpdate = this->_hudNeedsUpdate; @@ -805,7 +770,7 @@ bool ClientDisplayView::HUDNeedsUpdate() return needsUpdate; } -void ClientDisplayView::ClearHUDNeedsUpdate() +void ClientDisplayPresenter::ClearHUDNeedsUpdate() { pthread_mutex_lock(&this->_mutexHUDString); this->_hudNeedsUpdate = false; @@ -813,47 +778,27 @@ void ClientDisplayView::ClearHUDNeedsUpdate() } // NDS GPU Interface -const GPUClientFetchObject& ClientDisplayView::GetFetchObject() const +const GPUClientFetchObject& ClientDisplayPresenter::GetFetchObject() const { return *this->_fetchObject; } -void ClientDisplayView::SetFetchObject(GPUClientFetchObject *fetchObject) +void ClientDisplayPresenter::SetFetchObject(GPUClientFetchObject *fetchObject) { this->_fetchObject = fetchObject; } -bool ClientDisplayView::GetAllowViewUpdates() const -{ - return this->_allowViewUpdates; -} - -void ClientDisplayView::SetAllowViewUpdates(bool allowUpdates) -{ - this->_allowViewUpdates = allowUpdates; -} - -bool ClientDisplayView::GetAllowViewFlushes() const -{ - return this->_allowViewFlushes; -} - -void ClientDisplayView::SetAllowViewFlushes(bool allowFlushes) -{ - this->_allowViewFlushes = allowFlushes; -} - -void ClientDisplayView::_LoadNativeDisplayByID(const NDSDisplayID displayID) +void ClientDisplayPresenter::_LoadNativeDisplayByID(const NDSDisplayID displayID) { // Do nothing. This is implementation dependent. } -void ClientDisplayView::_LoadCustomDisplayByID(const NDSDisplayID displayID) +void ClientDisplayPresenter::_LoadCustomDisplayByID(const NDSDisplayID displayID) { // Do nothing. This is implementation dependent. } -void ClientDisplayView::LoadDisplays() +void ClientDisplayPresenter::LoadDisplays() { this->_emuDisplayInfo = this->_fetchObject->GetFetchDisplayInfoForBufferIndex(this->_fetchObject->GetLastFetchIndex()); @@ -980,7 +925,7 @@ void ClientDisplayView::LoadDisplays() } } -void ClientDisplayView::_ResizeCPUPixelScaler(const VideoFilterTypeID filterID) +void ClientDisplayPresenter::_ResizeCPUPixelScaler(const VideoFilterTypeID filterID) { const VideoFilterAttributes newFilterAttr = VideoFilter::GetAttributesByID(filterID); const size_t newDstBufferWidth = (this->_vf[NDSDisplayID_Main]->GetSrcWidth() + this->_vf[NDSDisplayID_Touch]->GetSrcWidth()) * newFilterAttr.scaleMultiply / newFilterAttr.scaleDivide; @@ -1000,139 +945,36 @@ void ClientDisplayView::_ResizeCPUPixelScaler(const VideoFilterTypeID filterID) this->_vfMasterDstBufferSize = newMasterBufferSize; } -void ClientDisplayView::ProcessDisplays() +void ClientDisplayPresenter::ProcessDisplays() { // Do nothing. This is implementation dependent. } -void ClientDisplayView::UpdateView() -{ - // Do nothing. This is implementation dependent. - this->_viewNeedsFlush = true; -} - -void ClientDisplayView::FlushView() -{ - // Do nothing. This is implementation dependent. - this->_viewNeedsFlush = false; -} - -void ClientDisplayView::CopyFrameToBuffer(uint32_t *dstBuffer) +void ClientDisplayPresenter::UpdateLayout() { // Do nothing. This is implementation dependent. } -void ClientDisplayView::FinishFrameAtIndex(const uint8_t bufferIndex) +void ClientDisplayPresenter::CopyFrameToBuffer(uint32_t *dstBuffer) { // Do nothing. This is implementation dependent. } -const NDSDisplayInfo& ClientDisplayView::GetEmuDisplayInfo() const +void ClientDisplayPresenter::FinishFrameAtIndex(const uint8_t bufferIndex) +{ + // Do nothing. This is implementation dependent. +} + +const NDSDisplayInfo& ClientDisplayPresenter::GetEmuDisplayInfo() const { return this->_emuDisplayInfo; } -void ClientDisplayView::SetEmuDisplayInfo(const NDSDisplayInfo &ndsDisplayInfo) +void ClientDisplayPresenter::SetEmuDisplayInfo(const NDSDisplayInfo &ndsDisplayInfo) { this->_emuDisplayInfo = ndsDisplayInfo; } -void ClientDisplayView::HandleEmulatorFrameEndEvent() -{ - this->UpdateView(); -} - -// Touch screen input handling -void ClientDisplayView::GetNDSPoint(const int inputID, const bool isInitialTouchPress, - const double clientX, const double clientY, - u8 &outX, u8 &outY) const -{ - double x = clientX; - double y = clientY; - double w = this->_renderProperty.normalWidth; - double h = this->_renderProperty.normalHeight; - const double logicalClientWidth = this->_renderProperty.clientWidth / this->_scaleFactor; - const double logicalClientHeight = this->_renderProperty.clientHeight / this->_scaleFactor; - - ClientDisplayView::ConvertNormalToTransformedBounds(1.0, this->_renderProperty.rotation, w, h); - const double s = ClientDisplayView::GetMaxScalarWithinBounds(w, h, logicalClientWidth, logicalClientHeight); - - ClientDisplayView::ConvertClientToNormalPoint(this->_renderProperty.normalWidth, this->_renderProperty.normalHeight, - logicalClientWidth, logicalClientHeight, - s, - this->_renderProperty.rotation, - x, y); - - // Normalize the touch location to the DS. - if (this->_renderProperty.mode == ClientDisplayMode_Dual) - { - switch (this->_renderProperty.layout) - { - case ClientDisplayLayout_Horizontal: - { - if (this->_renderProperty.order == ClientDisplayOrder_MainFirst) - { - x -= GPU_FRAMEBUFFER_NATIVE_WIDTH; - } - break; - } - - case ClientDisplayLayout_Hybrid_2_1: - case ClientDisplayLayout_Hybrid_16_9: - case ClientDisplayLayout_Hybrid_16_10: - { - if (isInitialTouchPress) - { - const bool isClickWithinMajorDisplay = (this->_renderProperty.order == ClientDisplayOrder_TouchFirst) && (x >= 0.0) && (x < 256.0); - (*_initialTouchInMajorDisplay)[inputID] = isClickWithinMajorDisplay; - } - - const bool handleClickInMajorDisplay = (*_initialTouchInMajorDisplay)[inputID]; - if (!handleClickInMajorDisplay) - { - const double minorDisplayScale = (this->_renderProperty.normalWidth - (double)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (double)GPU_FRAMEBUFFER_NATIVE_WIDTH; - x = (x - GPU_FRAMEBUFFER_NATIVE_WIDTH) / minorDisplayScale; - y = y / minorDisplayScale; - } - break; - } - - default: // Default to vertical orientation. - { - if (this->_renderProperty.order == ClientDisplayOrder_TouchFirst) - { - y -= ((double)GPU_FRAMEBUFFER_NATIVE_HEIGHT + this->_renderProperty.gapDistance); - } - break; - } - } - } - - y = GPU_FRAMEBUFFER_NATIVE_HEIGHT - y; - - // Constrain the touch point to the DS dimensions. - if (x < 0.0) - { - x = 0.0; - } - else if (x > (GPU_FRAMEBUFFER_NATIVE_WIDTH - 1.0)) - { - x = (GPU_FRAMEBUFFER_NATIVE_WIDTH - 1.0); - } - - if (y < 0.0) - { - y = 0.0; - } - else if (y > (GPU_FRAMEBUFFER_NATIVE_HEIGHT - 1.0)) - { - y = (GPU_FRAMEBUFFER_NATIVE_HEIGHT - 1.0); - } - - outX = (u8)(x + 0.001); - outY = (u8)(y + 0.001); -} - /******************************************************************************************** ConvertNormalToTransformedBounds() @@ -1152,9 +994,9 @@ void ClientDisplayView::GetNDSPoint(const int inputID, const bool isInitialTouch returned bounds will always be at its smallest when the angle is at 0, 90, 180, or 270 degrees, and largest when the angle is at 45, 135, 225, or 315 degrees. ********************************************************************************************/ -void ClientDisplayView::ConvertNormalToTransformedBounds(const double scalar, - const double angleDegrees, - double &inoutWidth, double &inoutHeight) +void ClientDisplayPresenter::ConvertNormalToTransformedBounds(const double scalar, + const double angleDegrees, + double &inoutWidth, double &inoutHeight) { const double angleRadians = angleDegrees * (M_PI/180.0); @@ -1290,8 +1132,8 @@ void ClientDisplayView::ConvertNormalToTransformedBounds(const double scalar, If keepInBoundsWidth or keepInBoundsHeight are less than or equal to zero, the returned scalar will be zero. ********************************************************************************************/ -double ClientDisplayView::GetMaxScalarWithinBounds(const double normalBoundsWidth, const double normalBoundsHeight, - const double keepInBoundsWidth, const double keepInBoundsHeight) +double ClientDisplayPresenter::GetMaxScalarWithinBounds(const double normalBoundsWidth, const double normalBoundsHeight, + const double keepInBoundsWidth, const double keepInBoundsHeight) { const double maxX = (normalBoundsWidth <= 0.0) ? 0.0 : keepInBoundsWidth / normalBoundsWidth; const double maxY = (normalBoundsHeight <= 0.0) ? 0.0 : keepInBoundsHeight / normalBoundsHeight; @@ -1299,6 +1141,212 @@ double ClientDisplayView::GetMaxScalarWithinBounds(const double normalBoundsWidt return (maxX <= maxY) ? maxX : maxY; } +void ClientDisplayPresenter::CalculateNormalSize(const ClientDisplayMode mode, const ClientDisplayLayout layout, const double gapScale, + double &outWidth, double &outHeight) +{ + if (mode == ClientDisplayMode_Dual) + { + switch (layout) + { + case ClientDisplayLayout_Horizontal: + outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH*2.0; + outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; + break; + + case ClientDisplayLayout_Hybrid_2_1: + outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH + (128.0); + outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; + break; + + case ClientDisplayLayout_Hybrid_16_9: + outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH + (64.0 * 4.0 / 3.0); + outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; + break; + + case ClientDisplayLayout_Hybrid_16_10: + outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH + (51.2); + outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; + break; + + default: // Default to vertical orientation. + outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH; + outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT*2.0 + (DS_DISPLAY_UNSCALED_GAP*gapScale); + break; + } + } + else + { + outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH; + outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; + } +} + +ClientDisplayViewInterface::ClientDisplayViewInterface() +{ + _displayViewID = 0; + _useVerticalSync = false; + _viewNeedsFlush = false; + _allowViewUpdates = true; + _allowViewFlushes = true; + + _initialTouchInMajorDisplay = new InitialTouchPressMap; +} + +ClientDisplayViewInterface::~ClientDisplayViewInterface() +{ + delete this->_initialTouchInMajorDisplay; + this->_initialTouchInMajorDisplay = NULL; +} + +int64_t ClientDisplayViewInterface::GetDisplayViewID() +{ + return this->_displayViewID; +} + +void ClientDisplayViewInterface::SetDisplayViewID(int64_t displayViewID) +{ + // This implementation-dependent value will never be used internally. + this->_displayViewID = displayViewID; +} + +bool ClientDisplayViewInterface::GetViewNeedsFlush() +{ + return this->_viewNeedsFlush; +} + +void ClientDisplayViewInterface::SetViewNeedsFlush() +{ + // Do nothing. This is implementation dependent. + this->_viewNeedsFlush = true; +} + +bool ClientDisplayViewInterface::GetUseVerticalSync() const +{ + return this->_useVerticalSync; +} + +void ClientDisplayViewInterface::SetUseVerticalSync(const bool useVerticalSync) +{ + this->_useVerticalSync = useVerticalSync; +} + +bool ClientDisplayViewInterface::GetAllowViewUpdates() const +{ + return this->_allowViewUpdates; +} + +void ClientDisplayViewInterface::SetAllowViewUpdates(bool allowUpdates) +{ + this->_allowViewUpdates = allowUpdates; +} + +bool ClientDisplayViewInterface::GetAllowViewFlushes() const +{ + return this->_allowViewFlushes; +} + +void ClientDisplayViewInterface::SetAllowViewFlushes(bool allowFlushes) +{ + this->_allowViewFlushes = allowFlushes; +} + +void ClientDisplayViewInterface::FlushView() +{ + // Do nothing. This is implementation dependent. + this->_viewNeedsFlush = false; +} + +// Touch screen input handling +void ClientDisplayViewInterface::GetNDSPoint(const ClientDisplayPresenterProperties &props, + const double logicalClientWidth, const double logicalClientHeight, + const int inputID, const bool isInitialTouchPress, + const double clientX, const double clientY, + uint8_t &outX, uint8_t &outY) const +{ + double x = clientX; + double y = clientY; + double w = props.normalWidth; + double h = props.normalHeight; + + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, props.rotation, w, h); + const double s = ClientDisplayPresenter::GetMaxScalarWithinBounds(w, h, logicalClientWidth, logicalClientHeight); + + ClientDisplayViewInterface::ConvertClientToNormalPoint(props.normalWidth, props.normalHeight, + logicalClientWidth, logicalClientHeight, + s, + props.rotation, + x, y); + + // Normalize the touch location to the DS. + if (props.mode == ClientDisplayMode_Dual) + { + switch (props.layout) + { + case ClientDisplayLayout_Horizontal: + { + if (props.order == ClientDisplayOrder_MainFirst) + { + x -= GPU_FRAMEBUFFER_NATIVE_WIDTH; + } + break; + } + + case ClientDisplayLayout_Hybrid_2_1: + case ClientDisplayLayout_Hybrid_16_9: + case ClientDisplayLayout_Hybrid_16_10: + { + if (isInitialTouchPress) + { + const bool isClickWithinMajorDisplay = (props.order == ClientDisplayOrder_TouchFirst) && (x >= 0.0) && (x < 256.0); + (*_initialTouchInMajorDisplay)[inputID] = isClickWithinMajorDisplay; + } + + const bool handleClickInMajorDisplay = (*_initialTouchInMajorDisplay)[inputID]; + if (!handleClickInMajorDisplay) + { + const double minorDisplayScale = (props.normalWidth - (double)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (double)GPU_FRAMEBUFFER_NATIVE_WIDTH; + x = (x - GPU_FRAMEBUFFER_NATIVE_WIDTH) / minorDisplayScale; + y = y / minorDisplayScale; + } + break; + } + + default: // Default to vertical orientation. + { + if (props.order == ClientDisplayOrder_TouchFirst) + { + y -= ((double)GPU_FRAMEBUFFER_NATIVE_HEIGHT + props.gapDistance); + } + break; + } + } + } + + y = GPU_FRAMEBUFFER_NATIVE_HEIGHT - y; + + // Constrain the touch point to the DS dimensions. + if (x < 0.0) + { + x = 0.0; + } + else if (x > (GPU_FRAMEBUFFER_NATIVE_WIDTH - 1.0)) + { + x = (GPU_FRAMEBUFFER_NATIVE_WIDTH - 1.0); + } + + if (y < 0.0) + { + y = 0.0; + } + else if (y > (GPU_FRAMEBUFFER_NATIVE_HEIGHT - 1.0)) + { + y = (GPU_FRAMEBUFFER_NATIVE_HEIGHT - 1.0); + } + + outX = (u8)(x + 0.001); + outY = (u8)(y + 0.001); +} + /******************************************************************************************** ConvertClientToNormalPoint() @@ -1320,11 +1368,11 @@ double ClientDisplayView::GetMaxScalarWithinBounds(const double normalBoundsWidt Details: It may help to call GetMaxScalarWithinBounds() for the scalar parameter. ********************************************************************************************/ -void ClientDisplayView::ConvertClientToNormalPoint(const double normalWidth, const double normalHeight, - const double clientWidth, const double clientHeight, - const double scalar, - const double angleDegrees, - double &inoutX, double &inoutY) +void ClientDisplayViewInterface::ConvertClientToNormalPoint(const double normalWidth, const double normalHeight, + const double clientWidth, const double clientHeight, + const double scalar, + const double angleDegrees, + double &inoutX, double &inoutY) { // Get the coordinates of the client point and translate the coordinate // system so that the origin becomes the center. @@ -1372,79 +1420,49 @@ void ClientDisplayView::ConvertClientToNormalPoint(const double normalWidth, con inoutY = (r * sin(normalizedAngle)) + (normalHeight / 2.0); } -void ClientDisplayView::CalculateNormalSize(const ClientDisplayMode mode, const ClientDisplayLayout layout, const double gapScale, - double &outWidth, double &outHeight) +ClientDisplay3DPresenter::ClientDisplay3DPresenter() { - if (mode == ClientDisplayMode_Dual) - { - switch (layout) - { - case ClientDisplayLayout_Horizontal: - outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH*2.0; - outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; - break; - - case ClientDisplayLayout_Hybrid_2_1: - outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH + (128.0); - outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; - break; - - case ClientDisplayLayout_Hybrid_16_9: - outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH + (64.0 * 4.0 / 3.0); - outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; - break; - - case ClientDisplayLayout_Hybrid_16_10: - outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH + (51.2); - outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; - break; - - default: // Default to vertical orientation. - outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH; - outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT*2.0 + (DS_DISPLAY_UNSCALED_GAP*gapScale); - break; - } - } - else - { - outWidth = (double)GPU_FRAMEBUFFER_NATIVE_WIDTH; - outHeight = (double)GPU_FRAMEBUFFER_NATIVE_HEIGHT; - } + __InstanceInit(); } -ClientDisplay3DView::ClientDisplay3DView() +ClientDisplay3DPresenter::ClientDisplay3DPresenter(const ClientDisplayPresenterProperties &props) : ClientDisplayPresenter(props) +{ + __InstanceInit(); +} + +void ClientDisplay3DPresenter::__InstanceInit() { _canFilterOnGPU = false; _willFilterOnGPU = false; _filtersPreferGPU = false; } -bool ClientDisplay3DView::CanFilterOnGPU() const +bool ClientDisplay3DPresenter::CanFilterOnGPU() const { return this->_canFilterOnGPU; } -bool ClientDisplay3DView::WillFilterOnGPU() const +bool ClientDisplay3DPresenter::WillFilterOnGPU() const { return this->_willFilterOnGPU; } -bool ClientDisplay3DView::GetFiltersPreferGPU() const +bool ClientDisplay3DPresenter::GetFiltersPreferGPU() const { return this->_filtersPreferGPU; } -void ClientDisplay3DView::SetFiltersPreferGPU(const bool preferGPU) +void ClientDisplay3DPresenter::SetFiltersPreferGPU(const bool preferGPU) { this->_filtersPreferGPU = preferGPU; } -void ClientDisplay3DView::SetSourceDeposterize(bool useDeposterize) +void ClientDisplay3DPresenter::SetSourceDeposterize(bool useDeposterize) { this->_useDeposterize = (this->_canFilterOnGPU) ? useDeposterize : false; } -void ClientDisplay3DView::SetHUDPositionVertices(float viewportWidth, float viewportHeight, float *vtxPositionBufferPtr) +void ClientDisplay3DPresenter::SetHUDPositionVertices(float viewportWidth, float viewportHeight, float *vtxPositionBufferPtr) { pthread_mutex_lock(&this->_mutexHUDString); std::string hudString = this->_hudString; @@ -1574,7 +1592,7 @@ void ClientDisplay3DView::SetHUDPositionVertices(float viewportWidth, float view this->SetHUDTouchLinePositionVertices(vtxPositionBufferPtr + j); } -void ClientDisplay3DView::SetHUDTouchLinePositionVertices(float *vtxBufferPtr) +void ClientDisplay3DPresenter::SetHUDTouchLinePositionVertices(float *vtxBufferPtr) { const float x = (this->_ndsFrameInfo.inputStatesApplied.Touch == 0) ? this->_ndsFrameInfo.touchLocXApplied : this->_ndsFrameInfo.touchLocXPending; const float y = 191.0f - ((this->_ndsFrameInfo.inputStatesApplied.Touch == 0) ? this->_ndsFrameInfo.touchLocYApplied : this->_ndsFrameInfo.touchLocYPending); @@ -1759,7 +1777,7 @@ void ClientDisplay3DView::SetHUDTouchLinePositionVertices(float *vtxBufferPtr) } } -void ClientDisplay3DView::SetHUDColorVertices(uint32_t *vtxColorBufferPtr) +void ClientDisplay3DPresenter::SetHUDColorVertices(uint32_t *vtxColorBufferPtr) { pthread_mutex_lock(&this->_mutexHUDString); std::string hudString = this->_hudString; @@ -1910,7 +1928,7 @@ void ClientDisplay3DView::SetHUDColorVertices(uint32_t *vtxColorBufferPtr) } } -void ClientDisplay3DView::SetHUDTextureCoordinates(float *texCoordBufferPtr) +void ClientDisplay3DPresenter::SetHUDTextureCoordinates(float *texCoordBufferPtr) { pthread_mutex_lock(&this->_mutexHUDString); std::string hudString = this->_hudString; @@ -1971,7 +1989,7 @@ void ClientDisplay3DView::SetHUDTextureCoordinates(float *texCoordBufferPtr) } } -void ClientDisplay3DView::SetScreenVertices(float *vtxBufferPtr) +void ClientDisplay3DPresenter::SetScreenVertices(float *vtxBufferPtr) { const float w = this->_renderProperty.normalWidth / 2.0f; const float h = this->_renderProperty.normalHeight / 2.0f; @@ -2096,7 +2114,7 @@ void ClientDisplay3DView::SetScreenVertices(float *vtxBufferPtr) } } -void ClientDisplay3DView::SetScreenTextureCoordinates(float w0, float h0, float w1, float h1, float *texCoordBufferPtr) +void ClientDisplay3DPresenter::SetScreenTextureCoordinates(float w0, float h0, float w1, float h1, float *texCoordBufferPtr) { texCoordBufferPtr[0] = 0.0f; texCoordBufferPtr[1] = 0.0f; texCoordBufferPtr[2] = w0; texCoordBufferPtr[3] = 0.0f; @@ -2111,6 +2129,62 @@ void ClientDisplay3DView::SetScreenTextureCoordinates(float w0, float h0, float memcpy(texCoordBufferPtr + (2 * 8), texCoordBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); } +ClientDisplayView::ClientDisplayView() +{ + _presenter = NULL; +} + +ClientDisplayView::ClientDisplayView(ClientDisplayPresenter *thePresenter) +{ + _presenter = thePresenter; +} + +void ClientDisplayView::Init() +{ + if (this->_presenter != NULL) + { + this->_presenter->Init(); + } +} + +ClientDisplayPresenter* ClientDisplayView::GetPresenter() +{ + return this->_presenter; +} + +void ClientDisplayView::SetPresenter(ClientDisplayPresenter *thePresenter) +{ + this->_presenter = thePresenter; +} + +ClientDisplay3DView::ClientDisplay3DView() +{ + _presenter = NULL; +} + +ClientDisplay3DView::ClientDisplay3DView(ClientDisplay3DPresenter *thePresenter) +{ + _presenter = thePresenter; +} + +void ClientDisplay3DView::Init() +{ + if (this->_presenter != NULL) + { + this->_presenter->Init(); + } +} + +ClientDisplay3DPresenter* ClientDisplay3DView::Get3DPresenter() +{ + return this->_presenter; +} + +void ClientDisplay3DView::Set3DPresenter(ClientDisplay3DPresenter *thePresenter) +{ + this->_presenter = thePresenter; +} + LUTValues *_LQ2xLUT = NULL; LUTValues *_HQ2xLUT = NULL; LUTValues *_HQ3xLUT = NULL; diff --git a/desmume/src/frontend/cocoa/ClientDisplayView.h b/desmume/src/frontend/cocoa/ClientDisplayView.h index 201aee8e3..4064a8c8f 100644 --- a/desmume/src/frontend/cocoa/ClientDisplayView.h +++ b/desmume/src/frontend/cocoa/ClientDisplayView.h @@ -110,7 +110,7 @@ struct ClientFrameInfo }; typedef struct ClientFrameInfo ClientFrameInfo; -struct ClientDisplayViewProperties +struct ClientDisplayPresenterProperties { ClientDisplayMode mode; ClientDisplayLayout layout; @@ -125,7 +125,7 @@ struct ClientDisplayViewProperties double viewScale; double gapDistance; }; -typedef struct ClientDisplayViewProperties ClientDisplayViewProperties; +typedef struct ClientDisplayPresenterProperties ClientDisplayPresenterProperties; extern LUTValues *_LQ2xLUT; extern LUTValues *_HQ2xLUT; @@ -133,15 +133,14 @@ extern LUTValues *_HQ3xLUT; extern LUTValues *_HQ4xLUT; void InitHQnxLUTs(); -class ClientDisplayView +class ClientDisplayPresenter { private: - void __InstanceInit(const ClientDisplayViewProperties &props); + void __InstanceInit(const ClientDisplayPresenterProperties &props); protected: - ClientDisplayViewProperties _renderProperty; - ClientDisplayViewProperties _stagedProperty; - InitialTouchPressMap *_initialTouchInMajorDisplay; + ClientDisplayPresenterProperties _renderProperty; + ClientDisplayPresenterProperties _stagedProperty; GPUClientFetchObject *_fetchObject; bool _useDeposterize; @@ -152,8 +151,6 @@ protected: bool _isSelectedDisplayEnabled[2]; NDSDisplayID _selectedSourceForDisplay[2]; - int64_t _displayViewID; - bool _useVerticalSync; double _scaleFactor; double _hudObjectScale; @@ -184,9 +181,6 @@ protected: std::string _hudInputString; std::string _outHudString; bool _hudNeedsUpdate; - bool _viewNeedsFlush; - bool _allowViewUpdates; - bool _allowViewFlushes; FT_Library _ftLibrary; const char *_lastFontFilePath; @@ -215,26 +209,19 @@ protected: virtual void _ResizeCPUPixelScaler(const VideoFilterTypeID filterID); public: - ClientDisplayView(); - ClientDisplayView(const ClientDisplayViewProperties &props); - virtual ~ClientDisplayView(); + ClientDisplayPresenter(); + ClientDisplayPresenter(const ClientDisplayPresenterProperties &props); + virtual ~ClientDisplayPresenter(); virtual void Init(); - int64_t GetDisplayViewID(); - virtual void SetDisplayViewID(int64_t displayViewID); - - virtual bool GetViewNeedsFlush(); - - bool GetUseVerticalSync() const; - virtual void SetUseVerticalSync(const bool useVerticalSync); double GetScaleFactor() const; virtual void SetScaleFactor(const double scaleFactor); // NDS screen layout - const ClientDisplayViewProperties& GetViewProperties() const; - void CommitViewProperties(const ClientDisplayViewProperties &props); - virtual void SetupViewProperties(); + const ClientDisplayPresenterProperties& GetPresenterProperties() const; + void CommitPresenterProperties(const ClientDisplayPresenterProperties &props); + virtual void SetupPresenterProperties(); double GetRotation() const; double GetViewScale() const; @@ -311,15 +298,9 @@ public: const GPUClientFetchObject& GetFetchObject() const; void SetFetchObject(GPUClientFetchObject *fetchObject); - bool GetAllowViewUpdates() const; - virtual void SetAllowViewUpdates(bool allowUpdates); - bool GetAllowViewFlushes() const; - virtual void SetAllowViewFlushes(bool allowFlushes); - virtual void LoadDisplays(); virtual void ProcessDisplays(); - virtual void UpdateView(); - virtual void FlushView(); + virtual void UpdateLayout(); virtual void FinishFrameAtIndex(const uint8_t bufferIndex); virtual void CopyFrameToBuffer(uint32_t *dstBuffer); @@ -327,12 +308,6 @@ public: // Emulator interface const NDSDisplayInfo& GetEmuDisplayInfo() const; void SetEmuDisplayInfo(const NDSDisplayInfo &ndsDisplayInfo); - virtual void HandleEmulatorFrameEndEvent(); - - // Touch screen input handling - void GetNDSPoint(const int inputID, const bool isInitialTouchPress, - const double clientX, const double clientY, - u8 &outX, u8 &outY) const; // Utility methods static void ConvertNormalToTransformedBounds(const double scalar, @@ -342,25 +317,69 @@ public: static double GetMaxScalarWithinBounds(const double normalBoundsWidth, const double normalBoundsHeight, const double keepInBoundsWidth, const double keepInBoundsHeight); + static void CalculateNormalSize(const ClientDisplayMode mode, const ClientDisplayLayout layout, const double gapScale, + double &outWidth, double &outHeight); +}; + +class ClientDisplayViewInterface +{ +protected: + InitialTouchPressMap *_initialTouchInMajorDisplay; + int64_t _displayViewID; + bool _useVerticalSync; + bool _viewNeedsFlush; + bool _allowViewUpdates; + bool _allowViewFlushes; + +public: + ClientDisplayViewInterface(); + virtual ~ClientDisplayViewInterface(); + + int64_t GetDisplayViewID(); + virtual void SetDisplayViewID(int64_t displayViewID); + + virtual bool GetViewNeedsFlush(); + virtual void SetViewNeedsFlush(); + + bool GetUseVerticalSync() const; + virtual void SetUseVerticalSync(const bool useVerticalSync); + + // Client view interface + bool GetAllowViewUpdates() const; + virtual void SetAllowViewUpdates(bool allowUpdates); + bool GetAllowViewFlushes() const; + virtual void SetAllowViewFlushes(bool allowFlushes); + + virtual void FlushView(); + + // Touch screen input handling + void GetNDSPoint(const ClientDisplayPresenterProperties &props, + const double logicalClientWidth, const double logicalClientHeight, + const int inputID, const bool isInitialTouchPress, + const double clientX, const double clientY, + uint8_t &outX, uint8_t &outY) const; + + // Utility methods static void ConvertClientToNormalPoint(const double normalBoundsWidth, const double normalBoundsHeight, const double transformBoundsWidth, const double transformBoundsHeight, const double scalar, const double angleDegrees, double &inoutX, double &inoutY); - - static void CalculateNormalSize(const ClientDisplayMode mode, const ClientDisplayLayout layout, const double gapScale, - double &outWidth, double &outHeight); }; -class ClientDisplay3DView : public ClientDisplayView +class ClientDisplay3DPresenter : public ClientDisplayPresenter { +private: + void __InstanceInit(); + protected: bool _canFilterOnGPU; bool _willFilterOnGPU; bool _filtersPreferGPU; public: - ClientDisplay3DView(); + ClientDisplay3DPresenter(); + ClientDisplay3DPresenter(const ClientDisplayPresenterProperties &props); bool CanFilterOnGPU() const; bool GetFiltersPreferGPU() const; @@ -377,4 +396,34 @@ public: void SetScreenTextureCoordinates(float w0, float h0, float w1, float h1, float *texCoordBufferPtr); }; +class ClientDisplayView : public ClientDisplayViewInterface +{ +protected: + ClientDisplayPresenter *_presenter; + +public: + ClientDisplayView(); + ClientDisplayView(ClientDisplayPresenter *thePresenter); + + virtual void Init(); + + ClientDisplayPresenter* GetPresenter(); + void SetPresenter(ClientDisplayPresenter *thePresenter); +}; + +class ClientDisplay3DView : public ClientDisplayViewInterface +{ +protected: + ClientDisplay3DPresenter *_presenter; + +public: + ClientDisplay3DView(); + ClientDisplay3DView(ClientDisplay3DPresenter *thePresenter); + + virtual void Init(); + + ClientDisplay3DPresenter* Get3DPresenter(); + void Set3DPresenter(ClientDisplay3DPresenter *thePresenter); +}; + #endif // _CLIENT_DISPLAY_VIEW_H_ diff --git a/desmume/src/frontend/cocoa/DeSmuME (Latest).xcodeproj/project.pbxproj b/desmume/src/frontend/cocoa/DeSmuME (Latest).xcodeproj/project.pbxproj index fdd734a1e..a20f52388 100644 --- a/desmume/src/frontend/cocoa/DeSmuME (Latest).xcodeproj/project.pbxproj +++ b/desmume/src/frontend/cocoa/DeSmuME (Latest).xcodeproj/project.pbxproj @@ -1048,6 +1048,9 @@ ABD10AEC1715FCDD00B5729D /* mic_ext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD10AE61715FCDD00B5729D /* mic_ext.cpp */; }; ABD10AED17160C9300B5729D /* ringbuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB1B9E601501A78000464647 /* ringbuffer.cpp */; }; ABD10AEE17160CDD00B5729D /* cocoa_input.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104111346652500AF11D1 /* cocoa_input.mm */; }; + ABD1FBF11F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FBF01F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm */; }; + ABD1FBF21F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FBF01F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm */; }; + ABD1FBF31F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FBF01F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm */; }; ABD1FED21345AC8400AF11D1 /* arm_instructions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEA31345AC8400AF11D1 /* arm_instructions.cpp */; }; ABD1FED31345AC8400AF11D1 /* armcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEA41345AC8400AF11D1 /* armcpu.cpp */; }; ABD1FED41345AC8400AF11D1 /* bios.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEA51345AC8400AF11D1 /* bios.cpp */; }; @@ -1628,6 +1631,8 @@ ABD10AE41715FCDD00B5729D /* mic_ext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mic_ext.h; sourceTree = SOURCE_ROOT; }; ABD10AE51715FCDD00B5729D /* audiosamplegenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audiosamplegenerator.cpp; sourceTree = SOURCE_ROOT; }; ABD10AE61715FCDD00B5729D /* mic_ext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mic_ext.cpp; sourceTree = SOURCE_ROOT; }; + ABD1FBF01F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MacScreenshotCaptureTool.mm; sourceTree = ""; }; + ABD1FBF41F7B7EA600B4F648 /* MacScreenshotCaptureTool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MacScreenshotCaptureTool.h; sourceTree = ""; }; ABD1FE6F1345AC8400AF11D1 /* armcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = armcpu.h; sourceTree = ""; }; ABD1FE701345AC8400AF11D1 /* bios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bios.h; sourceTree = ""; }; ABD1FE711345AC8400AF11D1 /* bits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bits.h; sourceTree = ""; }; @@ -2433,6 +2438,7 @@ AB01005C170D07AF00D70FBE /* InputProfileController.h */, AB3BF43F1E2628B6003E2B24 /* MacMetalDisplayView.h */, AB3BF4051E22FEA8003E2B24 /* MacOGLDisplayView.h */, + ABD1FBF41F7B7EA600B4F648 /* MacScreenshotCaptureTool.h */, AB3ACB7014C2361100D7D192 /* preferencesWindowDelegate.h */, ABAF0A3F1A96E67200B95B75 /* RomInfoPanel.h */, AB564902186E6EBC002740F4 /* Slot2WindowDelegate.h */, @@ -2449,6 +2455,7 @@ AB01005D170D07B000D70FBE /* InputProfileController.mm */, AB3BF43B1E26289E003E2B24 /* MacMetalDisplayView.mm */, AB3BF4011E22FE01003E2B24 /* MacOGLDisplayView.mm */, + ABD1FBF01F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm */, AB3ACB7114C2361100D7D192 /* preferencesWindowDelegate.mm */, ABAF0A401A96E67200B95B75 /* RomInfoPanel.mm */, AB564903186E6EBC002740F4 /* Slot2WindowDelegate.mm */, @@ -3814,6 +3821,7 @@ ABA7316F1BB51FDC00B26147 /* type1.c in Sources */, ABD1FF5F1345ACBF00AF11D1 /* fatfile.cpp in Sources */, ABD1FEDF1345AC8400AF11D1 /* FIFO.cpp in Sources */, + ABD1FBF31F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm in Sources */, ABAD3E7413AF1D6D00502E1E /* FIFOSampleBuffer.cpp in Sources */, ABD1FF601345ACBF00AF11D1 /* file_allocation_table.cpp in Sources */, AB2EE12D17D57ED500F68622 /* slot1_retail_mcrom_debug.cpp in Sources */, @@ -4035,6 +4043,7 @@ AB796D0115CDCBA200C59155 /* dlditool.cpp in Sources */, AB796D0215CDCBA200C59155 /* driver.cpp in Sources */, AB796D0315CDCBA200C59155 /* emufat.cpp in Sources */, + ABD1FBF11F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm in Sources */, AB3BF4381E25D9AE003E2B24 /* DisplayViewCALayer.mm in Sources */, AB564904186E6EBC002740F4 /* Slot2WindowDelegate.mm in Sources */, AB9038B217C5ED2200F410BD /* slot1_retail_mcrom.cpp in Sources */, @@ -4385,6 +4394,7 @@ AB8F3CE81A53AC2600A80BF6 /* epx.cpp in Sources */, AB8F3CE91A53AC2600A80BF6 /* hq2x.cpp in Sources */, AB8F3CEA1A53AC2600A80BF6 /* hq4x.cpp in Sources */, + ABD1FBF21F7B7E7E00B4F648 /* MacScreenshotCaptureTool.mm in Sources */, AB8F3CEB1A53AC2600A80BF6 /* advanscene.cpp in Sources */, AB8F3CEC1A53AC2600A80BF6 /* lq2x.cpp in Sources */, AB8F3CED1A53AC2600A80BF6 /* xbrz.cpp in Sources */, diff --git a/desmume/src/frontend/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj b/desmume/src/frontend/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj index f217d304f..719715b25 100644 --- a/desmume/src/frontend/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj +++ b/desmume/src/frontend/cocoa/DeSmuME (XCode 3).xcodeproj/project.pbxproj @@ -1227,6 +1227,11 @@ ABAAFBEB172122B6005DDDBE /* FileMigrationDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABAAFBE9172122B6005DDDBE /* FileMigrationDelegate.mm */; }; ABAAFBEC172122B6005DDDBE /* FileMigrationDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABAAFBE9172122B6005DDDBE /* FileMigrationDelegate.mm */; }; ABAAFBED172122B6005DDDBE /* FileMigrationDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABAAFBE9172122B6005DDDBE /* FileMigrationDelegate.mm */; }; + ABAB0AFF1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABAB0AFE1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm */; }; + ABAB0B001F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABAB0AFE1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm */; }; + ABAB0B011F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABAB0AFE1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm */; }; + ABAB0B021F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABAB0AFE1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm */; }; + ABAB0B031F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABAB0AFE1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm */; }; ABACB73A1AAC46B20066F429 /* Icon_MicrophoneDarkGreen_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABACB7391AAC46B20066F429 /* Icon_MicrophoneDarkGreen_256x256.png */; }; ABACB73B1AAC46B20066F429 /* Icon_MicrophoneDarkGreen_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABACB7391AAC46B20066F429 /* Icon_MicrophoneDarkGreen_256x256.png */; }; ABACB73C1AAC46B20066F429 /* Icon_MicrophoneDarkGreen_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABACB7391AAC46B20066F429 /* Icon_MicrophoneDarkGreen_256x256.png */; }; @@ -1994,6 +1999,8 @@ ABAAEFFE1B22361800E1269D /* hq3x.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hq3x.cpp; sourceTree = ""; }; ABAAFBE8172122B6005DDDBE /* FileMigrationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMigrationDelegate.h; sourceTree = ""; }; ABAAFBE9172122B6005DDDBE /* FileMigrationDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FileMigrationDelegate.mm; sourceTree = ""; }; + ABAB0AFD1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacScreenshotCaptureTool.h; sourceTree = ""; }; + ABAB0AFE1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MacScreenshotCaptureTool.mm; sourceTree = ""; }; ABACB7391AAC46B20066F429 /* Icon_MicrophoneDarkGreen_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_MicrophoneDarkGreen_256x256.png; path = images/Icon_MicrophoneDarkGreen_256x256.png; sourceTree = ""; }; ABAD104915ACE7A00000EC47 /* DeSmuME (PPC).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (PPC).app"; sourceTree = BUILT_PRODUCTS_DIR; }; ABAE2F7918682B6C00C92F4F /* Slot2WindowDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slot2WindowDelegate.h; sourceTree = ""; }; @@ -3017,6 +3024,7 @@ AB3ACB6E14C2361100D7D192 /* inputPrefsView.h */, AB213D43170CB141006DDB0F /* InputProfileController.h */, AB3E690E1E231E9900D4CC75 /* MacOGLDisplayView.h */, + ABAB0AFD1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.h */, AB3ACB7014C2361100D7D192 /* preferencesWindowDelegate.h */, ABC3DEBB1A96EA96009EC345 /* RomInfoPanel.h */, ABAE2F7918682B6C00C92F4F /* Slot2WindowDelegate.h */, @@ -3031,6 +3039,7 @@ AB3ACB6F14C2361100D7D192 /* inputPrefsView.mm */, AB213D44170CB141006DDB0F /* InputProfileController.mm */, AB3E690F1E231E9900D4CC75 /* MacOGLDisplayView.mm */, + ABAB0AFE1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm */, AB3ACB7114C2361100D7D192 /* preferencesWindowDelegate.mm */, ABC3DEBC1A96EA96009EC345 /* RomInfoPanel.mm */, ABAE2F7A18682B6C00C92F4F /* Slot2WindowDelegate.mm */, @@ -4617,6 +4626,7 @@ ABC04DA41F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */, ABC04DCB1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */, ABAFD2791F7110E6007705BD /* gdbstub.cpp in Sources */, + ABAB0B001F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4805,6 +4815,7 @@ ABC04DA51F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */, ABC04DCC1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */, ABAFD2781F7110E5007705BD /* gdbstub.cpp in Sources */, + ABAB0B011F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5023,6 +5034,7 @@ ABC04DA31F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */, ABC04DCA1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */, ABAFD2751F7110E4007705BD /* gdbstub.cpp in Sources */, + ABAB0AFF1F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5241,6 +5253,7 @@ ABC04DA71F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */, ABC04DCE1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */, ABAFD2761F7110E4007705BD /* gdbstub.cpp in Sources */, + ABAB0B031F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5429,6 +5442,7 @@ ABC04DA61F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */, ABC04DCD1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */, ABAFD2771F7110E5007705BD /* gdbstub.cpp in Sources */, + ABAB0B021F7C1BB70079EFD3 /* MacScreenshotCaptureTool.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/desmume/src/frontend/cocoa/DefaultUserPrefs.plist b/desmume/src/frontend/cocoa/DefaultUserPrefs.plist index 35bf21c74..25b71a21e 100644 --- a/desmume/src/frontend/cocoa/DefaultUserPrefs.plist +++ b/desmume/src/frontend/cocoa/DefaultUserPrefs.plist @@ -752,6 +752,26 @@ 0 RomInfoPanel_SectionViewState + ScreenshotCaptureTool_DirectoryPath + ~/Pictures + ScreenshotCaptureTool_FileFormat + 0 + ScreenshotCaptureTool_DisplayMode + 2 + ScreenshotCaptureTool_DisplayRotation + 0 + ScreenshotCaptureTool_DisplaySeparation + 0 + ScreenshotCaptureTool_DisplayLayout + 0 + ScreenshotCaptureTool_DisplayOrder + 0 + ScreenshotCaptureTool_Deposterize + + ScreenshotCaptureTool_OutputFilter + 1 + ScreenshotCaptureTool_PixelScaler + 0 Slot2_GBA_CartridgePath Slot2_GBA_SRAMPath diff --git a/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp b/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp index fb868e9c4..cc702823a 100644 --- a/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp +++ b/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp @@ -5019,15 +5019,17 @@ void OGLClientFetchObject::_FetchCustomDisplayByID(const NDSDisplayID displayID, OGLVideoOutput::OGLVideoOutput() { _contextInfo = NULL; + _viewportWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH; + _viewportHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2; _needUpdateViewport = true; _hasOGLPixelScaler = false; - _layerList = new std::vector; - _layerList->reserve(8); _texCPUFilterDstID[NDSDisplayID_Main] = 0; _texCPUFilterDstID[NDSDisplayID_Touch] = 0; - _fboFrameCopyID = 0; + + _layerList = new std::vector; + _layerList->reserve(8); } OGLVideoOutput::~OGLVideoOutput() @@ -5073,12 +5075,12 @@ void OGLVideoOutput::_UpdateClientSize() this->_needUpdateViewport = true; this->GetHUDLayer()->SetNeedsUpdateVertices(); - this->ClientDisplay3DView::_UpdateClientSize(); + this->ClientDisplay3DPresenter::_UpdateClientSize(); } void OGLVideoOutput::_UpdateViewScale() { - this->ClientDisplayView::_UpdateViewScale(); + this->ClientDisplay3DPresenter::_UpdateViewScale(); for (size_t i = 0; i < _layerList->size(); i++) { @@ -5109,7 +5111,7 @@ void OGLVideoOutput::_ResizeCPUPixelScaler(const VideoFilterTypeID filterID) glFinish(); - this->ClientDisplay3DView::_ResizeCPUPixelScaler(filterID); + this->ClientDisplay3DPresenter::_ResizeCPUPixelScaler(filterID); glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_ARB, this->_vfMasterDstBufferSize, this->_vfMasterDstBuffer); glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); @@ -5199,7 +5201,7 @@ void OGLVideoOutput::SetOutputFilter(const OutputFilterTypeID filterID) void OGLVideoOutput::SetPixelScaler(const VideoFilterTypeID filterID) { - this->ClientDisplay3DView::SetPixelScaler(filterID); + this->ClientDisplay3DPresenter::SetPixelScaler(filterID); this->_hasOGLPixelScaler = this->GetDisplayLayer()->SetGPUPixelScalerOGL(this->_pixelScaler); this->_willFilterOnGPU = (this->GetFiltersPreferGPU()) ? this->_hasOGLPixelScaler : false; @@ -5213,7 +5215,7 @@ void OGLVideoOutput::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize void OGLVideoOutput::SetHUDVisibility(const bool visibleState) { this->GetHUDLayer()->SetVisibility(visibleState); - this->ClientDisplay3DView::SetHUDVisibility(visibleState); + this->ClientDisplay3DPresenter::SetHUDVisibility(visibleState); } void OGLVideoOutput::SetFiltersPreferGPU(const bool preferGPU) @@ -5271,12 +5273,6 @@ void OGLVideoOutput::FinishFrameAtIndex(const uint8_t bufferIndex) void OGLVideoOutput::CopyFrameToBuffer(uint32_t *dstBuffer) { - for (size_t i = 0; i < _layerList->size(); i++) - { - OGLVideoLayer *theLayer = (*_layerList)[i]; - theLayer->SetNeedsUpdateViewport(); - } - GLuint texFrameCopyID = 0; glGenTextures(1, &texFrameCopyID); @@ -5290,6 +5286,7 @@ void OGLVideoOutput::CopyFrameToBuffer(uint32_t *dstBuffer) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->_fboFrameCopyID); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, texFrameCopyID, 0); + this->_needUpdateViewport = true; this->RenderFrameOGL(true); glReadPixels(0, 0, this->_renderProperty.clientWidth, this->_renderProperty.clientHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, dstBuffer); @@ -5297,11 +5294,7 @@ void OGLVideoOutput::CopyFrameToBuffer(uint32_t *dstBuffer) glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glDeleteTextures(1, &texFrameCopyID); - for (size_t i = 0; i < _layerList->size(); i++) - { - OGLVideoLayer *theLayer = (*_layerList)[i]; - theLayer->SetNeedsUpdateViewport(); - } + this->_needUpdateViewport = true; } void OGLVideoOutput::RenderFrameOGL(bool isRenderingFlipped) @@ -5834,7 +5827,7 @@ void OGLImage::UploadTransformationOGL() { const double w = this->_viewportWidth; const double h = this->_viewportHeight; - const GLdouble s = ClientDisplayView::GetMaxScalarWithinBounds(this->_normalWidth, this->_normalHeight, w, h); + const GLdouble s = ClientDisplayPresenter::GetMaxScalarWithinBounds(this->_normalWidth, this->_normalHeight, w, h); if (this->_canUseShaderOutput) { @@ -6560,7 +6553,7 @@ void OGLHUDLayer::RenderOGL(bool isRenderingFlipped) if (this->_needUpdateViewport) { - glUniform2f(this->_uniformViewSize, this->_output->GetViewProperties().clientWidth, this->_output->GetViewProperties().clientHeight); + glUniform2f(this->_uniformViewSize, this->_output->GetPresenterProperties().clientWidth, this->_output->GetPresenterProperties().clientHeight); glUniform1i(this->_uniformRenderFlipped, (isRenderingFlipped) ? GL_TRUE : GL_FALSE); this->_needUpdateViewport = false; } @@ -6577,7 +6570,7 @@ void OGLHUDLayer::RenderOGL(bool isRenderingFlipped) // First, draw the inputs. if (this->_output->GetHUDShowInput()) { - const ClientDisplayViewProperties &cdv = this->_output->GetViewProperties(); + const ClientDisplayPresenterProperties &cdv = this->_output->GetPresenterProperties(); if (this->_output->GetContextInfo()->IsShaderSupported()) { @@ -6776,7 +6769,7 @@ OGLDisplayLayer::~OGLDisplayLayer() void OGLDisplayLayer::_UpdateRotationScaleOGL() { - const ClientDisplayViewProperties &cdv = this->_output->GetViewProperties(); + const ClientDisplayPresenterProperties &cdv = this->_output->GetPresenterProperties(); const double r = cdv.rotation; const double s = cdv.viewScale; @@ -7140,7 +7133,7 @@ void OGLDisplayLayer::ProcessOGL() { const OGLClientFetchObject &fetchObj = (const OGLClientFetchObject &)this->_output->GetFetchObject(); const NDSDisplayInfo &emuDisplayInfo = this->_output->GetEmuDisplayInfo(); - const ClientDisplayMode mode = this->_output->GetViewProperties().mode; + const ClientDisplayMode mode = this->_output->GetPresenterProperties().mode; const NDSDisplayID selectedDisplaySource[2] = { this->_output->GetSelectedDisplaySourceForDisplay(NDSDisplayID_Main), this->_output->GetSelectedDisplaySourceForDisplay(NDSDisplayID_Touch) }; const bool didRenderNative[2] = { !emuDisplayInfo.didPerformCustomRender[selectedDisplaySource[NDSDisplayID_Main]], !emuDisplayInfo.didPerformCustomRender[selectedDisplaySource[NDSDisplayID_Touch]] }; @@ -7259,7 +7252,7 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped) this->_output->LockDisplayTextures(); glBindVertexArrayDESMUME(this->_vaoMainStatesID); - switch (this->_output->GetViewProperties().mode) + switch (this->_output->GetPresenterProperties().mode) { case ClientDisplayMode_Main: { @@ -7287,10 +7280,10 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped) case ClientDisplayMode_Dual: { - const NDSDisplayID majorDisplayID = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch; - const size_t majorDisplayVtx = (this->_output->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12; + const NDSDisplayID majorDisplayID = (this->_output->GetPresenterProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch; + const size_t majorDisplayVtx = (this->_output->GetPresenterProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12; - switch (this->_output->GetViewProperties().layout) + switch (this->_output->GetPresenterProperties().layout) { case ClientDisplayLayout_Hybrid_2_1: case ClientDisplayLayout_Hybrid_16_9: diff --git a/desmume/src/frontend/cocoa/OGLDisplayOutput.h b/desmume/src/frontend/cocoa/OGLDisplayOutput.h index b0dae7e78..49a58e190 100644 --- a/desmume/src/frontend/cocoa/OGLDisplayOutput.h +++ b/desmume/src/frontend/cocoa/OGLDisplayOutput.h @@ -373,7 +373,7 @@ public: virtual void SetFetchBuffers(const NDSDisplayInfo ¤tDisplayInfo); }; -class OGLVideoOutput : public ClientDisplay3DView +class OGLVideoOutput : public ClientDisplay3DPresenter { protected: OGLContextInfo *_contextInfo; @@ -381,10 +381,12 @@ protected: GLsizei _viewportHeight; bool _needUpdateViewport; bool _hasOGLPixelScaler; - std::vector *_layerList; + GLuint _texCPUFilterDstID[2]; GLuint _fboFrameCopyID; + std::vector *_layerList; + void _UpdateViewport(); virtual void _UpdateNormalSize(); diff --git a/desmume/src/frontend/cocoa/cocoa_GPU.h b/desmume/src/frontend/cocoa/cocoa_GPU.h index 6f47ddef0..70ce3bc78 100644 --- a/desmume/src/frontend/cocoa/cocoa_GPU.h +++ b/desmume/src/frontend/cocoa/cocoa_GPU.h @@ -62,12 +62,10 @@ typedef std::map DisplayLinkFlushTimeLimitMap; @property (assign, nonatomic) GPUClientFetchObject *GPUFetchObject; @property (readonly, nonatomic) volatile int32_t numberViewsUsingDirectToCPUFiltering; -- (const NDSDisplayInfo &) fetchDisplayInfoForIndex:(const u8)bufferIndex; - (pthread_rwlock_t *) rwlockFramebufferAtIndex:(const u8)bufferIndex; - (void) setOutputList:(NSMutableArray *)theOutputList mutex:(pthread_mutex_t *)theMutex; - (void) incrementViewsUsingDirectToCPUFiltering; - (void) decrementViewsUsingDirectToCPUFiltering; -- (void) handleFetchFromBufferIndexAndPushVideo:(NSData *)indexData; - (void) pushVideoDataToAllDisplayViews; - (void) finishAllDisplayViewsAtIndex:(const u8)bufferIndex; - (void) flushAllDisplaysOnDisplayLink:(CVDisplayLinkRef)displayLink timeStamp:(const CVTimeStamp *)timeStamp; diff --git a/desmume/src/frontend/cocoa/cocoa_GPU.mm b/desmume/src/frontend/cocoa/cocoa_GPU.mm index a99ceacbc..f3458f6e1 100644 --- a/desmume/src/frontend/cocoa/cocoa_GPU.mm +++ b/desmume/src/frontend/cocoa/cocoa_GPU.mm @@ -950,19 +950,6 @@ public: [super dealloc]; } -- (void) handleFetchFromBufferIndexAndPushVideo:(NSData *)indexData -{ - const NSInteger index = *(NSInteger *)[indexData bytes]; - - GPUFetchObject->FetchFromBufferIndex(index); - [self pushVideoDataToAllDisplayViews]; -} - -- (const NDSDisplayInfo &) fetchDisplayInfoForIndex:(const u8)bufferIndex -{ - return GPUFetchObject->GetFetchDisplayInfoForBufferIndex(bufferIndex); -} - - (pthread_rwlock_t *) rwlockFramebufferAtIndex:(const u8)bufferIndex { return _rwlockFramebuffer[bufferIndex]; @@ -1035,8 +1022,8 @@ public: { if ([cdsOutput isKindOfClass:[CocoaDSDisplayVideo class]]) { - ClientDisplay3DView *cdv = [(CocoaDSDisplayVideo *)cdsOutput clientDisplayView]; - cdv->FinishFrameAtIndex(bufferIndex); + ClientDisplay3DView *cdv = [(CocoaDSDisplayVideo *)cdsOutput clientDisplay3DView]; + cdv->Get3DPresenter()->FinishFrameAtIndex(bufferIndex); } } @@ -1063,7 +1050,7 @@ public: { if ([(CocoaDSDisplayVideo *)cdsOutput currentDisplayID] == displayID) { - ClientDisplay3DView *cdv = [(CocoaDSDisplayVideo *)cdsOutput clientDisplayView]; + ClientDisplay3DView *cdv = [(CocoaDSDisplayVideo *)cdsOutput clientDisplay3DView]; if (cdv->GetViewNeedsFlush()) { diff --git a/desmume/src/frontend/cocoa/cocoa_globals.h b/desmume/src/frontend/cocoa/cocoa_globals.h index ef9e01f81..742caa065 100644 --- a/desmume/src/frontend/cocoa/cocoa_globals.h +++ b/desmume/src/frontend/cocoa/cocoa_globals.h @@ -38,7 +38,7 @@ #define NSSTRING_TITLE_SELECT_MPCF_DISK_IMAGE_PANEL NSLocalizedString(@"Select MPCF Disk Image", nil) #define NSSTRING_TITLE_CHOOSE_GBA_CARTRIDGE_PANEL NSLocalizedString(@"Choose GBA Cartridge", nil) #define NSSTRING_TITLE_CHOOSE_GBA_SRAM_PANEL NSLocalizedString(@"Choose GBA SRAM File", nil) -#define NSSTRING_TITLE_SAVE_SCREENSHOT_PANEL NSLocalizedString(@"Save Screenshot", nil) +#define NSSTRING_TITLE_SAVE_SCREENSHOT_PANEL NSLocalizedString(@"Screenshot Save Location", nil) #define NSSTRING_TITLE_EXECUTE_CONTROL NSLocalizedString(@"Execute", nil) #define NSSTRING_TITLE_PAUSE_CONTROL NSLocalizedString(@"Pause", nil) @@ -367,7 +367,6 @@ enum MESSAGE_SET_SPU_INTERPOLATION_MODE, MESSAGE_SET_VOLUME, - MESSAGE_REQUEST_SCREENSHOT, MESSAGE_COPY_TO_PASTEBOARD }; diff --git a/desmume/src/frontend/cocoa/cocoa_output.h b/desmume/src/frontend/cocoa/cocoa_output.h index 1c91c3723..ffb6680bf 100644 --- a/desmume/src/frontend/cocoa/cocoa_output.h +++ b/desmume/src/frontend/cocoa/cocoa_output.h @@ -116,7 +116,7 @@ @interface CocoaDSDisplayVideo : CocoaDSDisplay { ClientDisplay3DView *_cdv; - ClientDisplayViewProperties _intermediateViewProps; + ClientDisplayPresenterProperties _intermediateViewProps; OSSpinLock spinlockViewProperties; OSSpinLock spinlockIsHUDVisible; @@ -129,7 +129,7 @@ OSSpinLock spinlockDisplayID; } -@property (assign, nonatomic) ClientDisplay3DView *clientDisplayView; +@property (assign, nonatomic, getter=clientDisplay3DView, setter=setClientDisplay3DView:) ClientDisplay3DView *_cdv; @property (readonly, nonatomic) BOOL canFilterOnGPU; @property (readonly, nonatomic) BOOL willFilterOnGPU; @property (assign) BOOL isHUDVisible; @@ -158,7 +158,7 @@ @property (assign) NSInteger outputFilter; @property (assign) NSInteger pixelScaler; -- (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps; +- (void) commitPresenterProperties:(const ClientDisplayPresenterProperties &)viewProps; - (void) handleChangeViewProperties; - (void) handleReceiveGPUFrame; @@ -166,12 +166,9 @@ - (void) handleReprocessRedraw; - (void) handleRedraw; - (void) handleCopyToPasteboard; -- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData; - (void) setScaleFactor:(float)theScaleFactor; - (void) hudUpdate; -- (NSImage *) copyImageFromView; - (NSImage *) image; -- (NSBitmapImageRep *) bitmapImageRep; @end diff --git a/desmume/src/frontend/cocoa/cocoa_output.mm b/desmume/src/frontend/cocoa/cocoa_output.mm index ad6c897c3..ced8a6398 100644 --- a/desmume/src/frontend/cocoa/cocoa_output.mm +++ b/desmume/src/frontend/cocoa/cocoa_output.mm @@ -568,7 +568,7 @@ @implementation CocoaDSDisplayVideo -@dynamic clientDisplayView; +@synthesize _cdv; @dynamic canFilterOnGPU; @dynamic willFilterOnGPU; @dynamic isHUDVisible; @@ -625,17 +625,7 @@ [super dealloc]; } -- (void) setClientDisplayView:(ClientDisplay3DView *)clientDisplayView -{ - _cdv = clientDisplayView; -} - -- (ClientDisplay3DView *) clientDisplayView -{ - return _cdv; -} - -- (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps +- (void) commitPresenterProperties:(const ClientDisplayPresenterProperties &)viewProps { OSSpinLockLock(&spinlockViewProperties); _intermediateViewProps = viewProps; @@ -646,25 +636,27 @@ - (BOOL) canFilterOnGPU { - return (_cdv->CanFilterOnGPU()) ? YES : NO; + return (_cdv->Get3DPresenter()->CanFilterOnGPU()) ? YES : NO; } - (BOOL) willFilterOnGPU { - return (_cdv->WillFilterOnGPU()) ? YES : NO; + return (_cdv->Get3DPresenter()->WillFilterOnGPU()) ? YES : NO; } - (void) setIsHUDVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDVisibility((theState) ? true : false); + _cdv->Get3DPresenter()->SetHUDVisibility((theState) ? true : false); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (BOOL) isHUDVisible { OSSpinLockLock(&spinlockIsHUDVisible); - const BOOL theState = (_cdv->GetHUDVisibility()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetHUDVisibility()) ? YES : NO; OSSpinLockUnlock(&spinlockIsHUDVisible); return theState; @@ -673,14 +665,16 @@ - (void) setIsHUDVideoFPSVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDShowVideoFPS((theState) ? true : false); + _cdv->Get3DPresenter()->SetHUDShowVideoFPS((theState) ? true : false); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (BOOL) isHUDVideoFPSVisible { OSSpinLockLock(&spinlockIsHUDVisible); - const BOOL theState = (_cdv->GetHUDShowVideoFPS()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetHUDShowVideoFPS()) ? YES : NO; OSSpinLockUnlock(&spinlockIsHUDVisible); return theState; @@ -689,14 +683,16 @@ - (void) setIsHUDRender3DFPSVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDShowRender3DFPS((theState) ? true : false); + _cdv->Get3DPresenter()->SetHUDShowRender3DFPS((theState) ? true : false); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (BOOL) isHUDRender3DFPSVisible { OSSpinLockLock(&spinlockIsHUDVisible); - const BOOL theState = (_cdv->GetHUDShowRender3DFPS()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetHUDShowRender3DFPS()) ? YES : NO; OSSpinLockUnlock(&spinlockIsHUDVisible); return theState; @@ -705,14 +701,16 @@ - (void) setIsHUDFrameIndexVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDShowFrameIndex((theState) ? true : false); + _cdv->Get3DPresenter()->SetHUDShowFrameIndex((theState) ? true : false); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (BOOL) isHUDFrameIndexVisible { OSSpinLockLock(&spinlockIsHUDVisible); - const BOOL theState = (_cdv->GetHUDShowFrameIndex()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetHUDShowFrameIndex()) ? YES : NO; OSSpinLockUnlock(&spinlockIsHUDVisible); return theState; @@ -721,14 +719,16 @@ - (void) setIsHUDLagFrameCountVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDShowLagFrameCount((theState) ? true : false); + _cdv->Get3DPresenter()->SetHUDShowLagFrameCount((theState) ? true : false); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (BOOL) isHUDLagFrameCountVisible { OSSpinLockLock(&spinlockIsHUDVisible); - const BOOL theState = (_cdv->GetHUDShowLagFrameCount()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetHUDShowLagFrameCount()) ? YES : NO; OSSpinLockUnlock(&spinlockIsHUDVisible); return theState; @@ -737,14 +737,16 @@ - (void) setIsHUDCPULoadAverageVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDShowCPULoadAverage((theState) ? true : false); + _cdv->Get3DPresenter()->SetHUDShowCPULoadAverage((theState) ? true : false); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (BOOL) isHUDCPULoadAverageVisible { OSSpinLockLock(&spinlockIsHUDVisible); - const BOOL theState = (_cdv->GetHUDShowCPULoadAverage()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetHUDShowCPULoadAverage()) ? YES : NO; OSSpinLockUnlock(&spinlockIsHUDVisible); return theState; @@ -753,14 +755,16 @@ - (void) setIsHUDRealTimeClockVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDShowRTC((theState) ? true : false); + _cdv->Get3DPresenter()->SetHUDShowRTC((theState) ? true : false); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (BOOL) isHUDRealTimeClockVisible { OSSpinLockLock(&spinlockIsHUDVisible); - const BOOL theState = (_cdv->GetHUDShowRTC()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetHUDShowRTC()) ? YES : NO; OSSpinLockUnlock(&spinlockIsHUDVisible); return theState; @@ -769,14 +773,16 @@ - (void) setIsHUDInputVisible:(BOOL)theState { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDShowInput((theState) ? true : false); + _cdv->Get3DPresenter()->SetHUDShowInput((theState) ? true : false); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (BOOL) isHUDInputVisible { OSSpinLockLock(&spinlockIsHUDVisible); - const BOOL theState = (_cdv->GetHUDShowInput()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetHUDShowInput()) ? YES : NO; OSSpinLockUnlock(&spinlockIsHUDVisible); return theState; @@ -785,14 +791,16 @@ - (void) setHudColorVideoFPS:(uint32_t)theColor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDColorVideoFPS(theColor); + _cdv->Get3DPresenter()->SetHUDColorVideoFPS(theColor); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (uint32_t) hudColorVideoFPS { OSSpinLockLock(&spinlockIsHUDVisible); - const uint32_t color32 = _cdv->GetHUDColorVideoFPS(); + const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorVideoFPS(); OSSpinLockUnlock(&spinlockIsHUDVisible); return color32; @@ -801,14 +809,16 @@ - (void) setHudColorRender3DFPS:(uint32_t)theColor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDColorRender3DFPS(theColor); + _cdv->Get3DPresenter()->SetHUDColorRender3DFPS(theColor); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (uint32_t) hudColorRender3DFPS { OSSpinLockLock(&spinlockIsHUDVisible); - const uint32_t color32 = _cdv->GetHUDColorRender3DFPS(); + const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorRender3DFPS(); OSSpinLockUnlock(&spinlockIsHUDVisible); return color32; @@ -817,14 +827,16 @@ - (void) setHudColorFrameIndex:(uint32_t)theColor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDColorFrameIndex(theColor); + _cdv->Get3DPresenter()->SetHUDColorFrameIndex(theColor); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (uint32_t) hudColorFrameIndex { OSSpinLockLock(&spinlockIsHUDVisible); - const uint32_t color32 = _cdv->GetHUDColorFrameIndex(); + const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorFrameIndex(); OSSpinLockUnlock(&spinlockIsHUDVisible); return color32; @@ -833,14 +845,16 @@ - (void) setHudColorLagFrameCount:(uint32_t)theColor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDColorLagFrameCount(theColor); + _cdv->Get3DPresenter()->SetHUDColorLagFrameCount(theColor); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (uint32_t) hudColorLagFrameCount { OSSpinLockLock(&spinlockIsHUDVisible); - const uint32_t color32 = _cdv->GetHUDColorLagFrameCount(); + const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorLagFrameCount(); OSSpinLockUnlock(&spinlockIsHUDVisible); return color32; @@ -849,14 +863,16 @@ - (void) setHudColorCPULoadAverage:(uint32_t)theColor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDColorCPULoadAverage(theColor); + _cdv->Get3DPresenter()->SetHUDColorCPULoadAverage(theColor); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (uint32_t) hudColorCPULoadAverage { OSSpinLockLock(&spinlockIsHUDVisible); - const uint32_t color32 = _cdv->GetHUDColorCPULoadAverage(); + const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorCPULoadAverage(); OSSpinLockUnlock(&spinlockIsHUDVisible); return color32; @@ -865,14 +881,16 @@ - (void) setHudColorRTC:(uint32_t)theColor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDColorRTC(theColor); + _cdv->Get3DPresenter()->SetHUDColorRTC(theColor); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (uint32_t) hudColorRTC { OSSpinLockLock(&spinlockIsHUDVisible); - const uint32_t color32 = _cdv->GetHUDColorRTC(); + const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorRTC(); OSSpinLockUnlock(&spinlockIsHUDVisible); return color32; @@ -881,14 +899,16 @@ - (void) setHudColorInputPendingAndApplied:(uint32_t)theColor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDColorInputPendingAndApplied(theColor); + _cdv->Get3DPresenter()->SetHUDColorInputPendingAndApplied(theColor); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (uint32_t) hudColorInputPendingAndApplied { OSSpinLockLock(&spinlockIsHUDVisible); - const uint32_t color32 = _cdv->GetHUDColorInputPendingAndApplied(); + const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorInputPendingAndApplied(); OSSpinLockUnlock(&spinlockIsHUDVisible); return color32; @@ -897,14 +917,16 @@ - (void) setHudColorInputAppliedOnly:(uint32_t)theColor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDColorInputAppliedOnly(theColor); + _cdv->Get3DPresenter()->SetHUDColorInputAppliedOnly(theColor); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (uint32_t) hudColorInputAppliedOnly { OSSpinLockLock(&spinlockIsHUDVisible); - const uint32_t color32 = _cdv->GetHUDColorInputAppliedOnly(); + const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorInputAppliedOnly(); OSSpinLockUnlock(&spinlockIsHUDVisible); return color32; @@ -913,14 +935,16 @@ - (void) setHudColorInputPendingOnly:(uint32_t)theColor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetHUDColorInputPendingOnly(theColor); + _cdv->Get3DPresenter()->SetHUDColorInputPendingOnly(theColor); OSSpinLockUnlock(&spinlockIsHUDVisible); + + _cdv->SetViewNeedsFlush(); } - (uint32_t) hudColorInputPendingOnly { OSSpinLockLock(&spinlockIsHUDVisible); - const uint32_t color32 = _cdv->GetHUDColorInputPendingOnly(); + const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorInputPendingOnly(); OSSpinLockUnlock(&spinlockIsHUDVisible); return color32; @@ -929,14 +953,16 @@ - (void) setDisplayMainVideoSource:(NSInteger)displaySourceID { OSSpinLockLock(&spinlockDisplayVideoSource); - _cdv->SetDisplayVideoSource(NDSDisplayID_Main, (ClientDisplaySource)displaySourceID); + _cdv->Get3DPresenter()->SetDisplayVideoSource(NDSDisplayID_Main, (ClientDisplaySource)displaySourceID); OSSpinLockUnlock(&spinlockDisplayVideoSource); + + _cdv->SetViewNeedsFlush(); } - (NSInteger) displayMainVideoSource { OSSpinLockLock(&spinlockDisplayVideoSource); - const NSInteger displayVideoSource = _cdv->GetDisplayVideoSource(NDSDisplayID_Main); + const NSInteger displayVideoSource = _cdv->Get3DPresenter()->GetDisplayVideoSource(NDSDisplayID_Main); OSSpinLockUnlock(&spinlockDisplayVideoSource); return displayVideoSource; @@ -945,14 +971,16 @@ - (void) setDisplayTouchVideoSource:(NSInteger)displaySourceID { OSSpinLockLock(&spinlockDisplayVideoSource); - _cdv->SetDisplayVideoSource(NDSDisplayID_Touch, (ClientDisplaySource)displaySourceID); + _cdv->Get3DPresenter()->SetDisplayVideoSource(NDSDisplayID_Touch, (ClientDisplaySource)displaySourceID); OSSpinLockUnlock(&spinlockDisplayVideoSource); + + _cdv->SetViewNeedsFlush(); } - (NSInteger) displayTouchVideoSource { OSSpinLockLock(&spinlockDisplayVideoSource); - const NSInteger displayVideoSource = _cdv->GetDisplayVideoSource(NDSDisplayID_Touch); + const NSInteger displayVideoSource = _cdv->Get3DPresenter()->GetDisplayVideoSource(NDSDisplayID_Touch); OSSpinLockUnlock(&spinlockDisplayVideoSource); return displayVideoSource; @@ -993,14 +1021,14 @@ - (void) setVideoFiltersPreferGPU:(BOOL)theState { OSSpinLockLock(&spinlockVideoFiltersPreferGPU); - _cdv->SetFiltersPreferGPU((theState) ? true : false); + _cdv->Get3DPresenter()->SetFiltersPreferGPU((theState) ? true : false); OSSpinLockUnlock(&spinlockVideoFiltersPreferGPU); } - (BOOL) videoFiltersPreferGPU { OSSpinLockLock(&spinlockVideoFiltersPreferGPU); - const BOOL theState = (_cdv->GetFiltersPreferGPU()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetFiltersPreferGPU()) ? YES : NO; OSSpinLockUnlock(&spinlockVideoFiltersPreferGPU); return theState; @@ -1009,14 +1037,14 @@ - (void) setSourceDeposterize:(BOOL)theState { OSSpinLockLock(&spinlockSourceDeposterize); - _cdv->SetSourceDeposterize((theState) ? true : false); + _cdv->Get3DPresenter()->SetSourceDeposterize((theState) ? true : false); OSSpinLockUnlock(&spinlockSourceDeposterize); } - (BOOL) sourceDeposterize { OSSpinLockLock(&spinlockSourceDeposterize); - const BOOL theState = (_cdv->GetSourceDeposterize()) ? YES : NO; + const BOOL theState = (_cdv->Get3DPresenter()->GetSourceDeposterize()) ? YES : NO; OSSpinLockUnlock(&spinlockSourceDeposterize); return theState; @@ -1025,14 +1053,14 @@ - (void) setOutputFilter:(NSInteger)filterID { OSSpinLockLock(&spinlockOutputFilter); - _cdv->SetOutputFilter((OutputFilterTypeID)filterID); + _cdv->Get3DPresenter()->SetOutputFilter((OutputFilterTypeID)filterID); OSSpinLockUnlock(&spinlockOutputFilter); } - (NSInteger) outputFilter { OSSpinLockLock(&spinlockOutputFilter); - const NSInteger filterID = _cdv->GetOutputFilter(); + const NSInteger filterID = _cdv->Get3DPresenter()->GetOutputFilter(); OSSpinLockUnlock(&spinlockOutputFilter); return filterID; @@ -1041,14 +1069,14 @@ - (void) setPixelScaler:(NSInteger)filterID { OSSpinLockLock(&spinlockPixelScaler); - _cdv->SetPixelScaler((VideoFilterTypeID)filterID); + _cdv->Get3DPresenter()->SetPixelScaler((VideoFilterTypeID)filterID); OSSpinLockUnlock(&spinlockPixelScaler); } - (NSInteger) pixelScaler { OSSpinLockLock(&spinlockPixelScaler); - const NSInteger filterID = _cdv->GetPixelScaler(); + const NSInteger filterID = _cdv->Get3DPresenter()->GetPixelScaler(); OSSpinLockUnlock(&spinlockPixelScaler); return filterID; @@ -1057,7 +1085,6 @@ - (void)handlePortMessage:(NSPortMessage *)portMessage { NSInteger message = (NSInteger)[portMessage msgid]; - NSArray *messageComponents = [portMessage components]; switch (message) { @@ -1081,10 +1108,6 @@ [self handleCopyToPasteboard]; break; - case MESSAGE_REQUEST_SCREENSHOT: - [self handleRequestScreenshot:[messageComponents objectAtIndex:0] fileTypeData:[messageComponents objectAtIndex:1]]; - break; - default: [super handlePortMessage:portMessage]; break; @@ -1095,52 +1118,53 @@ { [super handleEmuFrameProcessed]; [self hudUpdate]; - _cdv->HandleEmulatorFrameEndEvent(); + _cdv->SetViewNeedsFlush(); } - (void) handleChangeViewProperties { OSSpinLockLock(&spinlockViewProperties); - _cdv->CommitViewProperties(_intermediateViewProps); + _cdv->Get3DPresenter()->CommitPresenterProperties(_intermediateViewProps); OSSpinLockUnlock(&spinlockViewProperties); - _cdv->SetupViewProperties(); + _cdv->Get3DPresenter()->SetupPresenterProperties(); + _cdv->SetViewNeedsFlush(); } - (void) handleReceiveGPUFrame { [super handleReceiveGPUFrame]; - _cdv->LoadDisplays(); - _cdv->ProcessDisplays(); + _cdv->Get3DPresenter()->LoadDisplays(); + _cdv->Get3DPresenter()->ProcessDisplays(); } - (void) handleReloadReprocessRedraw { - GPUClientFetchObject &fetchObjMutable = (GPUClientFetchObject &)_cdv->GetFetchObject(); + GPUClientFetchObject &fetchObjMutable = (GPUClientFetchObject &)_cdv->Get3DPresenter()->GetFetchObject(); const u8 bufferIndex = fetchObjMutable.GetLastFetchIndex(); fetchObjMutable.FetchFromBufferIndex(bufferIndex); - _cdv->LoadDisplays(); - _cdv->ProcessDisplays(); + _cdv->Get3DPresenter()->LoadDisplays(); + _cdv->Get3DPresenter()->ProcessDisplays(); [self handleEmuFrameProcessed]; } - (void) handleReprocessRedraw { - _cdv->ProcessDisplays(); - _cdv->UpdateView(); + _cdv->Get3DPresenter()->ProcessDisplays(); + _cdv->SetViewNeedsFlush(); } - (void) handleRedraw { - _cdv->UpdateView(); + _cdv->SetViewNeedsFlush(); } - (void) handleCopyToPasteboard { - NSImage *screenshot = [self copyImageFromView]; + NSImage *screenshot = [self image]; if (screenshot == nil) { return; @@ -1151,28 +1175,10 @@ [pboard setData:[screenshot TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1.0f] forType:NSTIFFPboardType]; } -- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData -{ - NSString *fileURLString = [[NSString alloc] initWithData:fileURLStringData encoding:NSUTF8StringEncoding]; - NSURL *fileURL = [NSURL URLWithString:fileURLString]; - NSBitmapImageFileType fileType = *(NSBitmapImageFileType *)[fileTypeData bytes]; - - NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys: - fileURL, @"fileURL", - [NSNumber numberWithInteger:(NSInteger)fileType], @"fileType", - [self image], @"screenshotImage", - nil]; - - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"org.desmume.DeSmuME.requestScreenshotDidFinish" object:self userInfo:userInfo]; - [userInfo release]; - - [fileURLString release]; -} - - (void) setScaleFactor:(float)theScaleFactor { OSSpinLockLock(&spinlockIsHUDVisible); - _cdv->SetScaleFactor(theScaleFactor); + _cdv->Get3DPresenter()->SetScaleFactor(theScaleFactor); OSSpinLockUnlock(&spinlockIsHUDVisible); } @@ -1184,13 +1190,13 @@ OSSpinLockUnlock(&spinlockReceivedFrameIndex); OSSpinLockLock(&spinlockNDSFrameInfo); - _cdv->SetHUDInfo(clientFrameInfo, _ndsFrameInfo); + _cdv->Get3DPresenter()->SetHUDInfo(clientFrameInfo, _ndsFrameInfo); OSSpinLockUnlock(&spinlockNDSFrameInfo); } -- (NSImage *) copyImageFromView +- (NSImage *) image { - NSSize viewSize = NSMakeSize(_cdv->GetViewProperties().clientWidth, _cdv->GetViewProperties().clientHeight); + NSSize viewSize = NSMakeSize(_cdv->Get3DPresenter()->GetPresenterProperties().clientWidth, _cdv->Get3DPresenter()->GetPresenterProperties().clientHeight); NSUInteger w = viewSize.width; NSUInteger h = viewSize.height; @@ -1218,7 +1224,7 @@ return newImage; } - _cdv->CopyFrameToBuffer((uint32_t *)[newImageRep bitmapData]); + _cdv->Get3DPresenter()->CopyFrameToBuffer((uint32_t *)[newImageRep bitmapData]); // Attach the rendered frame to the NSImageRep [newImage addRepresentation:newImageRep]; @@ -1226,86 +1232,4 @@ return [newImage autorelease]; } -- (NSImage *) image -{ - pthread_rwlock_rdlock(self.rwlockProducer); - NSSize displaySize = NSMakeSize((CGFloat)GPU->GetCustomFramebufferWidth(), (_cdv->GetMode() == ClientDisplayMode_Dual) ? (CGFloat)(GPU->GetCustomFramebufferHeight() * 2): (CGFloat)GPU->GetCustomFramebufferHeight()); - pthread_rwlock_unlock(self.rwlockProducer); - - NSImage *newImage = [[NSImage alloc] initWithSize:displaySize]; - if (newImage == nil) - { - return newImage; - } - - // Render the frame in an NSBitmapImageRep - NSBitmapImageRep *newImageRep = [self bitmapImageRep]; - if (newImageRep == nil) - { - [newImage release]; - newImage = nil; - return newImage; - } - - // Attach the rendered frame to the NSImageRep - [newImage addRepresentation:newImageRep]; - - return [newImage autorelease]; -} - -- (NSBitmapImageRep *) bitmapImageRep -{ - GPUClientFetchObject &fetchObjMutable = (GPUClientFetchObject &)_cdv->GetFetchObject(); - NDSDisplayInfo &displayInfoMutable = (NDSDisplayInfo &)fetchObjMutable.GetFetchDisplayInfoForBufferIndex(fetchObjMutable.GetLastFetchIndex()); - - NSUInteger w = (NSUInteger)displayInfoMutable.customWidth; - NSUInteger h = (_cdv->GetMode() == ClientDisplayMode_Dual) ? (NSUInteger)(displayInfoMutable.customHeight * 2) : (NSUInteger)displayInfoMutable.customHeight; - - NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL - pixelsWide:w - pixelsHigh:h - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace - bytesPerRow:w * 4 - bitsPerPixel:32]; - - if (imageRep == nil) - { - return imageRep; - } - - void *displayBuffer = displayInfoMutable.masterCustomBuffer; - uint32_t *bitmapData = (uint32_t *)[imageRep bitmapData]; - - pthread_rwlock_wrlock(self.rwlockProducer); - - GPU->PostprocessDisplay(NDSDisplayID_Main, displayInfoMutable); - GPU->PostprocessDisplay(NDSDisplayID_Touch, displayInfoMutable); - GPU->ResolveDisplayToCustomFramebuffer(NDSDisplayID_Main, displayInfoMutable); - GPU->ResolveDisplayToCustomFramebuffer(NDSDisplayID_Touch, displayInfoMutable); - - if (displayInfoMutable.pixelBytes == 2) - { - ColorspaceConvertBuffer555To8888Opaque((u16 *)displayBuffer, bitmapData, (w * h)); - } - else if (displayInfoMutable.pixelBytes == 4) - { - memcpy(bitmapData, displayBuffer, w * h * sizeof(uint32_t)); - } - - pthread_rwlock_unlock(self.rwlockProducer); - -#ifdef MSB_FIRST - for (size_t i = 0; i < w * h; i++) - { - bitmapData[i] = LE_TO_LOCAL_32(bitmapData[i]); - } -#endif - - return [imageRep autorelease]; -} - @end diff --git a/desmume/src/frontend/cocoa/translations/English.lproj/DisplayWindow.xib b/desmume/src/frontend/cocoa/translations/English.lproj/DisplayWindow.xib index d395726d2..70f475d89 100644 --- a/desmume/src/frontend/cocoa/translations/English.lproj/DisplayWindow.xib +++ b/desmume/src/frontend/cocoa/translations/English.lproj/DisplayWindow.xib @@ -359,7 +359,7 @@ {1.7976931348623157e+308, 1.7976931348623157e+308} {256, 408} - + 256 YES @@ -368,7 +368,6 @@ 5156 {{2, 3}, {16, 16}} - 28938 100 @@ -377,7 +376,6 @@ 294 {{17, 5}, {137, 14}} - YES 68157504 @@ -417,7 +415,6 @@ 289 {{192, -1}, {40, 26}} - YES -2076180416 @@ -487,7 +484,6 @@ 289 {{151, -1}, {42, 26}} - YES -2076180416 @@ -546,140 +542,12 @@ {256, 408} - - {{0, 0}, {1920, 1177}} {256, 477} {1.7976931348623157e+308, 1.7976931348623157e+308} YES - - - 268 - - YES - - - 268 - {{176, 5}, {126, 26}} - - YES - - -2076180416 - 2048 - - - 109199360 - 1 - - - 400 - 75 - - - TIFF - - 2147483647 - 1 - - - _popUpItemAction: - - - YES - - OtherViews - - YES - - - - BMP - - 2147483647 - - - _popUpItemAction: - 1 - - - - - GIF - - 2147483647 - - - _popUpItemAction: - 2 - - - - - JPEG - - 2147483647 - - - _popUpItemAction: - 3 - - - - - PNG - - 2147483647 - - - _popUpItemAction: - 4 - - - - - JPEG 2000 - - 2147483647 - - - _popUpItemAction: - 5 - - - - - - 1 - YES - YES - 2 - - NO - - - - 268 - {{38, 11}, {136, 17}} - - YES - - 68157504 - 71304192 - Select Image Format: - - - - - - NO - 1 - - - {350, 35} - NSView - 268 @@ -1065,30 +933,6 @@ 68 - - - saveScreenshotPanelAccessoryView - - - - 105 - - - - selectedTag: screenshotFileFormat - - - - - - selectedTag: screenshotFileFormat - selectedTag - screenshotFileFormat - 2 - - - 106 - reset: @@ -1623,93 +1467,6 @@ - - 93 - - - YES - - - - - Screenshot Save Panel Accessory - - - 94 - - - YES - - - - - - 95 - - - YES - - - - - - 96 - - - - - 97 - - - YES - - - - - - 98 - - - YES - - - - - - - - - - - 99 - - - - - 100 - - - - - 101 - - - - - 102 - - - - - 103 - - - - - 104 - - - 116 @@ -1922,11 +1679,6 @@ -2.IBPluginDependency -3.IBPluginDependency 10.IBPluginDependency - 100.IBPluginDependency - 101.IBPluginDependency - 102.IBPluginDependency - 103.IBPluginDependency - 104.IBPluginDependency 116.IBPluginDependency 117.IBPluginDependency 118.IBPluginDependency @@ -1981,13 +1733,6 @@ 4.IBPluginDependency 5.IBPluginDependency 6.IBPluginDependency - 93.IBPluginDependency - 94.IBPluginDependency - 95.IBPluginDependency - 96.IBPluginDependency - 97.IBPluginDependency - 98.IBPluginDependency - 99.IBPluginDependency YES @@ -2012,11 +1757,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin {183.5, 317.5} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -2054,13 +1794,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin @@ -2081,909 +1814,7 @@ 248 - - - YES - - DisplayWindowController - NSWindowController - - YES - - YES - changeCoreSpeed: - changeDisplayGap: - changeDisplayMode: - changeDisplayOrder: - changeDisplayOrientation: - changeDisplayVideoSource: - changeHardwareMicGain: - changeHardwareMicMute: - changeRotation: - changeRotationRelative: - changeScale: - changeVideoOutputFilter: - changeVideoPixelScaler: - changeVolume: - copy: - frameAdvance: - openRom: - reset: - saveScreenshotAs: - toggleExecutePause: - toggleFullScreenDisplay: - toggleHUDVisibility: - toggleKeepMinDisplaySizeAtNormal: - toggleNDSDisplays: - toggleShowHUDCPULoadAverage: - toggleShowHUDFrameIndex: - toggleShowHUDInput: - toggleShowHUDLagFrameCount: - toggleShowHUDRealTimeClock: - toggleShowHUDRender3DFPS: - toggleShowHUDVideoFPS: - toggleStatusBar: - toggleVideoFiltersPreferGPU: - toggleVideoSourceDeposterize: - writeDefaultsDisplayGap: - writeDefaultsDisplayRotation: - writeDefaultsDisplayVideoSettings: - writeDefaultsHUDSettings: - - - YES - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - id - - - - YES - - YES - changeCoreSpeed: - changeDisplayGap: - changeDisplayMode: - changeDisplayOrder: - changeDisplayOrientation: - changeDisplayVideoSource: - changeHardwareMicGain: - changeHardwareMicMute: - changeRotation: - changeRotationRelative: - changeScale: - changeVideoOutputFilter: - changeVideoPixelScaler: - changeVolume: - copy: - frameAdvance: - openRom: - reset: - saveScreenshotAs: - toggleExecutePause: - toggleFullScreenDisplay: - toggleHUDVisibility: - toggleKeepMinDisplaySizeAtNormal: - toggleNDSDisplays: - toggleShowHUDCPULoadAverage: - toggleShowHUDFrameIndex: - toggleShowHUDInput: - toggleShowHUDLagFrameCount: - toggleShowHUDRealTimeClock: - toggleShowHUDRender3DFPS: - toggleShowHUDVideoFPS: - toggleStatusBar: - toggleVideoFiltersPreferGPU: - toggleVideoSourceDeposterize: - writeDefaultsDisplayGap: - writeDefaultsDisplayRotation: - writeDefaultsDisplayVideoSettings: - writeDefaultsHUDSettings: - - - YES - - changeCoreSpeed: - id - - - changeDisplayGap: - id - - - changeDisplayMode: - id - - - changeDisplayOrder: - id - - - changeDisplayOrientation: - id - - - changeDisplayVideoSource: - id - - - changeHardwareMicGain: - id - - - changeHardwareMicMute: - id - - - changeRotation: - id - - - changeRotationRelative: - id - - - changeScale: - id - - - changeVideoOutputFilter: - id - - - changeVideoPixelScaler: - id - - - changeVolume: - id - - - copy: - id - - - frameAdvance: - id - - - openRom: - id - - - reset: - id - - - saveScreenshotAs: - id - - - toggleExecutePause: - id - - - toggleFullScreenDisplay: - id - - - toggleHUDVisibility: - id - - - toggleKeepMinDisplaySizeAtNormal: - id - - - toggleNDSDisplays: - id - - - toggleShowHUDCPULoadAverage: - id - - - toggleShowHUDFrameIndex: - id - - - toggleShowHUDInput: - id - - - toggleShowHUDLagFrameCount: - id - - - toggleShowHUDRealTimeClock: - id - - - toggleShowHUDRender3DFPS: - id - - - toggleShowHUDVideoFPS: - id - - - toggleStatusBar: - id - - - toggleVideoFiltersPreferGPU: - id - - - toggleVideoSourceDeposterize: - id - - - writeDefaultsDisplayGap: - id - - - writeDefaultsDisplayRotation: - id - - - writeDefaultsDisplayVideoSettings: - id - - - writeDefaultsHUDSettings: - id - - - - - YES - - YES - microphoneGainControlView - microphoneGainMenuItem - microphoneGainSlider - microphoneMuteButton - outputVolumeControlView - outputVolumeMenuItem - saveScreenshotPanelAccessoryView - - - YES - NSView - NSMenuItem - NSSlider - NSButton - NSView - NSMenuItem - NSView - - - - YES - - YES - microphoneGainControlView - microphoneGainMenuItem - microphoneGainSlider - microphoneMuteButton - outputVolumeControlView - outputVolumeMenuItem - saveScreenshotPanelAccessoryView - - - YES - - microphoneGainControlView - NSView - - - microphoneGainMenuItem - NSMenuItem - - - microphoneGainSlider - NSSlider - - - microphoneMuteButton - NSButton - - - outputVolumeControlView - NSView - - - outputVolumeMenuItem - NSMenuItem - - - saveScreenshotPanelAccessoryView - NSView - - - - - IBProjectSource - userinterface/DisplayWindowController.h - - - - - YES - - NSActionCell - NSCell - - IBFrameworkSource - AppKit.framework/Headers/NSActionCell.h - - - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSButton - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSButton.h - - - - NSButtonCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSButtonCell.h - - - - NSCell - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSCell.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSMenuItemCell - NSButtonCell - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItemCell.h - - - - NSNumberFormatter - NSFormatter - - IBFrameworkSource - Foundation.framework/Headers/NSNumberFormatter.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CAAnimation.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CALayer.h - - - - NSObject - - IBFrameworkSource - QuartzCore.framework/Headers/CIImageProvider.h - - - - NSPopUpButton - NSButton - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButton.h - - - - NSPopUpButtonCell - NSMenuItemCell - - IBFrameworkSource - AppKit.framework/Headers/NSPopUpButtonCell.h - - - - NSProgressIndicator - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSProgressIndicator.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSSlider - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSSlider.h - - - - NSSliderCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSSliderCell.h - - - - NSTextField - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSTextField.h - - - - NSTextFieldCell - NSActionCell - - IBFrameworkSource - AppKit.framework/Headers/NSTextFieldCell.h - - - - NSToolbar - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbar.h - - - - NSToolbarItem - NSObject - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - NSWindowController - NSResponder - - showWindow: - id - - - showWindow: - - showWindow: - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSWindowController.h - - - - + 0 IBCocoaFramework diff --git a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.strings b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.strings index c6c55143fe5ea60427f6133b3a40e2753602a50a..093d6455381b51c0b968b8ff7f8336d45437961c 100644 GIT binary patch delta 4852 zcma)AeQ;FO6@T~L`yjzJZZIJvo4|%7BrHkT-E6YEP;oaF2$=vI5)=W$B7z@KNDx94 z${0mO2630Gd#2V2*_0VS+UX>Ytut0Jary^CttR?MhiVPbQ}!s^6uZ)@>{fPjS9b|@Dz&gBpyd(#T0x8W)v=tZwINYK zTC`R)w1e*+%LjH&D}~3y+ALhz{WEHtAiD3IwoAB$`rlAHeEJ40;KS<}ty5gEr9jIi zb+9Od)R-Dg{QR3Cp@8q>S6Lo@4HT<39y(hG_V-jfZ;NC>^0ZoE>YUK>(3Y3SE%|&n zVimG1=sk^^&UmY?#JfMf6#}D7IQ4T^XFd!E)eT^eYYpNJG_Tfjo6k?mT6c%KEKL3B3g@<8|tl|lPulEt5Y!5Vu< zwScEjDLopEjR|S{(4$Vlsnwj^*S{nIL5+Pc)awh`fAc zi5?MJjed<*hyTqi*INoB4#YV8K$GTFye9Hqa9u)ZKYJiNy;WJMELWC;>l;==g+j54 zsqw<-Wwl7tMFVryHFT8{k~+}WKyoCes3a1k)hj6DLo-)tD}*hnC1l^IshtL&Lp>=K zdea+~kg`l!Vfu8-Jm8X{3~Dol(qKqgZK%PXH51&vuN6_02%TFDV_3~@#i=-9bh=hX zynJ*pdA`)$zMp!GuEABIJ{DO9$_09Gmw_j zjtWEiHrJj)d*q-1;@#U=k;pfH|9}-Xb)vcPeN6Tvs<^6jm*Bje6+%-d`*G}HRtfff z%wbgB&@x>EJ$QKZDE85D)=oA<@Htkct3YrYO>I2dkA-<01MA<*tf)4$mn})vpvNq+ z>?)!oH`t*$M8#B*l!e4G4E>1afxy#b9{=EgTR;v&7Yz*<-be~z=ig}!>j@9QDz#;9%SZjp!h3V z1lB#w0+A>?Xm}ggFTITzvJG&)j+CZ6WnW{WjfflfGMuE-c=F(0*@Cq&FimWN4>2ie zg>WtLh;^{`!*p>ZF5svsyi6@T>p)iQ3T@!M8yNiBqq{)M%^OpAL-Zmlw_Tz~4fl1t zIee=`tT}{U(9FF&u&+YCiGPQ))ys<)p?5b9ykj+_6s-B0gC`A*?juIz2w5FO9R$UP3F{`zEO-h-p*ZssUrgkv;yY$#`?V$QL`Y+-( z#>31^Pn}tU3Dkf~8`&WPIByEL=uVXMY|8t4$}V!ydkj)*R+>w)etHn)sS_Rxn<5nTaD!iwimKr!E$Lo$QGY?xe)q~ zV&GXZR%d`47bl+33jQ1ihb6}5z-LF8okwEzc;;C7pAQvcrw@J1a?SZ1Ka7gWx77e| zU*v|_?W_QjxXcLFX9mj?(`_j!gD@~VL_Wmk+xZ|VfI|E*cF@6OdOO_A#>0nZ!;CL! zDTMy0*6VWa%G6VXyYxZFUqr;8u!;#9K-Nv@svcG(6gCJ7kiT4cP}wP2NehyTPWjY? zqj@Wg60HiX52bPPNdyE(xz4KK5!Hn#N_tV}R`s^_rAy5RqSVBkVEo$HOhBC+Zhuz5 z*$6$aAZrp_1huvrGl%;01nq zo%p8(245ptaQr)h!zQlH;MSPwNP_Ew?zmQlZy9fo*&%tq=7deJnwv=j>{EPr4&eFp zDshMc;O8S&-gelI1yDRh^#Z`{`3!bshacUAZ60`%tTnsQq71EwTXwBJv2DJT6_;pvT&*eOFRq`#oln`}F+a|YUu~O@ZaZEex?8v!BZa)@ z?t?h)d?v{f4`Pz=rVW*1zi>W6XU9}+4nbg^F{(x=VFxS_!hkq0&}{G*hFOfp&l6i8 zfu)?z7eVlkYD{b)y8vsgt%p|19l_}yDq9_m51iADgYy)g7#B{^R#@L>Nc}KUh6Rnx z@E%06k2<3E3J65$JYgQ@y=*qNA4aqEV?f;+c6;0iYlybw300)(t+e);pX63KS; z)YRD^+UWIOEe}F75v9-q%hb9+#^^F0Dqk$q<%a>AnH79KNo`^!-&C$w?C{b?{#LnV zGS9}ans?`74*W>!qH~ywZ)%q+X`=0i?gbOf2Jtu!oqd2OE3)#g*NaqGlnmal^T^PG zA6|fMxP%W@%>(CVmNk8=d&dR2w`0Fu^S-i7UuSh>H&Nt34bloWv zNm?NO5?cs%2lMdPYwSi8%~nA${Xq6J8@UUbGu6AP3;*x7%6pyl4sZlEN*(Vsf z(xuc1p1x8ry5U>UMr42_*ih|>;J!UJpfyFW%5ZIxz%tz&+y<6GNqkqk% z+m$^)cB}fu6%#GUIo1i1^P5}ntpC39$YB};dmqVJC{oyt^%BAgYLYcni#6ntHRP4| zye_3y?p@zGVqPVA8{P`tyg+T6tMy=+YzwJ4H8G)Dyh?%$N{AH220|3*3B#!_9 diff --git a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib index 3dcf864e2..43d832ff7 100644 --- a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib +++ b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib @@ -12,7 +12,7 @@ YES - + YES @@ -1919,9 +1919,9 @@ Tools YES - + - Save Screenshot As... + Show Screenshot Capture Tool... 2147483647 @@ -2164,7 +2164,7 @@ 134217728 33554432 - + NSImage NSApplicationIcon @@ -3863,7 +3863,7 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA -2034483200 100 - + 200 @@ -4139,7 +4139,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{72, 43}, {84, 17}} - YES 68157504 @@ -4158,7 +4157,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{44, 16}, {112, 17}} - YES 68157504 @@ -4177,7 +4175,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{158, 37}, {126, 26}} - YES -2076180416 @@ -4270,7 +4267,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA {{289, 14}, {72, 22}} - YES -1804599231 @@ -4363,7 +4359,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{63, 69}, {93, 17}} - YES 68157504 @@ -4382,7 +4377,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{158, 63}, {126, 26}} - YES -2076180416 @@ -4451,7 +4445,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{158, 11}, {126, 26}} - YES -2076180416 @@ -4553,12 +4546,10 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA {{1, 1}, {429, 97}} - {{6, 232}, {431, 113}} - {0, 0} 67108864 @@ -4589,7 +4580,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{15, 16}, {126, 17}} - YES 68157504 @@ -4691,7 +4681,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{144, 10}, {189, 26}} - YES -2080112384 @@ -4714,7 +4703,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{305, 36}, {38, 11}} - YES 68157504 @@ -4737,7 +4725,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{263, 36}, {38, 11}} - YES 68157504 @@ -4756,7 +4743,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{220, 36}, {38, 11}} - YES 68157504 @@ -4775,7 +4761,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{178, 36}, {38, 11}} - YES 68157504 @@ -4794,7 +4779,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA268 {{137, 36}, {38, 11}} - YES 68157504 @@ -5002,7 +4986,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA {{6, 5}, {431, 132}} - {0, 0} 67108864 @@ -5258,7 +5241,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA {{10, 33}, {443, 350}} - Display Views @@ -6275,7 +6257,6 @@ L3d3dy5hZHZhbnNjZW5lLmNvbS9vZmZsaW5lL2RhdGFzL0FEVkFOc0NFbmVfUlRvb2xEUy56aXA {489, 420} - NSView @@ -14255,7 +14236,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {1.7976931348623157e+308, 1.7976931348623157e+308} - + 256 YES @@ -14264,7 +14245,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 77}, {366, 17}} - _NS:3939 YES @@ -14289,7 +14269,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 289 {{290, 12}, {96, 32}} - _NS:610 YES @@ -14313,7 +14292,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 289 {{194, 12}, {96, 32}} - _NS:610 2 YES @@ -14338,7 +14316,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 292 {{17, 53}, {366, 16}} - _NS:3939 YES @@ -14361,8 +14338,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {400, 114} - - _NS:122 {{0, 0}, {1440, 878}} @@ -14409,11 +14384,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 - - + + -2147483392 {{256, 0}, {16, 17}} - YES @@ -14565,7 +14539,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 _doScroller: 0.99630996309963105 - {{20, 49}, {272, 353}} @@ -14917,7 +14890,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 134217728 33554432 - + 0 3 0 @@ -17335,7 +17308,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 134217728 33554432 - + 0 3 0 @@ -18467,7 +18440,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 134217728 33554432 - + 0 3 0 @@ -19765,7 +19738,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 YES - -2080374784 + 67108864 134217728 @@ -20843,14 +20816,14 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 1 - {260, 328} + {255, 328} NSView - {260, 328} + {255, 328} {0, 328} - {260, 328} + {255, 328} 2 0.0 0.0 @@ -26615,7 +26588,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 15 2 - {{64, 220}, {330, 811}} + {{64, 280}, {330, 811}} 1685585920 ROM Info RomInfoPanel @@ -26624,7 +26597,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {330, 811} {330, 88} - + 256 YES @@ -27996,7 +27969,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 134217728 33554432 - + 0 3 0 @@ -28013,6 +27986,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 1}, {330, 811}} + _NS:353 @@ -28027,7 +28001,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NO _doScroller: - 0.94814814814814818 + 0.96419753086419757 @@ -28044,6 +28018,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{-1, -2}, {332, 813}} + _NS:351 133138 @@ -28056,7 +28031,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {330, 811} - {{0, 0}, {1920, 1177}} {330, 110} @@ -28697,6 +28671,2265 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 SetSeparationPanel YES + + 23 + 2 + {{57, 380}, {480, 170}} + -461896704 + Screenshot Capture Tool + NSPanel + + + {480, 170} + {480, 170} + + + 256 + + YES + + + 306 + {{8, 9}, {267, 114}} + + _NS:2337 + YES + + 67108864 + 134217728 + Take Screenshot + + _NS:2337 + + -2038153216 + 130 + + + 400 + 75 + + NO + + + + 266 + {{10, 129}, {377, 18}} + + _NS:817 + YES + + -2069888959 + 272766528 + + + Screenshot Directory Path + _NS:817 + + + + + NO + 1 + + + + 265 + {{390, 123}, {85, 28}} + + _NS:610 + YES + + 67108864 + 134348800 + Choose... + + _NS:610 + + -2038284288 + 129 + + + 200 + 25 + + NO + + + + 268 + {{11, 148}, {161, 14}} + + _NS:4068 + YES + + 68157504 + 272761856 + Screenshot File Save Location + + _NS:4068 + + + + + NO + 1 + + + + 33 + + YES + + + 274 + + YES + + + 289 + {{155, 10}, {27, 27}} + + YES + + 67108864 + 134217728 + + + + -2030288896 + 130 + + + + 400 + 75 + + NO + + + + 289 + {{10, 17}, {142, 14}} + + _NS:4068 + YES + + 68157504 + 71435264 + Configure Display Layout: + + _NS:4068 + + + + + NO + 1 + + + + 289 + {{19, 73}, {76, 14}} + + _NS:4068 + YES + + 68157504 + 4326400 + File Format + + _NS:4068 + + + + + NO + 1 + + + + 289 + {{10, 51}, {173, 22}} + + _NS:791 + YES + + -2076180416 + 133120 + + _NS:791 + + 109199360 + 129 + + + 400 + 75 + + + TIFF + + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + BMP + + 2147483647 + + + _popUpItemAction: + 1 + + + + + GIF + + 2147483647 + + + _popUpItemAction: + 2 + + + + + JPEG + + 2147483647 + + + _popUpItemAction: + 3 + + + + + PNG + + 2147483647 + + + _popUpItemAction: + 4 + + + + + JPEG 2000 + + 2147483647 + + + _popUpItemAction: + 5 + + + + + + 1 + YES + YES + 2 + + NO + + + + 12 + {{9, 41}, {175, 5}} + + _NS:2429 + {0, 0} + + 67108864 + 0 + Box + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + 3 + 2 + 0 + NO + + + {{1, 1}, {193, 97}} + + _NS:21 + + + {{278, 9}, {195, 113}} + + _NS:18 + {0, 0} + + 67108864 + 0 + Screenshot Settings + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + + 1 + 0 + 2 + NO + + + {480, 170} + _NS:103 + + {{0, 0}, {1440, 878}} + {480, 186} + {480, 186} + ScreenshotCaptureToolPanel + NO + + + + 256 + + YES + + + 8 + {{313, 5}, {5, 150}} + + _NS:2182 + {0, 0} + + 67108864 + 0 + Box + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + 3 + 2 + 0 + NO + + + + 8 + {{156, 5}, {5, 150}} + + _NS:2182 + {0, 0} + + 67108864 + 0 + Box + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + 3 + 2 + 0 + NO + + + + 264 + {{329, 33}, {74, 14}} + + _NS:4068 + YES + + 68157504 + 272761856 + Pixel Scaler + + _NS:4068 + + + + + NO + 1 + + + + 264 + {{15, 52}, {103, 14}} + + _NS:4068 + YES + + 68157504 + 272761856 + Display Separation + + _NS:4068 + + + + + NO + 1 + + + + 264 + {{7, 30}, {146, 22}} + + _NS:791 + YES + + -2076180416 + 133120 + + _NS:791 + + 109199360 + 129 + + + 400 + 75 + + + 0% + + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + 50% + + 2147483647 + + + _popUpItemAction: + 50 + + + + + 100% + + 2147483647 + + + _popUpItemAction: + 100 + + + + + 150% + + 2147483647 + + + _popUpItemAction: + 150 + + + + + 200% + + 2147483647 + + + _popUpItemAction: + 200 + + + + + + 1 + YES + YES + 2 + + NO + + + + 264 + {{15, 92}, {92, 14}} + + _NS:4068 + YES + + 68157504 + 272761856 + Display Rotation + + _NS:4068 + + + + + NO + 1 + + + + 264 + {{7, 70}, {146, 22}} + + _NS:791 + YES + + -2076180416 + 133120 + + _NS:791 + + 109199360 + 129 + + + 400 + 75 + + + 0º + + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + 90º + + 2147483647 + + + _popUpItemAction: + 90 + + + + + 180º + + 2147483647 + + + _popUpItemAction: + 180 + + + + + 270º + + 2147483647 + + + _popUpItemAction: + 270 + + + + + + 1 + YES + YES + 2 + + NO + + + + 264 + {{15, 132}, {80, 14}} + + _NS:4068 + YES + + 68157504 + 272761856 + Display Mode + + _NS:4068 + + + + + NO + 1 + + + + 264 + {{7, 110}, {146, 22}} + + _NS:791 + YES + + -2076180416 + 133120 + + _NS:791 + + 109199360 + 129 + + + 400 + 75 + + + Dual Screen + + 2147483647 + 1 + + + _popUpItemAction: + 2 + + + YES + + OtherViews + + YES + + + Main + + 2147483647 + + + _popUpItemAction: + + + + + Touch + + 2147483647 + + + _popUpItemAction: + 1 + + + + + + + 2 + 1 + YES + YES + 2 + + NO + + + + 264 + {{329, 74}, {80, 14}} + + _NS:4068 + YES + + 68157504 + 272761856 + Output Filter + + _NS:4068 + + + + + NO + 1 + + + + 264 + {{172, 132}, {90, 14}} + + _NS:4068 + YES + + 68157504 + 272761856 + Display Layout + + _NS:4068 + + + + + NO + 1 + + + + 8 + + YES + + + 274 + + YES + + + 268 + {{15, 12}, {87, 18}} + + _NS:682 + YES + + 67108864 + 131072 + Deposterize + + _NS:682 + + 1211912448 + 2 + + + + + 200 + 25 + + NO + + + {{1, 1}, {144, 38}} + + _NS:21 + + + {{321, 92}, {146, 54}} + + _NS:18 + {0, 0} + + 67108864 + 0 + Source Filters + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + + 1 + 0 + 2 + NO + + + + 264 + {{321, 11}, {146, 22}} + + _NS:791 + YES + + -2076180416 + 133120 + + _NS:791 + + 109199360 + 129 + + + 400 + 75 + + + None + + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + Nearest 2x + + 2147483647 + + + _popUpItemAction: + 11 + + + + + Scanline + + 2147483647 + + + _popUpItemAction: + 9 + + + + + EPX + + 2147483647 + + + _popUpItemAction: + 14 + + + + + EPX+ + + 2147483647 + + + _popUpItemAction: + 15 + + + + + Super Eagle + + 2147483647 + + + _popUpItemAction: + 8 + + + + + 2xSaI + + 2147483647 + + + _popUpItemAction: + 6 + + + + + Super 2xSaI + + 2147483647 + + + _popUpItemAction: + 7 + + + + + LQ2x + + 2147483647 + + + _popUpItemAction: + 1 + + + + + LQ2xS + + 2147483647 + + + _popUpItemAction: + 2 + + + + + HQ2x + + 2147483647 + + + _popUpItemAction: + 3 + + + + + HQ2xS + + 2147483647 + + + _popUpItemAction: + 4 + + + + + HQ3x + + 2147483647 + + + _popUpItemAction: + 23 + + + + + HQ3xS + + 2147483647 + + + _popUpItemAction: + 24 + + + + + HQ4x + + 2147483647 + + + _popUpItemAction: + 5 + + + + + HQ4xS + + 2147483647 + + + _popUpItemAction: + 18 + + + + + 2xBRZ + + 2147483647 + + + _popUpItemAction: + 19 + + + + + 3xBRZ + + 2147483647 + + + _popUpItemAction: + 20 + + + + + 4xBRZ + + 2147483647 + + + _popUpItemAction: + 21 + + + + + 5xBRZ + + 2147483647 + + + _popUpItemAction: + 22 + + + + + 6xBRZ + + 2147483647 + + + _popUpItemAction: + 25 + + + + + + 1 + YES + YES + 2 + + NO + + + + 264 + {{321, 52}, {146, 22}} + + _NS:791 + YES + + -2076180416 + 133120 + + _NS:791 + + 109199360 + 129 + + + 400 + 75 + + + Bilinear + + 2147483647 + 1 + + + _popUpItemAction: + 1 + + + YES + + OtherViews + + YES + + + Nearest Neighbor + + 2147483647 + + + _popUpItemAction: + + + + + + Bicubic (B_Spline) + + 2147483647 + + + _popUpItemAction: + 2 + + + + + Bicubic (Michell-Netravali) + + 2147483647 + + + _popUpItemAction: + 3 + + + + + Lanczos2 + + 2147483647 + + + _popUpItemAction: + 4 + + + + + Lanczos3 + + 2147483647 + + + _popUpItemAction: + 5 + + + + + + 1 + 1 + YES + YES + 2 + + NO + + + + 264 + {{164, 110}, {146, 22}} + + _NS:791 + YES + + -2076180416 + 133120 + + _NS:791 + + 109199360 + 129 + + + 400 + 75 + + + Vertical + + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + Horizontal + + 2147483647 + + + _popUpItemAction: + 1 + + + + + Hybrid (2:1) + + 2147483647 + + + _popUpItemAction: + 1000 + + + + + Hybrid (16:9) + + 2147483647 + + + _popUpItemAction: + 1001 + + + + + Hybrid (16:10) + + 2147483647 + + + _popUpItemAction: + 1002 + + + + + + 1 + YES + YES + 2 + + NO + + + + 8 + + YES + + + 274 + + YES + + + 268 + {{8, 14}, {132, 32}} + + _NS:736 + YES + NO + 2 + 1 + + YES + + -2080374784 + 131072 + Main Display First + + + 1211912448 + 0 + + + + 200 + 25 + + + 67108864 + 131072 + Touch Display First + + + 1 + 1211912448 + 0 + + 549453824 + {18, 18} + + YES + + YES + + + + TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw +IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ +29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 +dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA +AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG +AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ +0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ +7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ +5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ +3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD +AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns +AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ +6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ +/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ +///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl +YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA +AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD +AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu +AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgEAAAMAAAABABIAAAEB +AAMAAAABABIAAAECAAMAAAAEAAAFxgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS +AAMAAAABAAEAAAFTAAMAAAAEAAAFzodzAAcAAAwYAAAF1gAAAAAACAAIAAgACAABAAEAAQABAAAMGGFw +cGwCAAAAbW50clJHQiBYWVogB9YABAADABMALAASYWNzcEFQUEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAOclhZWgAAASwAAAAUZ1hZWgAAAUAAAAAUYlhZWgAAAVQAAAAUd3RwdAAAAWgAAAAUY2hhZAAA +AXwAAAAsclRSQwAAAagAAAAOZ1RSQwAAAbgAAAAOYlRSQwAAAcgAAAAOdmNndAAAAdgAAAMSbmRpbgAA +BOwAAAY+ZGVzYwAACywAAABkZHNjbQAAC5AAAAAubW1vZAAAC8AAAAAoY3BydAAAC+gAAAAtWFlaIAAA +AAAAAF1KAAA0kQAACCVYWVogAAAAAAAAdCAAALRgAAAjPVhZWiAAAAAAAAAlbAAAFyoAAKfDWFlaIAAA +AAAAAPNSAAEAAAABFs9zZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbGN1 +cnYAAAAAAAAAAQHNAABjdXJ2AAAAAAAAAAEBzQAAY3VydgAAAAAAAAABAc0AAHZjZ3QAAAAAAAAAAAAD +AQAAAQACBAUGBwkKCw0ODxASExQWFxgaGxweHyAiIyQmJygpKywtLzAxMjM1Njc4OTs8PT5AQUJDREZH +SElKS0xOT1BRUlNUVVZXWFlaW1xdXl9hYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SF +hoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnZ6foKGio6SlpqanqKmqq6ytra6vsLGysrO0tba3uLi5uru8 +vL2+v8DBwcLDxMXGxsfIycrKy8zNzs7P0NHS0tPU1dbW19jZ2drb3Nzd3t/g4eLi4+Tl5ufo6enq6+zt +7u/w8fHy8/T19vf4+fr7/P3+/v8AAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR8gISIjJCUnKCkq +Ky0uLzAxMzQ1Njc4OTo7PD0/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaWltcXV5fYGFiY2RlZmdo +aWprbG1ub3BxcnN0dXZ3d3h5ent8fH1+f4CBgoKDhIWGh4iIiYqLjI2Oj5CRkpOUlJWWl5iZmpucnZ2e +n6ChoqOkpaamp6ipqqusra6vsLCxsrO0tba3uLm5uru8vb6/wMHCw8TFx8jJysvMzc7P0NDR0tPU1dbX +2Nna29ze3+Dh4uPk5ebn6err7O3u7/Hy8/T19vf5+vv8/f7/AAIDAwQFBgcICQoKCwwNDg8QERITFBUW +FxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODg5Ojs8PT4+P0BBQkNDREVGR0hJSUpLTE1O +Tk9QUVJSU1RVVVZXWFhZWltbXF1eXl9gYWFiY2RkZWZnZ2hpaWprbGxtbm5vcHFxcnNzdHV1dnd4eHl6 +ent8fH1+fn+AgYGCg4SEhYaHiImJiouMjY6Oj5CRkpOTlJWWl5iZmZqbnJ2en6ChoqOkpaanqKmqq6yt +rq+xsrO0tba3uLq7vL2+wMHDxMbHycrMzs/R0tTW19nb3d7g4uTm6Ors7vDy9Pb4+vz+/wAAbmRpbgAA +AAAAAAY2AACXGgAAVjoAAFPKAACJ3gAAJ8IAABaoAABQDQAAVDkAAiuFAAIZmQABeFEAAwEAAAIAAAAA +AAEABgANABcAIwAxAEAAUgBlAHsAkwCrAMUA4gD/AR8BPwFhAYUBqgHQAfgCIAJLAncCpQLSAwIDMwNl +A5gDzgQFBD0EdQSvBOsFKQVnBacF6AYqBm4GtQb8B0UHkgfkCDkIkAjnCT4JmAn0ClAKrQsLC2sLygwq +DIwM8Q1XDcAOKA6SDv4PbA/bEE0QxBE7EbQSMRKwEzITuRREFNAVYBXxFocXHhfAGGIZBBmsGlQa+RuU +HC4czh1yHhQeux9jIA0gvCFoIhkizyOJJEEk+SW6JnknOygFKMspkypiKzIsASzXLawuhy9gMD4xGzH8 +MtszvzSgNYY2cjdcOEw5OTorOxs8CD0EPfU+6z/nQOFB2ELUQ9VE00XcRttH5EjxSgBLCUwdTTFOUE9v +UI9Rt1LdVAVVNlZsV6VY4FohW21ct135X09goGH0Y0tkqGYFZ19oxGova5ptCG54b/BxbnLsdG119Xd/ +eQh6knwqfcV/W4D4gpSEO4Xih4CJKorYjIqOOY/jkZuTWJUOlsyYiZpSnB6d4Z+soX+jWqUvpxOo+6rj +rMuuwLC4sra0rra0uL+60LzfvwDBHcLdxLXGhchYyi7MCs3lz7rRmtOA1WPXR9kq2xPc/97s4M/iveSn +5o3obupT7ELuLPAM8fLz0PW396H5f/tZ/T3//wAAAAEAAwALABYAJQA3AE0AZQCBAJ8AwQDlAQsBNQFh +AZABwQH1AisCZAKfAtwDHANfA6MD6gQ0BH8EzQT1BR0FcAXEBhsGdAbPBy0HXAeMB+4IUgi4CSAJVAmK +CfYKZArVC0cLgQu8DDIMqw0mDaIOIQ6hDyQPqRAvELgQ/RFDEc8SXRLuE4AUFRSrFUMV3RZ5FxcXthhY +GPwZoRpIGvEbnBxJHPgdqB5bHw8fxSB9ITch8iKwJDAk8yW3Jn4nRigQKNwpqSp5K0osHCzxLccuoC95 +MFUxMzISMvMz1TS5NaA2hzdxOFw5STo4Oyg8Gj4DPvs/9EDuQepD6ETpRexG8Uf3SP9LFEwhTTBOQE9S +UGZSklOrVMVV4Vb/WB5ZP1phW4Vcq13SXvthUmJ/Y69k4GYSZ0dofGm0au1tZG6ib+FxInJlc6l073Y2 +d396FXtjfLJ+A39VgKmB/4NWhK+GCYjCiiGLgYzjjkePrJESknuT5Ja8mCuZm5sMnH+d9J9qoOGiWqPV +pVGmz6eOqE6pzqtRrNSuWq/gsWmy8rR+tgu5Kbq6vE294b93wQ7Cp8RBxd3He8kZyrrLisxbzf/Po9FK +0vHUm9ZF1/HZn9tO3Cbc/96x4GTiGePQ5YjnQegf6Pzquex27jbv9/G583z0X/VC9wj40Pqa/GX+Mf// +AAAAAQADAAsAJQA3AE0AZQCBAJ8AwQELATUBYQGQAcEB9QIrAmQCnwLcAxwDXwOjA+oENAR/BM0FHQVw +BcQGGwZ0Bs8HLQeMB+4IUgi4CSAJign2CmQK1QtHC7wMMgyrDSYNog4hDqEPJA+pEC8QuBFDEl0S7hOA +FBUUqxVDFnkXFxe2GFgY/BpIGvEbnBxJHPgdqB8PH8UgfSE3IfIjbyQwJPMltydGKBAo3Cp5K0osHC3H +LqAveTEzMhIy8zS5NaA2hzhcOUk6ODwaPQ4+Az/0QO5C6EPoROlG8Uf3SglLFEwhTkBPUlF7UpJUxVXh +Vv9ZP1phXKtd0mAlYVJjr2TgZhJofGm0au1tZG6ib+FxInJldO92Nnd/eMl6FXyyfgN/VYCpgf+Er4YJ +h2WIwoohi4GOR4+skRKSe5PklVCWvJgrmZubDJx/nfSfaqDholqj1aVRps+oTqnOq1Gs1K2Xrlqv4LFp +svK0frYLt5m5Kbnxurq8Tb3hv3fBDsHawqfEQcUPxd3He8hKyRnKusuKzFvN/87Rz6PQdtFK0vHTxtSb +1kXXG9fx2MjZn9tO3Cbc/93Y3rHfiuBk4hni9ePQ5KzliOZk50HoH+j86drqueuX7HbtVu427xbv9/DX +8bnymvN89F/1QvYl9wj37PjQ+bX6mvt//GX9S/4x//8AAGRlc2MAAAAAAAAACkNvbG9yIExDRAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABIAAAAcAEMAbwBsAG8AcgAgAEwAQwBE +AABtbW9kAAAAAAAABhAAAJxOAAAAAL5zkQAAAAAAAAAAAAAAAAAAAAAAdGV4dAAAAABDb3B5cmlnaHQg +QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA + + + + + + + + 400 + 75 + + + {132, 15} + {4, 2} + 1151868928 + NSActionCell + + 67108864 + 131072 + Radio + + 1211912448 + 0 + + 549453824 + {18, 18} + + YES + + YES + + + + TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw +IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ +29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 +dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA +AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG +AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ +0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ +7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ +5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ +3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD +AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns +AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ +6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ +/v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ +///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl +YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA +AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD +AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu +AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgEAAAMAAAABABIAAAEB +AAMAAAABABIAAAECAAMAAAAEAAAFxgEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES +AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS +AAMAAAABAAEAAAFTAAMAAAAEAAAFzodzAAcAAAxIAAAF1gAAAAAACAAIAAgACAABAAEAAQABAAAMSExp +bm8CEAAAbW50clJHQiBYWVogB84AAgAJAAYAMQAAYWNzcE1TRlQAAAAASUVDIHNSR0IAAAAAAAAAAAAA +AAAAAPbWAAEAAAAA0y1IUCAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAARY3BydAAAAVAAAAAzZGVzYwAAAYQAAABsd3RwdAAAAfAAAAAUYmtwdAAAAgQAAAAUclhZWgAA +AhgAAAAUZ1hZWgAAAiwAAAAUYlhZWgAAAkAAAAAUZG1uZAAAAlQAAABwZG1kZAAAAsQAAACIdnVlZAAA +A0wAAACGdmlldwAAA9QAAAAkbHVtaQAAA/gAAAAUbWVhcwAABAwAAAAkdGVjaAAABDAAAAAMclRSQwAA +BDwAAAgMZ1RSQwAABDwAAAgMYlRSQwAABDwAAAgMdGV4dAAAAABDb3B5cmlnaHQgKGMpIDE5OTggSGV3 +bGV0dC1QYWNrYXJkIENvbXBhbnkAAGRlc2MAAAAAAAAAEnNSR0IgSUVDNjE5NjYtMi4xAAAAAAAAAAAA +AAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAFhZWiAAAAAAAADzUQABAAAAARbMWFlaIAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAA +b6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9kZXNjAAAAAAAA +ABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAAAAAAAAAAABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAuSUVDIDYx +OTY2LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAAAAAAAAAuSUVDIDYxOTY2 +LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRl +c2MAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUM2MTk2Ni0yLjEAAAAAAAAA +AAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4gSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAB2aWV3AAAAAAATpP4AFF8uABDPFAAD7cwABBMLAANcngAAAAFYWVogAAAAAABM +CVYAUAAAAFcf521lYXMAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAKPAAAAAnNpZyAAAAAAQ1JUIGN1 +cnYAAAAAAAAEAAAAAAUACgAPABQAGQAeACMAKAAtADIANwA7AEAARQBKAE8AVABZAF4AYwBoAG0AcgB3 +AHwAgQCGAIsAkACVAJoAnwCkAKkArgCyALcAvADBAMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQET +ARkBHwElASsBMgE4AT4BRQFMAVIBWQFgAWcBbgF1AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHp +AfIB+gIDAgwCFAIdAiYCLwI4AkECSwJUAl0CZwJxAnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUDAAML +AxYDIQMtAzgDQwNPA1oDZgNyA34DigOWA6IDrgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsESARVBGMEcQR+ +BIwEmgSoBLYExATTBOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1BcUF1QXlBfYGBgYWBicGNwZI +BlkGagZ7BowGnQavBsAG0QbjBvUHBwcZBysHPQdPB2EHdAeGB5kHrAe/B9IH5Qf4CAsIHwgyCEYIWghu +CIIIlgiqCL4I0gjnCPsJEAklCToJTwlkCXkJjwmkCboJzwnlCfsKEQonCj0KVApqCoEKmAquCsUK3Arz +CwsLIgs5C1ELaQuAC5gLsAvIC+EL+QwSDCoMQwxcDHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2ODakNww3e +DfgOEw4uDkkOZA5/DpsOtg7SDu4PCQ8lD0EPXg96D5YPsw/PD+wQCRAmEEMQYRB+EJsQuRDXEPURExEx +EU8RbRGMEaoRyRHoEgcSJhJFEmQShBKjEsMS4xMDEyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTw +FRIVNBVWFXgVmxW9FeAWAxYmFkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY+hkg +GUUZaxmRGbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxSHHscoxzMHPUdHh1HHXAdmR3D +HeweFh5AHmoelB6+HukfEx8+H2kflB+/H+ogFSBBIGwgmCDEIPAhHCFIIXUhoSHOIfsiJyJVIoIiryLd +IwojOCNmI5QjwiPwJB8kTSR8JKsk2iUJJTglaCWXJccl9yYnJlcmhya3JugnGCdJJ3onqyfcKA0oPyhx +KKIo1CkGKTgpaymdKdAqAio1KmgqmyrPKwIrNitpK50r0SwFLDksbiyiLNctDC1BLXYtqy3hLhYuTC6C +Lrcu7i8kL1ovkS/HL/4wNTBsMKQw2zESMUoxgjG6MfIyKjJjMpsy1DMNM0YzfzO4M/E0KzRlNJ402DUT +NU01hzXCNf02NzZyNq426TckN2A3nDfXOBQ4UDiMOMg5BTlCOX85vDn5OjY6dDqyOu87LTtrO6o76Dwn +PGU8pDzjPSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/iQCNAZECmQOdBKUFqQaxB7kIwQnJCtUL3QzpDfUPA +RANER0SKRM5FEkVVRZpF3kYiRmdGq0bwRzVHe0fASAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkvi +TCpMcky6TQJNSk2TTdxOJU5uTrdPAE9JT5NP3VAnUHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZUQlSP +VNtVKFV1VcJWD1ZcVqlW91dEV5JX4FgvWH1Yy1kaWWlZuFoHWlZaplr1W0VblVvlXDVchlzWXSddeF3J +XhpebF69Xw9fYV+zYAVgV2CqYPxhT2GiYfViSWKcYvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeT +Z+loP2iWaOxpQ2maafFqSGqfavdrT2una/9sV2yvbQhtYG25bhJua27Ebx5veG/RcCtwhnDgcTpxlXHw +cktypnMBc11zuHQUdHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5KnmJeed6RnqlewR7Y3vCfCF8gXzh +fUF9oX4BfmJ+wn8jf4R/5YBHgKiBCoFrgc2CMIKSgvSDV4O6hB2EgITjhUeFq4YOhnKG14c7h5+IBIhp +iM6JM4mZif6KZIrKizCLlov8jGOMyo0xjZiN/45mjs6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSK +lPSVX5XJljSWn5cKl3WX4JhMmLiZJJmQmfyaaJrVm0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFH +obaiJqKWowajdqPmpFakx6U4pammGqaLpv2nbqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1ErbiuLa6h +rxavi7AAsHWw6rFgsdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZuNG5SrnCuju6tbsuu6e8Ibyb +vRW9j74KvoS+/796v/XAcMDswWfB48JfwtvDWMPUxFHEzsVLxcjGRsbDx0HHv8g9yLzJOsm5yjjKt8s2 +y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 +2vvbgNwF3IrdEN2W3hzeot8p36/gNuC94UThzOJT4tvjY+Pr5HPk/OWE5g3mlucf56noMui86Ubp0Opb +6uXrcOv77IbtEe2c7ijutO9A78zwWPDl8XLx//KM8xnzp/Q09ML1UPXe9m32+/eK+Bn4qPk4+cf6V/rn ++3f8B/yY/Sn9uv5L/tz/bf//A + + + + + + + + 400 + 75 + + + + + + + + {{1, 1}, {144, 56}} + + _NS:21 + + + {{164, 34}, {146, 72}} + + _NS:18 + {0, 0} + + 67108864 + 0 + Display Order + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + + 1 + 0 + 2 + NO + + + {474, 160} + NSView + + + + {474, 160} + {0, 160} + {474, 160} + 1 + 0.0 + 0.0 + + + + + MacScreenshotCaptureToolDelegate + + + 31 + 2 + {{57, 304}, {480, 245}} + -461896704 + Video Capture Tool + NSPanel + + + {1.7976931348623157e+308, 1.7976931348623157e+308} + {480, 245} + + + 256 + + YES + + + 306 + {{8, 9}, {267, 188}} + + _NS:2337 + YES + + 67108864 + 134217728 + Start Recording + + _NS:2337 + + -2038153216 + 130 + + + 400 + 75 + + NO + + + + 290 + {{10, 204}, {377, 18}} + + _NS:817 + YES + + -2069888959 + 272766528 + + + Video Directory Path + _NS:817 + + + + + NO + 1 + + + + 265 + {{390, 198}, {85, 28}} + + _NS:610 + YES + + 67108864 + 134348800 + Choose... + + _NS:610 + + -2038284288 + 129 + + + 200 + 25 + + NO + + + + 268 + {{11, 222}, {160, 14}} + + _NS:4068 + YES + + 68157504 + 272761856 + Video File Save Location + + _NS:4068 + + + + + NO + 1 + + + + 33 + + YES + + + 274 + + YES + + + 289 + {{155, 10}, {27, 27}} + + YES + + 67108864 + 134217728 + + + + -2030288896 + 130 + + + + 400 + 75 + + NO + + + + 289 + {{10, 17}, {142, 14}} + + _NS:4068 + YES + + 68157504 + 71435264 + Configure Display Layout: + + _NS:4068 + + + + + NO + 1 + + + + 289 + {{15, 148}, {76, 14}} + + _NS:4068 + YES + + 68157504 + 4326400 + File Format + + _NS:4068 + + + + + NO + 1 + + + + 289 + {{10, 126}, {173, 22}} + + _NS:791 + YES + + -2076180416 + 133120 + + _NS:791 + + 109199360 + 129 + + + 400 + 75 + + + AVI + + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + + 1 + YES + YES + 2 + + NO + + + + 289 + {{10, 75}, {173, 22}} + + _NS:791 + YES + + -2076180416 + 133120 + + _NS:791 + + 109199360 + 129 + + + 400 + 75 + + + Size of emulated frame + + 2147483647 + 1 + + + _popUpItemAction: + + + YES + + OtherViews + + YES + + + + YES + YES + + + 2147483647 + 1 + + + _popUpItemAction: + + + + + 480p NTSC (3:2, 720x480) + + 2147483647 + + + _popUpItemAction: + + + + + 480p PAL (5:4, 720x576) + + 2147483647 + + + _popUpItemAction: + + + + + 720p (16:9, 1280x720) + + 2147483647 + + + _popUpItemAction: + + + + + 1080p (16:9, 1920x1080) + + 2147483647 + + + _popUpItemAction: + + + + + VGA (4:3, 640x480) + + 2147483647 + + + _popUpItemAction: + + + + + SVGA (4:3, 800x600) + + 2147483647 + + + _popUpItemAction: + + + + + XGA (4:3, 1024x768) + + 2147483647 + + + _popUpItemAction: + + + + + SXGA (4:3, 1280x960) + + 2147483647 + + + _popUpItemAction: + + + + + UXGA (4:3, 1600x1200) + + 2147483647 + + + _popUpItemAction: + + + + + YES + YES + + + 2147483647 + 1 + + + _popUpItemAction: + + + + + Custom + + 2147483647 + + + _popUpItemAction: + + + + + + 1 + YES + YES + 2 + + NO + + + + 289 + {{18, 97}, {68, 14}} + + _NS:4068 + YES + + 68157504 + 4326400 + Video Size + + _NS:4068 + + + + + NO + 1 + + + + 289 + {{19, 54}, {20, 14}} + + _NS:4068 + YES + + 68157504 + 71435264 + W: + + _NS:4068 + + + + + NO + 1 + + + + 289 + + YES + + {{40, 52}, {54, 19}} + + _NS:185 + YES + + -1804599231 + 71435264 + + + + + YES + + YES + allowsFloats + formatterBehavior + locale + maximumFractionDigits + negativeInfinitySymbol + nilSymbol + numberStyle + positiveInfinitySymbol + usesGroupingSeparator + + + YES + + + + + -∞ + + + +∞ + + + + #0 + #0 + + + + + + + + NaN + + + + + + 3 + YES + YES + YES + + . + , + NO + NO + NO + + _NS:185 + + YES + + + + NO + 1 + + + + 289 + {{105, 54}, {20, 14}} + + _NS:4068 + YES + + 68157504 + 71435264 + H: + + _NS:4068 + + + + + NO + 1 + + + + 289 + + YES + + {{126, 52}, {54, 19}} + + _NS:185 + YES + + -1804599231 + 71435264 + + + + + YES + + YES + allowsFloats + formatterBehavior + locale + maximumFractionDigits + negativeInfinitySymbol + nilSymbol + numberStyle + positiveInfinitySymbol + usesGroupingSeparator + + + YES + + + + + -∞ + + + +∞ + + + + #0 + #0 + + + + + + + + NaN + + + + + + 3 + YES + YES + YES + + . + , + NO + NO + NO + + _NS:185 + + YES + + + + NO + 1 + + + + 12 + {{9, 115}, {175, 5}} + + _NS:2429 + {0, 0} + + 67108864 + 0 + Box + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + 3 + 2 + 0 + NO + + + + 12 + {{9, 41}, {175, 5}} + + _NS:2429 + {0, 0} + + 67108864 + 0 + Box + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + 3 + 2 + 0 + NO + + + {{1, 1}, {193, 172}} + + _NS:21 + + + {{278, 9}, {195, 188}} + + _NS:18 + {0, 0} + + 67108864 + 0 + Video Settings + + + + 3 + MCAwLjgwMDAwMDAxMTkAA + + + + 1 + 0 + 2 + NO + + + {480, 245} + _NS:103 + + {{0, 0}, {1440, 878}} + {480, 261} + {1.7976931348623157e+308, 1.7976931348623157e+308} + VideoCaptureToolPanel + NO + 279 2 @@ -29540,7 +31773,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 134217728 33554432 - + 0 3 0 @@ -30046,7 +32279,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 134217728 33554432 - + 0 3 0 @@ -30998,7 +33231,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 currentRom mainWindow mainWindow.displayRotation - mainWindow.screenshotFileFormat selectedExportRomSaveID mainWindow.displayGap mainWindow.view.videoSourceDeposterize @@ -31470,14 +33702,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 2025 - - - prefGeneralView - - - - 2093 - prefWindow @@ -32590,22 +34814,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 5145 - - - cheatListWindow - - - - 5146 - - - - cheatWindowController - - - - 5147 - prefWindowController @@ -36200,22 +38408,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 6808 - - - cdsSoundController - - - - 6824 - - - - romInfoPanelController - - - - 6825 - content @@ -37232,14 +39424,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 7003 - - - inputManager - - - - 7004 - inputManager @@ -39554,14 +41738,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 8240 - - - saveScreenshotAs: - - - - 8241 - toggleFullScreenDisplay: @@ -39947,14 +42123,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 8508 - - - slot2Window - - - - 8509 - window @@ -40031,14 +42199,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 8531 - - - inputDeviceListController - - - - 8532 - testRumble: @@ -42829,14 +44989,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 9886 - - - romInfoPanel - - - - 9887 - disclosureButton @@ -44741,6 +46893,254 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 10539 + + + contentView + + + + 10628 + + + + parentWindow + + + + 10629 + + + + toggle: + + + + 10633 + + + + makeKeyAndOrderFront: + + + + 10715 + + + + toggle: + + + + 10957 + + + + takeScreenshot: + + + + 10962 + + + + chooseDirectoryPath: + + + + 10963 + + + + window + + + + 10964 + + + + value: saveDirectoryPath + + + + + + value: saveDirectoryPath + value + saveDirectoryPath + 2 + + + 10968 + + + + selectedTag: displayRotation + + + + + + selectedTag: displayRotation + selectedTag + displayRotation + 2 + + + 10975 + + + + selectedTag: displayMode + + + + + + selectedTag: displayMode + selectedTag + displayMode + 2 + + + 10976 + + + + selectedTag: displayLayout + + + + + + selectedTag: displayLayout + selectedTag + displayLayout + 2 + + + 10977 + + + + selectedTag: displayOrder + + + + + + selectedTag: displayOrder + selectedTag + displayOrder + 2 + + + 10978 + + + + selectedTag: outputFilterID + + + + + + selectedTag: outputFilterID + selectedTag + outputFilterID + 2 + + + 10979 + + + + selectedTag: pixelScalerID + + + + + + selectedTag: pixelScalerID + selectedTag + pixelScalerID + 2 + + + 10980 + + + + value: useDeposterize + + + + + + value: useDeposterize + value + useDeposterize + 2 + + + 10981 + + + + selectedTag: fileFormat + + + + + + selectedTag: fileFormat + selectedTag + fileFormat + 2 + + + 10982 + + + + selectedTag: displaySeparation + + + + + + selectedTag: displaySeparation + selectedTag + displaySeparation + 2 + + + 10984 + + + + romInfoPanel + + + + 10985 + + + + screenshotCaptureToolDelegate + + + + 10986 + + + + inputDeviceListController + + + + 10987 + @@ -46243,13 +48643,13 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 YES - + @@ -50134,11 +52534,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 - - 2553 - - - 5713 @@ -60798,6 +63193,1195 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 + + 10540 + + + YES + + + + Panel (Snapshot Capture Tool) + + + 10541 + + + YES + + + + + + + + + + 10592 + + + YES + + + + + + 10593 + + + + + 10617 + + + YES + + + + + + 10618 + + + + + 10619 + + + YES + + + + + + 10620 + + + + + 10624 + + + YES + + + + + + + + + + + + + + + + + + + Screenshot Capture Tool Layout Drawer Content View + + + 10625 + + + Screenshot Capture Tool Drawer + + + 10676 + + + YES + + + + + + 10690 + + + YES + + + + + + + + 10691 + + + + + 10692 + + + + + 10693 + + + + + 10714 + + + + + 10727 + + + YES + + + + + + 10728 + + + YES + + + + + + 10729 + + + YES + + + + + + + + + + 10730 + + + + + 10731 + + + + + 10732 + + + + + 10733 + + + + + 10734 + + + + + 10741 + + + YES + + + + + + 10742 + + + YES + + + + + + 10743 + + + YES + + + + + + + + + + + 10744 + + + + + 10745 + + + + + 10746 + + + + + 10747 + + + YES + + + + + + 10748 + + + YES + + + + + + 10749 + + + YES + + + + + + + + + + + + + + + + + + + + + + + + + + 10750 + + + + + 10751 + + + + + 10752 + + + + + 10753 + + + + + 10754 + + + + + 10755 + + + + + 10756 + + + + + 10757 + + + + + 10758 + + + + + 10759 + + + + + 10760 + + + + + 10761 + + + + + 10762 + + + + + 10763 + + + + + 10764 + + + + + 10765 + + + + + 10766 + + + + + 10767 + + + + + 10768 + + + + + 10769 + + + + + 10770 + + + + + 10771 + + + + + 10772 + + + + + 10773 + + + + + 10776 + + + YES + + + + + + 10774 + + + YES + + + + + + 10775 + + + + + 10777 + + + YES + + + + + + 10778 + + + + + 10779 + + + YES + + + + + + 10780 + + + + + 10781 + + + YES + + + + + + 10782 + + + + + 10783 + + + + + 10784 + + + + + 10785 + + + YES + + + + + + 10786 + + + + + 10866 + + + YES + + + + + + + + + + 10630 + + + YES + + + + + + 10631 + + + + + 10712 + + + YES + + + + + + 10713 + + + + + 10725 + + + YES + + + + + + 10726 + + + + + 10716 + + + YES + + + + + + 10717 + + + YES + + + + + + 10718 + + + YES + + + + + + + + + + + 10724 + + + + + 10723 + + + + + 10722 + + + + + 10721 + + + + + 10720 + + + + + 10719 + + + + + 10873 + + + YES + + + + + + 10874 + + + YES + + + + + + 10875 + + + + + 10876 + + + YES + + + + + + 10877 + + + YES + + + + + + + + 10881 + + + + + 10882 + + + + + 10883 + + + + + 10884 + + + YES + + + + + + 10885 + + + YES + + + + + + 10886 + + + + + 10887 + + + YES + + + + + + 10888 + + + YES + + + + + + + + + 10889 + + + + + 10890 + + + + + 10891 + + + + + 10892 + + + + + 10893 + + + YES + + + + + + 10894 + + + YES + + + + + + 10895 + + + + + 10896 + + + YES + + + + + + 10897 + + + YES + + + + + + + + + + 10898 + + + + + 10899 + + + + + 10900 + + + + + 10901 + + + + + 10902 + + + + + 10903 + + + YES + + + + Panel (Video Capture Tool) + + + 10904 + + + YES + + + + + + + + + + 10911 + + + YES + + + + + + + + + + + + + + + + + 10912 + + + YES + + + + + + 10913 + + + YES + + + + + + 10914 + + + YES + + + + + + 10915 + + + YES + + + + + + 10916 + + + + + 10917 + + + + + 10918 + + + + + 10919 + + + + + 10920 + + + YES + + + + + + 10921 + + + YES + + + + + + 10922 + + + YES + + + + + + 10923 + + + YES + + + + + + 10924 + + + YES + + + + + + 10925 + + + YES + + + + + + 10926 + + + + + 10932 + + + + + 10933 + + + + + 10934 + + + + + 10905 + + + YES + + + + + + 10942 + + + YES + + + + + + 10943 + + + YES + + + + + + + + + + + + + + + + + + 10956 + + + + + 10955 + + + + + 10954 + + + + + 10953 + + + + + 10952 + + + + + 10951 + + + + + 10950 + + + + + 10949 + + + + + 10948 + + + + + 10947 + + + + + 10946 + + + + + 10945 + + + + + 10944 + + + + + 10910 + + + YES + + + + + + 10935 + + + + + 10909 + + + YES + + + + + + 10936 + + + + + 10908 + + + YES + + + + + + 10937 + + + YES + + + + + + 10938 + + + + + 10907 + + + YES + + + + + + 10939 + + + + + 10906 + + + YES + + + + + + 10940 + + + YES + + + + + + 10941 + + + + + 10958 + + + + + 10959 + + + + + 10960 + + + + + 10961 + + + @@ -61191,6 +64775,245 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 10529.IBPluginDependency 10530.IBPluginDependency 10531.IBPluginDependency + 10540.IBEditorWindowLastContentRect + 10540.IBPluginDependency + 10540.IBWindowTemplateEditedContentRect + 10540.NSWindowTemplate.visibleAtLaunch + 10540.windowTemplate.hasMaxSize + 10540.windowTemplate.hasMinSize + 10540.windowTemplate.maxSize + 10540.windowTemplate.minSize + 10541.IBPluginDependency + 10592.IBPluginDependency + 10592.IBViewBoundsToFrameTransform + 10593.IBPluginDependency + 10617.IBPluginDependency + 10617.IBViewBoundsToFrameTransform + 10618.IBPluginDependency + 10619.IBPluginDependency + 10619.IBViewBoundsToFrameTransform + 10620.IBPluginDependency + 10624.IBEditorWindowLastContentRect + 10624.IBPluginDependency + 10624.IBViewBoundsToFrameTransform + 10625.IBPluginDependency + 10630.IBPluginDependency + 10630.IBViewBoundsToFrameTransform + 10631.IBPluginDependency + 10676.IBPluginDependency + 10676.IBViewBoundsToFrameTransform + 10690.IBPluginDependency + 10690.IBViewBoundsToFrameTransform + 10691.IBPluginDependency + 10692.IBPluginDependency + 10693.IBPluginDependency + 10712.IBPluginDependency + 10712.IBViewBoundsToFrameTransform + 10713.IBPluginDependency + 10714.IBPluginDependency + 10716.IBPluginDependency + 10716.IBViewBoundsToFrameTransform + 10717.IBPluginDependency + 10718.IBEditorWindowLastContentRect + 10718.IBPluginDependency + 10719.IBPluginDependency + 10720.IBPluginDependency + 10721.IBPluginDependency + 10722.IBPluginDependency + 10723.IBPluginDependency + 10724.IBPluginDependency + 10725.IBPluginDependency + 10725.IBViewBoundsToFrameTransform + 10726.IBPluginDependency + 10727.IBPluginDependency + 10727.IBViewBoundsToFrameTransform + 10728.IBPluginDependency + 10729.IBEditorWindowLastContentRect + 10729.IBPluginDependency + 10730.IBPluginDependency + 10731.IBPluginDependency + 10732.IBPluginDependency + 10733.IBPluginDependency + 10734.IBPluginDependency + 10741.IBPluginDependency + 10741.IBViewBoundsToFrameTransform + 10742.IBPluginDependency + 10743.IBEditorWindowLastContentRect + 10743.IBPluginDependency + 10744.IBPluginDependency + 10745.IBPluginDependency + 10746.IBPluginDependency + 10747.IBPluginDependency + 10747.IBViewBoundsToFrameTransform + 10748.IBPluginDependency + 10749.IBEditorWindowLastContentRect + 10749.IBPluginDependency + 10750.IBPluginDependency + 10751.IBPluginDependency + 10752.IBPluginDependency + 10753.IBPluginDependency + 10754.IBPluginDependency + 10755.IBPluginDependency + 10756.IBPluginDependency + 10757.IBPluginDependency + 10758.IBPluginDependency + 10759.IBPluginDependency + 10760.IBPluginDependency + 10761.IBPluginDependency + 10762.IBPluginDependency + 10763.IBPluginDependency + 10764.IBPluginDependency + 10765.IBPluginDependency + 10766.IBPluginDependency + 10767.IBPluginDependency + 10768.IBPluginDependency + 10769.IBPluginDependency + 10770.IBPluginDependency + 10771.IBPluginDependency + 10772.IBPluginDependency + 10773.IBPluginDependency + 10774.IBPluginDependency + 10774.IBViewBoundsToFrameTransform + 10775.IBPluginDependency + 10776.IBPluginDependency + 10776.IBViewBoundsToFrameTransform + 10777.IBPluginDependency + 10777.IBViewBoundsToFrameTransform + 10778.IBPluginDependency + 10779.IBPluginDependency + 10779.IBViewBoundsToFrameTransform + 10780.IBPluginDependency + 10781.IBPluginDependency + 10781.IBViewBoundsToFrameTransform + 10782.IBPluginDependency + 10783.IBPluginDependency + 10783.IBViewBoundsToFrameTransform + 10784.IBPluginDependency + 10784.IBViewBoundsToFrameTransform + 10785.IBPluginDependency + 10785.IBViewBoundsToFrameTransform + 10786.IBPluginDependency + 10866.IBPluginDependency + 10866.IBViewBoundsToFrameTransform + 10873.IBPluginDependency + 10873.IBViewBoundsToFrameTransform + 10874.IBPluginDependency + 10874.IBViewBoundsToFrameTransform + 10875.IBPluginDependency + 10876.IBPluginDependency + 10877.IBEditorWindowLastContentRect + 10877.IBPluginDependency + 10881.IBPluginDependency + 10882.IBPluginDependency + 10883.IBPluginDependency + 10884.IBPluginDependency + 10884.IBViewBoundsToFrameTransform + 10885.IBPluginDependency + 10885.IBViewBoundsToFrameTransform + 10886.IBPluginDependency + 10887.IBPluginDependency + 10888.IBEditorWindowLastContentRect + 10888.IBPluginDependency + 10889.IBPluginDependency + 10890.IBPluginDependency + 10891.IBPluginDependency + 10892.IBPluginDependency + 10893.IBPluginDependency + 10893.IBViewBoundsToFrameTransform + 10894.IBPluginDependency + 10894.IBViewBoundsToFrameTransform + 10895.IBPluginDependency + 10896.IBPluginDependency + 10897.IBEditorWindowLastContentRect + 10897.IBPluginDependency + 10898.IBPluginDependency + 10899.IBPluginDependency + 10900.IBPluginDependency + 10901.IBPluginDependency + 10902.IBPluginDependency + 10903.IBEditorWindowLastContentRect + 10903.IBPluginDependency + 10903.IBWindowTemplateEditedContentRect + 10903.NSWindowTemplate.visibleAtLaunch + 10903.windowTemplate.hasMaxSize + 10903.windowTemplate.hasMinSize + 10903.windowTemplate.maxSize + 10903.windowTemplate.minSize + 10904.IBPluginDependency + 10905.IBPluginDependency + 10905.IBViewBoundsToFrameTransform + 10906.IBPluginDependency + 10906.IBViewBoundsToFrameTransform + 10907.IBPluginDependency + 10907.IBViewBoundsToFrameTransform + 10908.IBPluginDependency + 10908.IBViewBoundsToFrameTransform + 10909.IBPluginDependency + 10909.IBViewBoundsToFrameTransform + 10910.IBPluginDependency + 10910.IBViewBoundsToFrameTransform + 10911.IBPluginDependency + 10911.IBViewBoundsToFrameTransform + 10912.IBPluginDependency + 10912.IBViewBoundsToFrameTransform + 10913.IBPluginDependency + 10913.IBViewBoundsToFrameTransform + 10914.IBPluginDependency + 10914.IBViewBoundsToFrameTransform + 10915.IBPluginDependency + 10915.IBViewBoundsToFrameTransform + 10916.IBPluginDependency + 10917.IBPluginDependency + 10918.IBPluginDependency + 10919.IBPluginDependency + 10920.IBPluginDependency + 10920.IBViewBoundsToFrameTransform + 10921.IBPluginDependency + 10921.IBViewBoundsToFrameTransform + 10922.IBPluginDependency + 10922.IBViewBoundsToFrameTransform + 10923.IBPluginDependency + 10923.IBViewBoundsToFrameTransform + 10924.IBPluginDependency + 10925.IBEditorWindowLastContentRect + 10925.IBPluginDependency + 10926.IBPluginDependency + 10932.IBPluginDependency + 10933.IBPluginDependency + 10934.IBPluginDependency + 10935.IBPluginDependency + 10936.IBPluginDependency + 10937.IBPluginDependency + 10938.IBNumberFormatterBehaviorMetadataKey + 10938.IBNumberFormatterLocalizesFormatMetadataKey + 10938.IBPluginDependency + 10939.IBPluginDependency + 10940.IBPluginDependency + 10941.IBNumberFormatterBehaviorMetadataKey + 10941.IBNumberFormatterLocalizesFormatMetadataKey + 10941.IBPluginDependency + 10942.IBPluginDependency + 10943.IBEditorWindowLastContentRect + 10943.IBPluginDependency + 10944.IBPluginDependency + 10945.IBPluginDependency + 10946.IBPluginDependency + 10947.IBPluginDependency + 10948.IBPluginDependency + 10949.IBPluginDependency + 10950.IBPluginDependency + 10951.IBPluginDependency + 10952.IBPluginDependency + 10953.IBPluginDependency + 10954.IBPluginDependency + 10955.IBPluginDependency + 10956.IBPluginDependency + 10958.IBPluginDependency + 10958.IBViewBoundsToFrameTransform + 10959.IBPluginDependency + 10960.IBPluginDependency + 10960.IBViewBoundsToFrameTransform + 10961.IBPluginDependency 1113.IBPluginDependency 1114.IBPluginDependency 1115.IBPluginDependency @@ -61457,7 +65280,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 2483.IBPluginDependency 2518.IBPluginDependency 2519.IBPluginDependency - 2553.IBPluginDependency 2556.IBPluginDependency 2565.IBAttributePlaceholdersKey 2565.IBPluginDependency @@ -61534,6 +65356,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 3480.IBViewBoundsToFrameTransform 3481.IBPluginDependency 3482.IBPluginDependency + 3488.IBEditorWindowLastContentRect 3488.IBPluginDependency 3488.IBWindowTemplateEditedContentRect 3488.NSWindowTemplate.visibleAtLaunch @@ -61786,6 +65609,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 4053.IBPluginDependency 4054.IBPluginDependency 4059.IBPluginDependency + 4059.IBViewBoundsToFrameTransform 4060.IBPluginDependency 4062.IBPluginDependency 4066.IBPluginDependency @@ -62641,14 +66465,19 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 7802.IBPluginDependency 7803.IBPluginDependency 7804.IBPluginDependency + 7804.IBViewBoundsToFrameTransform 7805.IBPluginDependency 7806.IBPluginDependency + 7806.IBViewBoundsToFrameTransform 7807.IBPluginDependency 7808.IBPluginDependency + 7808.IBViewBoundsToFrameTransform 7809.IBPluginDependency 7810.IBPluginDependency + 7810.IBViewBoundsToFrameTransform 7811.IBPluginDependency 7812.IBPluginDependency + 7812.IBViewBoundsToFrameTransform 7813.IBPluginDependency 7817.IBEditorWindowLastContentRect 7817.IBPluginDependency @@ -63899,7 +67728,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{863, 603}, {289, 173}} + {{813, 603}, {289, 173}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -64010,7 +67839,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 P4AAAL+AAABDewAAww8AAA com.apple.InterfaceBuilder.CocoaPlugin - {{731, 278}, {175, 103}} + {{201, 470}, {175, 103}} com.apple.InterfaceBuilder.CocoaPlugin ToolTip @@ -64208,6 +68037,102 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + {{670, 692}, {480, 170}} + com.apple.InterfaceBuilder.CocoaPlugin + {{670, 692}, {480, 170}} + + + + {480, 170} + {480, 170} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBkAAAw8gAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBoAAAw9SAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABD8AAAw9aAAA + + com.apple.InterfaceBuilder.CocoaPlugin + {{674, 506}, {474, 160}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABEBcAAw7uAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + AULyAABCsAAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDFgAAw18AAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABD0wAAw7iAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCngAAwzUAAA + + com.apple.InterfaceBuilder.CocoaPlugin + {{948, 670}, {173, 105}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDwPcAw8YAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDr4AAw6wAAA + + com.apple.InterfaceBuilder.CocoaPlugin + {{827, 550}, {146, 88}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDuIAAwvwAAA + + com.apple.InterfaceBuilder.CocoaPlugin + {{984, 475}, {200, 105}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDMwAAw38AAA + + com.apple.InterfaceBuilder.CocoaPlugin + {{984, 179}, {146, 360}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -64219,7 +68144,238 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{329, 320}, {520, 422}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBcAAAwqoAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + AUOvgABCwAAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDOwAAw7MAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDvIAAwwwAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDOwAAw4aAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + AUMcAABBIAAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + AUOcgABBIAAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBqAAAw9wAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + AUEwAABDAgAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABA4AAAwzgAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBcAAAw0YAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{670, 584}, {146, 54}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABA4AAAwxAAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBcAAAwx4AAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{670, 527}, {146, 71}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBQAAAwwcAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBoAAAwxUAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{670, 470}, {146, 88}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{363, 369}, {480, 245}} + com.apple.InterfaceBuilder.CocoaPlugin + {{363, 369}, {480, 245}} + + + + {10000, 245} + {480, 245} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDRwAAwvAAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDiAAAwrwAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDdwAAwrYAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDMQAAwrwAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDGAAAwrYAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDBgAAwuoAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + AUEwAABDAgAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBkAAAw8gAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBqAAAw9wAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABD8AAAw9aAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABBoAAAw9SAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABEBcAAw7uAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABD0wAAw7iAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDwPcAw8YAAA + + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABD54AAw8eAAA + + com.apple.InterfaceBuilder.CocoaPlugin + {{693, 533}, {104, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{547, 278}, {193, 210}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + AUEQAABC5gAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + AUGoAABDJQAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{323, 434}, {520, 422}} {215, 355} com.apple.InterfaceBuilder.CocoaPlugin @@ -64294,7 +68450,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{337, 114}, {489, 420}} + {{1, 436}, {489, 420}} {796.5, 896.5} com.apple.InterfaceBuilder.CocoaPlugin @@ -64414,7 +68570,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{708, 526}, {132, 63}} + {{178, 718}, {132, 63}} com.apple.InterfaceBuilder.CocoaPlugin ToolTip @@ -64587,7 +68743,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{791, 763}, {194, 73}} + {{505, 763}, {194, 73}} com.apple.InterfaceBuilder.CocoaPlugin ToolTip @@ -64664,7 +68820,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin ToolTip @@ -64699,14 +68854,14 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{463, 836}, {512, 20}} + {{125, 836}, {512, 20}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{603, 363}, {315, 473}} + {{399, 363}, {315, 473}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -64718,7 +68873,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{555, 683}, {151, 153}} + {{269, 683}, {151, 153}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -64749,8 +68904,9 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + {{84, 262}, {640, 480}} com.apple.InterfaceBuilder.CocoaPlugin - {{657, 415}, {640, 480}} + {{84, 262}, {640, 480}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -65334,10 +69490,13 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{807, 419}, {260, 328}} + {{562, 419}, {255, 328}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDMAAAwp4AAA + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -65654,7 +69813,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{862, 723}, {261, 113}} + {{576, 723}, {261, 113}} com.apple.InterfaceBuilder.CocoaPlugin YES @@ -65825,7 +69984,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{568, 423}, {257, 413}} + {{313, 423}, {257, 413}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -65840,7 +69999,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{787, 703}, {292, 133}} + {{449, 703}, {292, 133}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -65890,7 +70049,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{863, 693}, {182, 43}} + {{813, 693}, {182, 43}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -66113,7 +70272,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{21, 377}, {328, 434}} + {{517, 300}, {328, 434}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -66439,7 +70598,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{918, 583}, {118, 133}} + {{714, 583}, {118, 133}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -66475,14 +70634,29 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDmIAAwjQAAA + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDg4AAwjQAAA + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDXAAAwjQAAA + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDMgAAwjQAAA + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABDCQAAwjQAAA + com.apple.InterfaceBuilder.CocoaPlugin {{873, 618}, {248, 148}} com.apple.InterfaceBuilder.CocoaPlugin @@ -66691,11 +70865,11 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{513, 373}, {325, 463}} + {{227, 373}, {325, 463}} com.apple.InterfaceBuilder.CocoaPlugin - {{329, 454}, {173, 339}} + {{655, 347}, {173, 339}} com.apple.InterfaceBuilder.CocoaPlugin - {{329, 454}, {173, 339}} + {{655, 347}, {173, 339}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -66744,7 +70918,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{918, 203}, {132, 423}} + {{714, 203}, {132, 423}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -66951,9 +71125,9 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 YES - {{819, 88}, {330, 768}} + {{819, 75}, {330, 781}} com.apple.InterfaceBuilder.CocoaPlugin - {{819, 88}, {330, 768}} + {{819, 75}, {330, 781}} @@ -67034,9 +71208,9 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{898, 620}, {254, 242}} + {{568, 620}, {254, 242}} com.apple.InterfaceBuilder.CocoaPlugin - {{898, 620}, {254, 242}} + {{568, 620}, {254, 242}} com.apple.InterfaceBuilder.CocoaPlugin @@ -67269,11 +71443,11 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{918, 643}, {134, 23}} + {{714, 643}, {134, 23}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{918, 523}, {235, 123}} + {{612, 523}, {235, 123}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -67622,7 +71796,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 - 10539 + 10987 @@ -67682,22 +71856,13 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 YES aboutWindowController cdsCoreController - cdsSoundController - cheatListWindow - cheatWindowController emuControlController - inputDeviceListController - inputManager inputPrefsView mLoadStateSlot mSaveStateSlot migrationDelegate - prefGeneralView prefWindow prefWindowController - romInfoPanel - romInfoPanelController - slot2Window troubleshootingWindow @@ -67705,21 +71870,12 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSObjectController NSObjectController NSObjectController - NSWindow - NSObjectController - NSObjectController - NSArrayController - InputManager InputPrefsView NSMenu NSMenu FileMigrationDelegate - NSView NSWindow NSObjectController - RomInfoPanel - NSObjectController - NSWindow NSWindow @@ -67729,22 +71885,13 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 YES aboutWindowController cdsCoreController - cdsSoundController - cheatListWindow - cheatWindowController emuControlController - inputDeviceListController - inputManager inputPrefsView mLoadStateSlot mSaveStateSlot migrationDelegate - prefGeneralView prefWindow prefWindowController - romInfoPanel - romInfoPanelController - slot2Window troubleshootingWindow @@ -67757,30 +71904,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 cdsCoreController NSObjectController - - cdsSoundController - NSObjectController - - - cheatListWindow - NSWindow - - - cheatWindowController - NSObjectController - emuControlController NSObjectController - - inputDeviceListController - NSArrayController - - - inputManager - InputManager - inputPrefsView InputPrefsView @@ -67797,10 +71924,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 migrationDelegate FileMigrationDelegate - - prefGeneralView - NSView - prefWindow NSWindow @@ -67809,18 +71932,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 prefWindowController NSObjectController - - romInfoPanel - RomInfoPanel - - - romInfoPanelController - NSObjectController - - - slot2Window - NSWindow - troubleshootingWindow NSWindow @@ -68110,7 +72221,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 DisplayPreviewView NSView - + IBProjectSource userinterface/preferencesWindowDelegate.h @@ -68140,7 +72251,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 frameAdvance: openRom: reset: - saveScreenshotAs: toggleExecutePause: toggleFullScreenDisplay: toggleHUDVisibility: @@ -68200,7 +72310,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 id id id - id @@ -68225,7 +72334,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 frameAdvance: openRom: reset: - saveScreenshotAs: toggleExecutePause: toggleFullScreenDisplay: toggleHUDVisibility: @@ -68320,10 +72428,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 reset: id - - saveScreenshotAs: - id - toggleExecutePause: id @@ -68412,7 +72516,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 microphoneMuteButton outputVolumeControlView outputVolumeMenuItem - saveScreenshotPanelAccessoryView YES @@ -68422,7 +72525,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSButton NSView NSMenuItem - NSView @@ -68435,7 +72537,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 microphoneMuteButton outputVolumeControlView outputVolumeMenuItem - saveScreenshotPanelAccessoryView YES @@ -68463,10 +72564,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 outputVolumeMenuItem NSMenuItem - - saveScreenshotPanelAccessoryView - NSView - @@ -68875,12 +72972,15 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 executionControlWindow exportRomSavePanelAccessoryView firmwarePanelController + inputDeviceListController inputManager ndsErrorSheet ndsErrorStatusTextField + romInfoPanel romInfoPanelController saveFileMigrationSheet saveStatePrecloseSheet + screenshotCaptureToolDelegate slot1ManagerWindow slot2WindowController @@ -68898,12 +72998,15 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSWindow NSView NSObjectController + NSArrayController InputManager NSWindow NSTextField + RomInfoPanel NSObjectController NSWindow NSWindow + MacScreenshotCaptureToolDelegate NSWindow NSObjectController @@ -68924,12 +73027,15 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 executionControlWindow exportRomSavePanelAccessoryView firmwarePanelController + inputDeviceListController inputManager ndsErrorSheet ndsErrorStatusTextField + romInfoPanel romInfoPanelController saveFileMigrationSheet saveStatePrecloseSheet + screenshotCaptureToolDelegate slot1ManagerWindow slot2WindowController @@ -68983,6 +73089,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 firmwarePanelController NSObjectController + + inputDeviceListController + NSArrayController + inputManager InputManager @@ -68995,6 +73105,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 ndsErrorStatusTextField NSTextField + + romInfoPanel + RomInfoPanel + romInfoPanelController NSObjectController @@ -69007,6 +73121,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 saveStatePrecloseSheet NSWindow + + screenshotCaptureToolDelegate + MacScreenshotCaptureToolDelegate + slot1ManagerWindow NSWindow @@ -69484,6 +73602,46 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 userinterface/InputProfileController.h + + MacScreenshotCaptureToolDelegate + NSObject + + YES + + YES + chooseDirectoryPath: + takeScreenshot: + + + YES + id + id + + + + YES + + YES + chooseDirectoryPath: + takeScreenshot: + + + YES + + chooseDirectoryPath: + id + + + takeScreenshot: + id + + + + + IBProjectSource + userinterface/MacScreenshotCaptureTool.h + + PreferencesWindowDelegate NSObject @@ -69803,12 +73961,12 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 - + RomInfoContentView NSView - + IBProjectSource userinterface/RomInfoPanel.h @@ -69880,7 +74038,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 - + RomInfoPanelSectionView @@ -69917,7 +74075,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 - + Slot2WindowDelegate @@ -70287,21 +74445,21 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSApplication NSResponder - + IBFrameworkSource AppKit.framework/Headers/NSApplication.h NSApplication - + IBFrameworkSource AppKit.framework/Headers/NSApplicationScripting.h NSApplication - + IBFrameworkSource AppKit.framework/Headers/NSColorPanel.h @@ -70386,7 +74544,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSControl NSView - + IBFrameworkSource AppKit.framework/Headers/NSControl.h @@ -70472,7 +74630,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSDrawer NSResponder - + IBFrameworkSource AppKit.framework/Headers/NSDrawer.h @@ -70528,7 +74686,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSMenu NSObject - + IBFrameworkSource AppKit.framework/Headers/NSMenu.h @@ -70536,7 +74694,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSMenuItem NSObject - + IBFrameworkSource AppKit.framework/Headers/NSMenuItem.h @@ -70574,19 +74732,19 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSObject - + NSObject - + NSObject - + NSObject - + NSObject @@ -70625,7 +74783,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSObject - + NSObject @@ -70636,7 +74794,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSObject - + IBFrameworkSource AppKit.framework/Headers/NSOutlineView.h @@ -70657,21 +74815,21 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSObject - + IBFrameworkSource AppKit.framework/Headers/NSTableView.h NSObject - + IBFrameworkSource AppKit.framework/Headers/NSToolbarItem.h NSObject - + IBFrameworkSource AppKit.framework/Headers/NSView.h @@ -70841,7 +74999,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSOutlineView NSTableView - + NSPanel @@ -71005,7 +75163,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSTableView NSControl - + NSText @@ -71050,7 +75208,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSToolbarItem NSObject - + NSUserDefaultsController @@ -71069,7 +75227,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSView - + NSView @@ -71081,11 +75239,11 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSView NSResponder - + NSWindow - + NSWindow @@ -71228,7 +75386,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {515, 457} {14, 14} {8, 8} - {512, 512} + {128, 128} {11, 11} {10, 3} {32, 32} diff --git a/desmume/src/frontend/cocoa/userinterface/DisplayViewCALayer.h b/desmume/src/frontend/cocoa/userinterface/DisplayViewCALayer.h index 274ad1352..913754ede 100644 --- a/desmume/src/frontend/cocoa/userinterface/DisplayViewCALayer.h +++ b/desmume/src/frontend/cocoa/userinterface/DisplayViewCALayer.h @@ -22,15 +22,17 @@ #import #import "InputManager.h" +#import "../ClientDisplayView.h" @class CocoaDSDisplayVideo; @class MacClientSharedObject; -class ClientDisplay3DView; +class MacDisplayLayeredView; @protocol DisplayViewCALayer @required -- (ClientDisplay3DView *) clientDisplay3DView; + +@property (assign, nonatomic, getter=clientDisplayView, setter=setClientDisplayView:) MacDisplayLayeredView *_cdv; @end @@ -39,7 +41,7 @@ class ClientDisplay3DView; @required @property (retain) InputManager *inputManager; @property (retain) CocoaDSDisplayVideo *cdsVideoOutput; -@property (readonly, nonatomic) ClientDisplay3DView *clientDisplay3DView; +@property (readonly, nonatomic) MacDisplayLayeredView *clientDisplayView; @property (readonly) BOOL canUseShaderBasedFilters; @property (assign, nonatomic) BOOL allowViewUpdates; @property (assign) BOOL isHUDVisible; @@ -68,34 +70,43 @@ class ClientDisplay3DView; @property (assign) NSInteger pixelScaler; - (void) setupLayer; -- (void) requestScreenshot:(NSURL *)fileURL fileType:(NSBitmapImageFileType)fileType; @end -class DisplayViewCALayerInterface +class MacDisplayPresenterInterface { -private: - NSView *_nsView; - CALayer *_frontendLayer; - bool _willRenderToCALayer; - +protected: MacClientSharedObject *_sharedData; public: - DisplayViewCALayerInterface(); + MacDisplayPresenterInterface(); + MacDisplayPresenterInterface(MacClientSharedObject *sharedObject); + + MacClientSharedObject* GetSharedData(); + virtual void SetSharedData(MacClientSharedObject *sharedObject); +}; + +class MacDisplayLayeredView : public ClientDisplay3DView +{ +private: + void __InstanceInit(); + +protected: + NSView *_nsView; + CALayer *_caLayer; + bool _willRenderToCALayer; + +public: + MacDisplayLayeredView(); + MacDisplayLayeredView(ClientDisplay3DPresenter *thePresenter); NSView* GetNSView() const; void SetNSView(NSView *theView); - CALayer* GetFrontendLayer() const; - void SetFrontendLayer(CALayer *layer); - void CALayerDisplay(); + CALayer* GetCALayer() const; bool GetRenderToCALayer() const; void SetRenderToCALayer(const bool renderToLayer); - - MacClientSharedObject* GetSharedData(); - void SetSharedData(MacClientSharedObject *sharedObject); }; #endif // _DISPLAYVIEWCALAYER_H diff --git a/desmume/src/frontend/cocoa/userinterface/DisplayViewCALayer.mm b/desmume/src/frontend/cocoa/userinterface/DisplayViewCALayer.mm index e62a350aa..d5c4e2afd 100644 --- a/desmume/src/frontend/cocoa/userinterface/DisplayViewCALayer.mm +++ b/desmume/src/frontend/cocoa/userinterface/DisplayViewCALayer.mm @@ -18,55 +18,66 @@ #import "DisplayViewCALayer.h" #import "../cocoa_GPU.h" -DisplayViewCALayerInterface::DisplayViewCALayerInterface() +MacDisplayPresenterInterface::MacDisplayPresenterInterface() { - _nsView = nil; - _frontendLayer = nil; _sharedData = nil; - _willRenderToCALayer = false; } -NSView* DisplayViewCALayerInterface::GetNSView() const +MacDisplayPresenterInterface::MacDisplayPresenterInterface(MacClientSharedObject *sharedObject) { - return this->_nsView; + _sharedData = sharedObject; } -void DisplayViewCALayerInterface::SetNSView(NSView *theView) -{ - this->_nsView = theView; -} - -CALayer* DisplayViewCALayerInterface::GetFrontendLayer() const -{ - return this->_frontendLayer; -} - -void DisplayViewCALayerInterface::SetFrontendLayer(CALayer *layer) -{ - this->_frontendLayer = layer; -} - -void DisplayViewCALayerInterface::CALayerDisplay() -{ - [this->_frontendLayer setNeedsDisplay]; -} - -bool DisplayViewCALayerInterface::GetRenderToCALayer() const -{ - return this->_willRenderToCALayer; -} - -void DisplayViewCALayerInterface::SetRenderToCALayer(const bool renderToLayer) -{ - this->_willRenderToCALayer = renderToLayer; -} - -MacClientSharedObject* DisplayViewCALayerInterface::GetSharedData() +MacClientSharedObject* MacDisplayPresenterInterface::GetSharedData() { return this->_sharedData; } -void DisplayViewCALayerInterface::SetSharedData(MacClientSharedObject *sharedObject) +void MacDisplayPresenterInterface::SetSharedData(MacClientSharedObject *sharedObject) { this->_sharedData = sharedObject; } + +#pragma mark - + +MacDisplayLayeredView::MacDisplayLayeredView() +{ + __InstanceInit(); +} + +MacDisplayLayeredView::MacDisplayLayeredView(ClientDisplay3DPresenter *thePresenter) : ClientDisplay3DView(thePresenter) +{ + __InstanceInit(); +} + +void MacDisplayLayeredView::__InstanceInit() +{ + _nsView = nil; + _caLayer = nil; + _willRenderToCALayer = false; +} + +NSView* MacDisplayLayeredView::GetNSView() const +{ + return this->_nsView; +} + +void MacDisplayLayeredView::SetNSView(NSView *theView) +{ + this->_nsView = theView; +} + +CALayer* MacDisplayLayeredView::GetCALayer() const +{ + return this->_caLayer; +} + +bool MacDisplayLayeredView::GetRenderToCALayer() const +{ + return this->_willRenderToCALayer; +} + +void MacDisplayLayeredView::SetRenderToCALayer(const bool renderToLayer) +{ + this->_willRenderToCALayer = renderToLayer; +} diff --git a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.h b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.h index 3b42e4d08..e229f9479 100644 --- a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.h +++ b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.h @@ -42,7 +42,7 @@ class OGLVideoOutput; { InputManager *inputManager; CocoaDSDisplayVideo *cdsVideoOutput; - CALayer *localLayer; + CALayer *localLayer; NSOpenGLContext *localOGLContext; } @@ -59,8 +59,7 @@ class OGLVideoOutput; { NSObject *dummyObject; - ClientDisplayViewProperties _localViewProps; - NSView *saveScreenshotPanelAccessoryView; + ClientDisplayPresenterProperties _localViewProps; NSView *outputVolumeControlView; NSView *microphoneGainControlView; NSMenuItem *outputVolumeMenuItem; @@ -73,8 +72,6 @@ class OGLVideoOutput; NSScreen *assignedScreen; NSWindow *masterWindow; - NSInteger screenshotFileFormat; - NSSize _minDisplayViewSize; BOOL _isMinSizeNormal; NSUInteger _statusBarHeight; @@ -89,7 +86,6 @@ class OGLVideoOutput; @property (readonly) IBOutlet NSObject *dummyObject; -@property (readonly) IBOutlet NSView *saveScreenshotPanelAccessoryView; @property (readonly) IBOutlet NSView *outputVolumeControlView; @property (readonly) IBOutlet NSView *microphoneGainControlView; @property (readonly) IBOutlet NSMenuItem *outputVolumeMenuItem; @@ -109,13 +105,12 @@ class OGLVideoOutput; @property (assign, nonatomic) double displayGap; @property (assign, nonatomic) double displayScale; @property (assign, nonatomic) double displayRotation; -@property (assign) NSInteger screenshotFileFormat; @property (assign) BOOL isMinSizeNormal; @property (assign) BOOL isShowingStatusBar; - (id)initWithWindowNibName:(NSString *)windowNibName emuControlDelegate:(EmuControllerDelegate *)theEmuController; -- (ClientDisplayViewProperties &) localViewProperties; +- (ClientDisplayPresenterProperties &) localViewProperties; - (void) setVideoPropertiesWithoutUpdateUsingPreferGPU:(BOOL)preferGPU sourceDeposterize:(BOOL)useDeposterize outputFilter:(NSInteger)outputFilterID @@ -150,7 +145,6 @@ class OGLVideoOutput; - (IBAction) reset:(id)sender; - (IBAction) changeCoreSpeed:(id)sender; - (IBAction) openRom:(id)sender; -- (IBAction) saveScreenshotAs:(id)sender; // View Menu - (IBAction) changeScale:(id)sender; diff --git a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm index 094972c27..cc124b33d 100644 --- a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm +++ b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm @@ -52,7 +52,6 @@ @synthesize assignedScreen; @synthesize masterWindow; @synthesize view; -@synthesize saveScreenshotPanelAccessoryView; @synthesize outputVolumeControlView; @synthesize microphoneGainControlView; @synthesize outputVolumeMenuItem; @@ -67,7 +66,6 @@ @dynamic displayOrientation; @dynamic displayOrder; @dynamic displayGap; -@synthesize screenshotFileFormat; @dynamic isMinSizeNormal; @dynamic isShowingStatusBar; @@ -92,7 +90,6 @@ static std::unordered_map _screenMap; // emuControl = [theEmuController retain]; assignedScreen = nil; masterWindow = nil; - screenshotFileFormat = NSTIFFFileType; // These need to be initialized first since there are dependencies on these. _localViewProps.normalWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH; @@ -118,11 +115,6 @@ static std::unordered_map _screenMap; // _masterWindowFrame = NSMakeRect(0.0, 0.0, _localViewProps.clientWidth, _localViewProps.clientHeight + _localViewProps.gapDistance); _masterStatusBarState = NO; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(saveScreenshotAsFinish:) - name:@"org.desmume.DeSmuME.requestScreenshotDidFinish" - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondToScreenChange:) name:@"NSApplicationDidChangeScreenParametersNotification" @@ -192,7 +184,7 @@ static std::unordered_map _screenMap; // if ([self isFullScreen]) { - [[[self view] cdsVideoOutput] commitViewProperties:_localViewProps]; + [[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps]; } else { @@ -207,7 +199,7 @@ static std::unordered_map _screenMap; // // display view to update itself. if (oldBounds.width == newBounds.width && oldBounds.height == newBounds.height) { - [[[self view] cdsVideoOutput] commitViewProperties:_localViewProps]; + [[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps]; } } } @@ -223,7 +215,7 @@ static std::unordered_map _screenMap; // ( ((_localViewProps.mode == ClientDisplayMode_Main) || (_localViewProps.mode == ClientDisplayMode_Touch)) && (displayModeID == ClientDisplayMode_Dual) ); _localViewProps.mode = (ClientDisplayMode)displayModeID; - ClientDisplayView::CalculateNormalSize((ClientDisplayMode)displayModeID, (ClientDisplayLayout)[self displayOrientation], [self displayGap], _localViewProps.normalWidth, _localViewProps.normalHeight); + ClientDisplayPresenter::CalculateNormalSize((ClientDisplayMode)displayModeID, (ClientDisplayLayout)[self displayOrientation], [self displayGap], _localViewProps.normalWidth, _localViewProps.normalHeight); [self setIsMinSizeNormal:[self isMinSizeNormal]]; if (![self isFullScreen] && willModeChangeSize) @@ -232,7 +224,7 @@ static std::unordered_map _screenMap; // } else { - [[[self view] cdsVideoOutput] commitViewProperties:_localViewProps]; + [[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps]; } } @@ -245,14 +237,14 @@ static std::unordered_map _screenMap; // { _localViewProps.layout = (ClientDisplayLayout)theOrientation; - ClientDisplayView::CalculateNormalSize((ClientDisplayMode)[self displayMode], (ClientDisplayLayout)theOrientation, [self displayGap], _localViewProps.normalWidth, _localViewProps.normalHeight); + ClientDisplayPresenter::CalculateNormalSize((ClientDisplayMode)[self displayMode], (ClientDisplayLayout)theOrientation, [self displayGap], _localViewProps.normalWidth, _localViewProps.normalHeight); [self setIsMinSizeNormal:[self isMinSizeNormal]]; if ([self displayMode] == ClientDisplayMode_Dual) { if ([self isFullScreen]) { - [[[self view] cdsVideoOutput] commitViewProperties:_localViewProps]; + [[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps]; } else { @@ -269,7 +261,7 @@ static std::unordered_map _screenMap; // - (void) setDisplayOrder:(NSInteger)theOrder { _localViewProps.order = (ClientDisplayOrder)theOrder; - [[[self view] cdsVideoOutput] commitViewProperties:_localViewProps]; + [[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps]; } - (NSInteger) displayOrder @@ -280,7 +272,7 @@ static std::unordered_map _screenMap; // - (void) setDisplayGap:(double)gapScalar { _localViewProps.gapScale = gapScalar; - ClientDisplayView::CalculateNormalSize((ClientDisplayMode)[self displayMode], (ClientDisplayLayout)[self displayOrientation], gapScalar, _localViewProps.normalWidth, _localViewProps.normalHeight); + ClientDisplayPresenter::CalculateNormalSize((ClientDisplayMode)[self displayMode], (ClientDisplayLayout)[self displayOrientation], gapScalar, _localViewProps.normalWidth, _localViewProps.normalHeight); [self setIsMinSizeNormal:[self isMinSizeNormal]]; if ([self displayMode] == ClientDisplayMode_Dual) @@ -296,7 +288,7 @@ static std::unordered_map _screenMap; // case ClientDisplayLayout_Hybrid_16_9: case ClientDisplayLayout_Hybrid_16_10: default: - [[[self view] cdsVideoOutput] commitViewProperties:_localViewProps]; + [[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps]; break; } } @@ -306,7 +298,7 @@ static std::unordered_map _screenMap; // { case ClientDisplayLayout_Hybrid_16_9: case ClientDisplayLayout_Hybrid_16_10: - [[[self view] cdsVideoOutput] commitViewProperties:_localViewProps]; + [[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps]; break; case ClientDisplayLayout_Horizontal: @@ -341,7 +333,7 @@ static std::unordered_map _screenMap; // // Set the minimum content size, keeping the display rotation in mind. double transformedMinWidth = _minDisplayViewSize.width; double transformedMinHeight = _minDisplayViewSize.height; - ClientDisplayView::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, transformedMinWidth, transformedMinHeight); + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, transformedMinWidth, transformedMinHeight); [[self window] setContentMinSize:NSMakeSize(transformedMinWidth, transformedMinHeight + _statusBarHeight)]; } @@ -393,7 +385,7 @@ static std::unordered_map _screenMap; // #pragma mark Class Methods -- (ClientDisplayViewProperties &) localViewProperties +- (ClientDisplayPresenterProperties &) localViewProperties { return _localViewProps; } @@ -429,7 +421,7 @@ static std::unordered_map _screenMap; // _localViewProps.gapDistance = DS_DISPLAY_UNSCALED_GAP * gapScale; _localViewProps.rotation = 360.0 - _localRotation; - ClientDisplayView::CalculateNormalSize(mode, layout, gapScale, _localViewProps.normalWidth, _localViewProps.normalHeight); + ClientDisplayPresenter::CalculateNormalSize(mode, layout, gapScale, _localViewProps.normalWidth, _localViewProps.normalHeight); // Set the minimum content size. _isMinSizeNormal = isMinSizeNormal; @@ -444,7 +436,7 @@ static std::unordered_map _screenMap; // double transformedMinWidth = _minDisplayViewSize.width; double transformedMinHeight = _minDisplayViewSize.height; - ClientDisplayView::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, transformedMinWidth, transformedMinHeight); + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, transformedMinWidth, transformedMinHeight); [[self window] setContentMinSize:NSMakeSize(transformedMinWidth, transformedMinHeight + _statusBarHeight)]; // Set the client size and resize the window. @@ -458,7 +450,7 @@ static std::unordered_map _screenMap; // // window size changed or not. if (oldBounds.width == newBounds.width && oldBounds.height == newBounds.height) { - [[[self view] cdsVideoOutput] commitViewProperties:_localViewProps]; + [[[self view] cdsVideoOutput] commitPresenterProperties:_localViewProps]; } } @@ -529,7 +521,7 @@ static std::unordered_map _screenMap; // // Get the maximum scalar size within drawBounds. double checkWidth = _localViewProps.normalWidth; double checkHeight = _localViewProps.normalHeight; - ClientDisplayView::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, checkWidth, checkHeight); + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, checkWidth, checkHeight); const double maxViewScaleInHostScreen = [self maxViewScaleInHostScreen:checkWidth height:checkHeight]; if (_localViewScale > maxViewScaleInHostScreen) @@ -540,7 +532,7 @@ static std::unordered_map _screenMap; // // Get the new bounds for the window's content view based on the transformed draw bounds. double transformedWidth = _localViewProps.normalWidth; double transformedHeight = _localViewProps.normalHeight; - ClientDisplayView::ConvertNormalToTransformedBounds(_localViewScale, _localViewProps.rotation, transformedWidth, transformedHeight); + ClientDisplayPresenter::ConvertNormalToTransformedBounds(_localViewScale, _localViewProps.rotation, transformedWidth, transformedHeight); // Get the center of the content view in screen coordinates. const NSRect windowContentRect = [[masterWindow contentView] bounds]; @@ -573,29 +565,7 @@ static std::unordered_map _screenMap; // const NSRect windowFrame = [[self window] frameRectForContentRect:NSMakeRect(0.0, 0.0, contentBoundsWidth, contentBoundsHeight + _statusBarHeight)]; const NSSize visibleScreenBounds = { (screenFrame.size.width - (windowFrame.size.width - contentBoundsWidth)), (screenFrame.size.height - (windowFrame.size.height - contentBoundsHeight)) }; - return ClientDisplayView::GetMaxScalarWithinBounds(contentBoundsWidth, contentBoundsHeight, visibleScreenBounds.width, visibleScreenBounds.height); -} - -- (void) saveScreenshotAsFinish:(NSNotification *)aNotification -{ - NSURL *fileURL = (NSURL *)[[aNotification userInfo] valueForKey:@"fileURL"]; - NSBitmapImageFileType fileType = (NSBitmapImageFileType)[(NSNumber *)[[aNotification userInfo] valueForKey:@"fileType"] integerValue]; - NSImage *screenshotImage = (NSImage *)[[aNotification userInfo] valueForKey:@"screenshotImage"]; - - const BOOL fileSaved = [CocoaDSFile saveScreenshot:fileURL bitmapData:(NSBitmapImageRep *)[[screenshotImage representations] objectAtIndex:0] fileType:fileType]; - if (!fileSaved) - { - NSAlert *theAlert = [[NSAlert alloc] init]; - [theAlert setMessageText:NSSTRING_ALERT_SCREENSHOT_FAILED_TITLE]; - [theAlert setInformativeText:NSSTRING_ALERT_SCREENSHOT_FAILED_MESSAGE]; - [theAlert setAlertStyle:NSCriticalAlertStyle]; - - [theAlert runModal]; - - [theAlert release]; - } - - [emuControl restoreCoreState]; + return ClientDisplayPresenter::GetMaxScalarWithinBounds(contentBoundsWidth, contentBoundsHeight, visibleScreenBounds.width, visibleScreenBounds.height); } - (void) enterFullScreen @@ -681,7 +651,7 @@ static std::unordered_map _screenMap; // CGDirectDisplayID displayID = [idNumber unsignedIntValue]; [[[self view] cdsVideoOutput] setCurrentDisplayID:displayID]; - [[[self view] cdsVideoOutput] clientDisplayView]->UpdateView(); + [[[self view] cdsVideoOutput] clientDisplay3DView]->SetViewNeedsFlush(); } - (void) respondToScreenChange:(NSNotification *)aNotification @@ -797,7 +767,7 @@ static std::unordered_map _screenMap; // // Set the minimum content size, keeping the display rotation in mind. double transformedMinWidth = _minDisplayViewSize.width; double transformedMinHeight = _minDisplayViewSize.height; - ClientDisplayView::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, transformedMinWidth, transformedMinHeight); + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, transformedMinWidth, transformedMinHeight); transformedMinHeight += _statusBarHeight; // Resize the window if it's smaller than the minimum content size. @@ -870,26 +840,6 @@ static std::unordered_map _screenMap; // [emuControl openRom:sender]; } -- (IBAction) saveScreenshotAs:(id)sender -{ - [emuControl pauseCore]; - - NSSavePanel *panel = [NSSavePanel savePanel]; - [panel setCanCreateDirectories:YES]; - [panel setTitle:NSSTRING_TITLE_SAVE_SCREENSHOT_PANEL]; - [panel setAccessoryView:saveScreenshotPanelAccessoryView]; - - const NSInteger buttonClicked = [panel runModal]; - if(buttonClicked == NSOKButton) - { - [view requestScreenshot:[panel URL] fileType:(NSBitmapImageFileType)[self screenshotFileFormat]]; - } - else - { - [emuControl restoreCoreState]; - } -} - - (IBAction) changeScale:(id)sender { [self setDisplayScale:(double)[CocoaDSUtil getIBActionSenderTag:sender] / 100.0]; @@ -1324,11 +1274,12 @@ static std::unordered_map _screenMap; // // Set up the video output thread. CocoaDSDisplayVideo *newDisplayOutput = [[[CocoaDSDisplayVideo alloc] init] autorelease]; - [newDisplayOutput setClientDisplayView:[newView clientDisplay3DView]]; + ClientDisplay3DView *cdv = [newView clientDisplayView]; + + [newDisplayOutput setClientDisplay3DView:cdv]; - ClientDisplayView *cdv = [newDisplayOutput clientDisplayView]; NSString *fontPath = [[NSBundle mainBundle] pathForResource:@"SourceSansPro-Bold" ofType:@"otf"]; - cdv->SetHUDFontPath([fontPath cStringUsingEncoding:NSUTF8StringEncoding]); + cdv->Get3DPresenter()->SetHUDFontPath([fontPath cStringUsingEncoding:NSUTF8StringEncoding]); if (scaleFactor != 1.0f) { @@ -1336,7 +1287,7 @@ static std::unordered_map _screenMap; // } else { - cdv->LoadHUDFont(); + cdv->Get3DPresenter()->LoadHUDFont(); } [newView setCdsVideoOutput:newDisplayOutput]; @@ -1390,9 +1341,9 @@ static std::unordered_map _screenMap; // // Find the maximum scalar we can use for the display view, bounded by the content Rect. double checkWidth = _localViewProps.normalWidth; double checkHeight = _localViewProps.normalHeight; - ClientDisplayView::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, checkWidth, checkHeight); + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, checkWidth, checkHeight); const NSSize contentBounds = NSMakeSize(contentRect.size.width, contentRect.size.height - _statusBarHeight); - _localViewScale = ClientDisplayView::GetMaxScalarWithinBounds(checkWidth, checkHeight, contentBounds.width, contentBounds.height); + _localViewScale = ClientDisplayPresenter::GetMaxScalarWithinBounds(checkWidth, checkHeight, contentBounds.width, contentBounds.height); // Make a new content Rect with our max scalar, and convert it back to a frame Rect. const NSRect finalContentRect = NSMakeRect(0.0f, 0.0f, checkWidth * _localViewScale, (checkHeight * _localViewScale) + _statusBarHeight); @@ -1445,9 +1396,9 @@ static std::unordered_map _screenMap; // // Find the maximum scalar we can use for the display view, bounded by the content Rect. double checkWidth = _localViewProps.normalWidth; double checkHeight = _localViewProps.normalHeight; - ClientDisplayView::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, checkWidth, checkHeight); + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, _localViewProps.rotation, checkWidth, checkHeight); const NSSize contentBounds = NSMakeSize(contentRect.size.width, contentRect.size.height - _statusBarHeight); - const double maxS = ClientDisplayView::GetMaxScalarWithinBounds(checkWidth, checkHeight, contentBounds.width, contentBounds.height); + const double maxS = ClientDisplayPresenter::GetMaxScalarWithinBounds(checkWidth, checkHeight, contentBounds.width, contentBounds.height); // Make a new content Rect with our max scalar, and convert it back to a frame Rect. const NSRect finalContentRect = NSMakeRect(0.0f, 0.0f, checkWidth * maxS, (checkHeight * maxS) + _statusBarHeight); @@ -1640,7 +1591,7 @@ static std::unordered_map _screenMap; // @synthesize inputManager; @synthesize cdsVideoOutput; -@dynamic clientDisplay3DView; +@dynamic clientDisplayView; @dynamic canUseShaderBasedFilters; @dynamic allowViewUpdates; @dynamic isHUDVisible; @@ -1725,8 +1676,8 @@ static std::unordered_map _screenMap; // { BOOL isHandled = NO; DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate]; - ClientDisplayView *cdv = [(id)localLayer clientDisplay3DView]; - const ClientDisplayMode displayMode = cdv->GetMode(); + MacDisplayLayeredView *cdv = [localLayer clientDisplayView]; + const ClientDisplayMode displayMode = cdv->Get3DPresenter()->GetMode(); // Convert the clicked location from window coordinates, to view coordinates, // and finally to DS touchscreen coordinates. @@ -1736,12 +1687,17 @@ static std::unordered_map _screenMap; // if (displayMode != ClientDisplayMode_Main) { + const ClientDisplayPresenterProperties &props = cdv->Get3DPresenter()->GetPresenterProperties(); + const double scaleFactor = cdv->Get3DPresenter()->GetScaleFactor(); const NSEventType eventType = [theEvent type]; const bool isInitialMouseDown = (eventType == NSLeftMouseDown) || (eventType == NSRightMouseDown) || (eventType == NSOtherMouseDown); // Convert the clicked location from window coordinates, to view coordinates, and finally to NDS touchscreen coordinates. const NSPoint clientLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - cdv->GetNDSPoint((int)buttonNumber, isInitialMouseDown, clientLoc.x, clientLoc.y, x, y); + + cdv->GetNDSPoint(props, + props.clientWidth * scaleFactor, props.clientHeight * scaleFactor, + (int)buttonNumber, isInitialMouseDown, clientLoc.x, clientLoc.y, x, y); } MacInputDevicePropertiesEncoder *inputEncoder = [inputManager inputEncoder]; @@ -1759,9 +1715,9 @@ static std::unordered_map _screenMap; // #pragma mark CocoaDisplayView Protocol -- (ClientDisplay3DView *) clientDisplay3DView +- (MacDisplayLayeredView *) clientDisplayView { - return [(id)localLayer clientDisplay3DView]; + return [localLayer clientDisplayView]; } - (BOOL) canUseShaderBasedFilters @@ -1771,12 +1727,12 @@ static std::unordered_map _screenMap; // - (BOOL) allowViewUpdates { - return ([self clientDisplay3DView]->GetAllowViewUpdates()) ? YES : NO; + return ([self clientDisplayView]->GetAllowViewUpdates()) ? YES : NO; } - (void) setAllowViewUpdates:(BOOL)allowUpdates { - [self clientDisplay3DView]->SetAllowViewUpdates((allowUpdates) ? true : false); + [self clientDisplayView]->SetAllowViewUpdates((allowUpdates) ? true : false); } - (void) setIsHUDVisible:(BOOL)theState @@ -2031,9 +1987,9 @@ static std::unordered_map _screenMap; // { [macSharedData decrementViewsUsingDirectToCPUFiltering]; } - - [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW]; } + + [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW]; } - (BOOL) sourceDeposterize @@ -2073,9 +2029,9 @@ static std::unordered_map _screenMap; // { [macSharedData decrementViewsUsingDirectToCPUFiltering]; } - - [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW]; } + + [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW]; } - (NSInteger) pixelScaler @@ -2088,39 +2044,30 @@ static std::unordered_map _screenMap; // DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate]; CocoaDSCore *cdsCore = (CocoaDSCore *)[[[windowController emuControl] cdsCoreController] content]; CocoaDSGPU *cdsGPU = [cdsCore cdsGPU]; + MacClientSharedObject *macSharedData = [cdsGPU sharedData]; BOOL isMetalLayer = NO; #ifdef ENABLE_APPLE_METAL - MacClientSharedObject *macSharedData = [cdsGPU sharedData]; if ((macSharedData != nil) && [macSharedData isKindOfClass:[MetalDisplayViewSharedData class]]) { - localLayer = [[DisplayViewMetalLayer alloc] init]; - [(DisplayViewMetalLayer *)localLayer setSharedData:(MetalDisplayViewSharedData *)macSharedData]; - - MacMetalDisplayView *macMTLCDV = (MacMetalDisplayView *)[(id)localLayer clientDisplay3DView]; - macMTLCDV->SetFetchObject([cdsGPU fetchObject]); - macMTLCDV->Init(); - macMTLCDV->SetNSView(self); - macMTLCDV->SetSharedData([cdsGPU sharedData]); - - if ([(DisplayViewMetalLayer *)localLayer device] == nil) + if ([(MetalDisplayViewSharedData *)macSharedData device] != nil) { - [localLayer release]; - localLayer = nil; + MacMetalDisplayView *macMTLCDV = new MacMetalDisplayView(macSharedData); + macMTLCDV->SetNSView(self); + macMTLCDV->Init(); + + localLayer = macMTLCDV->GetCALayer(); + isMetalLayer = YES; } - - isMetalLayer = YES; } + else #endif - - if (localLayer == nil) { - localLayer = [[DisplayViewOpenGLLayer alloc] init]; - MacOGLDisplayView *macOGLCDV = (MacOGLDisplayView *)[(id)localLayer clientDisplay3DView]; - macOGLCDV->SetFetchObject([cdsGPU fetchObject]); - macOGLCDV->Init(); + MacOGLDisplayView *macOGLCDV = new MacOGLDisplayView(macSharedData); macOGLCDV->SetNSView(self); - macOGLCDV->SetSharedData([cdsGPU sharedData]); + macOGLCDV->Init(); + + localLayer = macOGLCDV->GetCALayer(); // For macOS 10.8 Mountain Lion and later, we can use the CAOpenGLLayer directly. But for // earlier versions of macOS, using the CALayer directly will cause too many strange issues, @@ -2137,13 +2084,13 @@ static std::unordered_map _screenMap; // [self setWantsBestResolutionOpenGLSurface:YES]; } #endif - localOGLContext = macOGLCDV->GetNSContext(); + localOGLContext = ((MacOGLDisplayPresenter *)macOGLCDV->Get3DPresenter())->GetNSContext(); [localOGLContext retain]; } } - ClientDisplay3DView *cdv = [(id)localLayer clientDisplay3DView]; - cdv->UpdateView(); + MacDisplayLayeredView *cdv = [localLayer clientDisplayView]; + cdv->Get3DPresenter()->UpdateLayout(); if (localOGLContext != nil) { @@ -2174,19 +2121,6 @@ static std::unordered_map _screenMap; // } } -- (void) requestScreenshot:(NSURL *)fileURL fileType:(NSBitmapImageFileType)fileType -{ - NSString *fileURLString = [fileURL absoluteString]; - NSData *fileURLStringData = [fileURLString dataUsingEncoding:NSUTF8StringEncoding]; - NSData *bitmapImageFileTypeData = [[NSData alloc] initWithBytes:&fileType length:sizeof(NSBitmapImageFileType)]; - NSArray *messageComponents = [[NSArray alloc] initWithObjects:fileURLStringData, bitmapImageFileTypeData, nil]; - - [CocoaDSUtil messageSendOneWayWithMessageComponents:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REQUEST_SCREENSHOT array:messageComponents]; - - [bitmapImageFileTypeData release]; - [messageComponents release]; -} - #pragma mark InputHIDManagerTarget Protocol - (BOOL) handleHIDQueue:(IOHIDQueueRef)hidQueue hidManager:(InputHIDManager *)hidManager { @@ -2261,12 +2195,12 @@ static std::unordered_map _screenMap; // - (void)updateLayer { - [self clientDisplay3DView]->FlushView(); + [self clientDisplayView]->FlushView(); } - (void)drawRect:(NSRect)dirtyRect { - [self clientDisplay3DView]->FlushView(); + [self clientDisplayView]->FlushView(); } - (void)setFrame:(NSRect)rect @@ -2277,7 +2211,7 @@ static std::unordered_map _screenMap; // if (rect.size.width != oldFrame.size.width || rect.size.height != oldFrame.size.height) { DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate]; - ClientDisplayViewProperties &props = [windowController localViewProperties]; + ClientDisplayPresenterProperties &props = [windowController localViewProperties]; NSRect newViewportRect = rect; #if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7) @@ -2290,11 +2224,11 @@ static std::unordered_map _screenMap; // // Calculate the view scale for the given client size. double checkWidth = props.normalWidth; double checkHeight = props.normalHeight; - ClientDisplayView::ConvertNormalToTransformedBounds(1.0, props.rotation, checkWidth, checkHeight); + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, props.rotation, checkWidth, checkHeight); props.clientWidth = newViewportRect.size.width; props.clientHeight = newViewportRect.size.height; - props.viewScale = ClientDisplayView::GetMaxScalarWithinBounds(checkWidth, checkHeight, props.clientWidth, props.clientHeight); + props.viewScale = ClientDisplayPresenter::GetMaxScalarWithinBounds(checkWidth, checkHeight, props.clientWidth, props.clientHeight); if (localOGLContext != nil) { @@ -2311,7 +2245,7 @@ static std::unordered_map _screenMap; // } #endif - [[self cdsVideoOutput] commitViewProperties:props]; + [[self cdsVideoOutput] commitPresenterProperties:props]; } } diff --git a/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.h b/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.h index 1c78969f4..f69776511 100644 --- a/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.h +++ b/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.h @@ -28,6 +28,8 @@ @class CocoaDSCheatManager; @class CheatWindowDelegate; @class DisplayWindowController; +@class RomInfoPanel; +@class MacScreenshotCaptureToolDelegate; class AudioSampleBlockGenerator; @interface EmuControllerDelegate : NSObject @@ -41,15 +43,19 @@ class AudioSampleBlockGenerator; CocoaDSCheatManager *dummyCheatList; CheatWindowDelegate *cheatWindowDelegate; + MacScreenshotCaptureToolDelegate *screenshotCaptureToolDelegate; NSObjectController *firmwarePanelController; NSObjectController *romInfoPanelController; NSObjectController *cdsCoreController; NSObjectController *cdsSoundController; NSObjectController *cheatWindowController; NSObjectController *slot2WindowController; + NSArrayController *inputDeviceListController; NSArrayController *cheatListController; NSArrayController *cheatDatabaseController; + RomInfoPanel *romInfoPanel; + NSWindow *displayRotationPanel; NSWindow *displaySeparationPanel; NSWindow *displayVideoSettingsPanel; @@ -116,15 +122,19 @@ class AudioSampleBlockGenerator; @property (retain) CocoaDSCheatManager *cdsCheats; @property (readonly) IBOutlet CheatWindowDelegate *cheatWindowDelegate; +@property (readonly) IBOutlet MacScreenshotCaptureToolDelegate *screenshotCaptureToolDelegate; @property (readonly) IBOutlet NSObjectController *firmwarePanelController; @property (readonly) IBOutlet NSObjectController *romInfoPanelController; @property (readonly) IBOutlet NSObjectController *cdsCoreController; @property (readonly) IBOutlet NSObjectController *cdsSoundController; @property (readonly) IBOutlet NSObjectController *cheatWindowController; @property (readonly) IBOutlet NSObjectController *slot2WindowController; +@property (readonly) IBOutlet NSArrayController *inputDeviceListController; @property (readonly) IBOutlet NSArrayController *cheatListController; @property (readonly) IBOutlet NSArrayController *cheatDatabaseController; +@property (readonly) IBOutlet RomInfoPanel *romInfoPanel; + @property (readonly) IBOutlet NSWindow *displayRotationPanel; @property (readonly) IBOutlet NSWindow *displaySeparationPanel; @property (readonly) IBOutlet NSWindow *displayVideoSettingsPanel; @@ -278,6 +288,10 @@ class AudioSampleBlockGenerator; - (void) updateAllWindowTitles; - (void) updateDisplayPanelTitles; -- (void) setupUserDefaults; +- (void) appInit; +- (void) readUserDefaults; +- (void) writeUserDefaults; +- (void) restoreDisplayWindowStates; +- (void) saveDisplayWindowStates; @end diff --git a/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm b/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm index 4a8715738..a723b6159 100644 --- a/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm +++ b/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm @@ -20,6 +20,7 @@ #import "InputManager.h" #import "cheatWindowDelegate.h" #import "Slot2WindowDelegate.h" +#import "MacScreenshotCaptureTool.h" #import "cocoa_globals.h" #import "cocoa_cheat.h" @@ -42,6 +43,7 @@ @synthesize cdsCheats; @synthesize cheatWindowDelegate; +@synthesize screenshotCaptureToolDelegate; @synthesize firmwarePanelController; @synthesize romInfoPanelController; @synthesize cdsCoreController; @@ -50,6 +52,9 @@ @synthesize cheatListController; @synthesize cheatDatabaseController; @synthesize slot2WindowController; +@synthesize inputDeviceListController; + +@synthesize romInfoPanel; @synthesize displayRotationPanel; @synthesize displaySeparationPanel; @@ -1029,7 +1034,7 @@ if ([[windowController view] isHUDInputVisible]) { - [[windowController view] clientDisplay3DView]->UpdateView(); + [[windowController view] clientDisplayView]->SetViewNeedsFlush(); } } } @@ -1054,7 +1059,7 @@ if ([[windowController view] isHUDInputVisible]) { - [[windowController view] clientDisplay3DView]->UpdateView(); + [[windowController view] clientDisplayView]->SetViewNeedsFlush(); } } } @@ -1078,7 +1083,7 @@ if ([[windowController view] isHUDInputVisible]) { - [[windowController view] clientDisplay3DView]->UpdateView(); + [[windowController view] clientDisplayView]->SetViewNeedsFlush(); } } } @@ -1808,6 +1813,7 @@ // Update the UI to indicate that a ROM has indeed been loaded. [self updateAllWindowTitles]; + [screenshotCaptureToolDelegate setRomName:[currentRom internalName]]; for (DisplayWindowController *windowController in windowList) { @@ -1889,6 +1895,7 @@ // Update the UI to indicate that the ROM has finished unloading. [self updateAllWindowTitles]; + [screenshotCaptureToolDelegate setRomName:[currentRom internalName]]; [[cdsCore cdsGPU] clearWithColor:0x8000]; for (DisplayWindowController *windowController in windowList) @@ -2245,9 +2252,37 @@ } } -- (void) setupUserDefaults +- (void) appInit +{ + [romInfoPanelController setContent:[CocoaDSRom romNotLoadedBindings]]; + [cheatWindowController setContent:[cheatWindowDelegate bindings]]; + + // Update the SLOT-2 device list. + Slot2WindowDelegate *slot2WindowDelegate = (Slot2WindowDelegate *)[slot2WindowController content]; + [slot2WindowDelegate update]; + [slot2WindowDelegate setHidManager:[inputManager hidManager]]; + [slot2WindowDelegate setAutoSelectedDeviceText:[[slot2WindowDelegate deviceManager] autoSelectedDeviceName]]; + + CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; + [screenshotCaptureToolDelegate setSharedData:[[cdsCore cdsGPU] sharedData]]; +} + +- (void) readUserDefaults { CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; + Slot2WindowDelegate *slot2WindowDelegate = (Slot2WindowDelegate *)[slot2WindowController content]; + + // Set up the user's default input settings. + NSDictionary *userMappings = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"Input_ControllerMappings"]; + if (userMappings == nil) + { + NSDictionary *defaultKeyMappingsDict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"DefaultKeyMappings" ofType:@"plist"]]; + NSArray *internalDefaultProfilesList = (NSArray *)[defaultKeyMappingsDict valueForKey:@"DefaultInputProfiles"]; + userMappings = [(NSDictionary *)[internalDefaultProfilesList objectAtIndex:0] valueForKey:@"Mappings"]; + } + + [inputManager setMappingsWithMappings:userMappings]; + [[inputManager hidManager] setDeviceListController:inputDeviceListController]; // Set the microphone settings per user preferences. [[cdsCore cdsController] setHardwareMicMute:[[NSUserDefaults standardUserDefaults] boolForKey:@"Microphone_HardwareMicMute"]]; @@ -2279,6 +2314,227 @@ // Set the stylus options per user preferences. [[cdsCore cdsController] setStylusPressure:[[NSUserDefaults standardUserDefaults] integerForKey:@"Emulation_StylusPressure"]]; + + // Set up the default SLOT-2 device. + [slot2WindowDelegate setupUserDefaults]; + + // Set up the ROM Info panel. + [romInfoPanel setupUserDefaults]; + + // Set up the screenshot capture tool defaults. + [screenshotCaptureToolDelegate readUserDefaults]; +} + +- (void) writeUserDefaults +{ + [romInfoPanel writeDefaults]; + [screenshotCaptureToolDelegate writeUserDefaults]; +} + +- (void) restoreDisplayWindowStates +{ + NSArray *windowPropertiesList = [[NSUserDefaults standardUserDefaults] arrayForKey:@"General_DisplayWindowRestorableStates"]; + const BOOL willRestoreWindows = [[NSUserDefaults standardUserDefaults] boolForKey:@"General_WillRestoreDisplayWindows"]; + + if (!willRestoreWindows || windowPropertiesList == nil || [windowPropertiesList count] < 1) + { + // If no windows were saved for restoring (the user probably closed all windows before + // app termination), then simply create a new display window per user defaults. + [self newDisplayWindow:self]; + } + else + { + for (NSDictionary *windowProperties in windowPropertiesList) + { + DisplayWindowController *windowController = [[DisplayWindowController alloc] initWithWindowNibName:@"DisplayWindow" emuControlDelegate:self]; + + if (windowController == nil) + { + continue; + } + + const NSInteger displayMode = ([windowProperties objectForKey:@"displayMode"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayMode"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_Mode"]; + const double displayScale = ([windowProperties objectForKey:@"displayScale"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayScale"] doubleValue] : ([[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayView_Size"] / 100.0); + const double displayRotation = ([windowProperties objectForKey:@"displayRotation"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayRotation"] doubleValue] : [[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayView_Rotation"]; + const NSInteger displayOrientation = ([windowProperties objectForKey:@"displayOrientation"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayOrientation"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Orientation"]; + const NSInteger displayOrder = ([windowProperties objectForKey:@"displayOrder"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayOrder"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Order"]; + const double displayGap = ([windowProperties objectForKey:@"displayGap"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayGap"] doubleValue] : ([[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayViewCombo_Gap"] / 100.0); + + const NSInteger displayMainSource = ([windowProperties objectForKey:@"displayMainVideoSource"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayMainVideoSource"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_DisplayMainVideoSource"]; + const NSInteger displayTouchSource = ([windowProperties objectForKey:@"displayTouchVideoSource"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayTouchVideoSource"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_DisplayTouchVideoSource"]; + + const BOOL videoFiltersPreferGPU = ([windowProperties objectForKey:@"videoFiltersPreferGPU"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"videoFiltersPreferGPU"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_FiltersPreferGPU"]; + const BOOL videoSourceDeposterize = ([windowProperties objectForKey:@"videoSourceDeposterize"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"videoSourceDeposterize"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_Deposterize"]; + const NSInteger videoPixelScaler = ([windowProperties objectForKey:@"videoFilterType"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"videoFilterType"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_VideoFilter"]; + const NSInteger videoOutputFilter = ([windowProperties objectForKey:@"videoOutputFilter"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"videoOutputFilter"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_OutputFilter"]; + + const BOOL hudEnable = ([windowProperties objectForKey:@"hudEnable"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudEnable"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_EnableHUD"]; + const BOOL hudShowVideoFPS = ([windowProperties objectForKey:@"hudShowVideoFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowVideoFPS"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowVideoFPS"]; + const BOOL hudShowRender3DFPS = ([windowProperties objectForKey:@"hudShowRender3DFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowRender3DFPS"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowRender3DFPS"]; + const BOOL hudShowFrameIndex = ([windowProperties objectForKey:@"hudShowFrameIndex"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowFrameIndex"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowFrameIndex"]; + const BOOL hudShowLagFrameCount = ([windowProperties objectForKey:@"hudShowLagFrameCount"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowLagFrameCount"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowLagFrameCount"]; + const BOOL hudShowCPULoadAverage = ([windowProperties objectForKey:@"hudShowCPULoadAverage"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowCPULoadAverage"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowCPULoadAverage"]; + const BOOL hudShowRTC = ([windowProperties objectForKey:@"hudShowRTC"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowRTC"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowRTC"]; + const BOOL hudShowInput = ([windowProperties objectForKey:@"hudShowInput"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowInput"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowInput"]; + + const NSUInteger hudColorVideoFPS = ([windowProperties objectForKey:@"hudColorVideoFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorVideoFPS"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_VideoFPS"]; + const NSUInteger hudColorRender3DFPS = ([windowProperties objectForKey:@"hudColorRender3DFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorRender3DFPS"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Render3DFPS"]; + const NSUInteger hudColorFrameIndex = ([windowProperties objectForKey:@"hudColorFrameIndex"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorFrameIndex"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_FrameIndex"]; + const NSUInteger hudColorLagFrameCount = ([windowProperties objectForKey:@"hudColorLagFrameCount"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorLagFrameCount"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_LagFrameCount"]; + const NSUInteger hudColorCPULoadAverage = ([windowProperties objectForKey:@"hudColorCPULoadAverage"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorCPULoadAverage"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_CPULoadAverage"]; + const NSUInteger hudColorRTC = ([windowProperties objectForKey:@"hudColorRTC"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorRTC"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_RTC"]; + const NSUInteger hudColorInputPendingAndApplied = ([windowProperties objectForKey:@"hudColorInputPendingAndApplied"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorInputPendingAndApplied"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Input_PendingAndApplied"]; + const NSUInteger hudColorInputAppliedOnly = ([windowProperties objectForKey:@"hudColorInputAppliedOnly"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorInputAppliedOnly"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Input_AppliedOnly"]; + const NSUInteger hudColorInputPendingOnly = ([windowProperties objectForKey:@"hudColorInputPendingOnly"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorInputPendingOnly"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Input_PendingOnly"]; + + const BOOL useVerticalSync = ([windowProperties objectForKey:@"useVerticalSync"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"useVerticalSync"] boolValue] : YES; + const BOOL isMinSizeNormal = ([windowProperties objectForKey:@"isMinSizeNormal"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"isMinSizeNormal"] boolValue] : YES; + const BOOL isShowingStatusBar = ([windowProperties objectForKey:@"isShowingStatusBar"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"isShowingStatusBar"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_ShowStatusBar"]; + const BOOL isInFullScreenMode = ([windowProperties objectForKey:@"isInFullScreenMode"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"isInFullScreenMode"] boolValue] : NO; + const NSUInteger screenIndex = ([windowProperties objectForKey:@"screenIndex"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"screenIndex"] unsignedIntegerValue] : 0; + NSString *windowFrameStr = (NSString *)[windowProperties valueForKey:@"windowFrame"]; + + int frameX = 0; + int frameY = 0; + int frameWidth = 256; + int frameHeight = 192*2; + const char *frameCStr = [windowFrameStr cStringUsingEncoding:NSUTF8StringEncoding]; + sscanf(frameCStr, "%i %i %i %i", &frameX, &frameY, &frameWidth, &frameHeight); + + // Force the window to load now so that we can overwrite its internal defaults with the user's defaults. + [windowController window]; + + [windowController setDisplayMode:(ClientDisplayMode)displayMode + viewScale:displayScale + rotation:displayRotation + layout:(ClientDisplayLayout)displayOrientation + order:(ClientDisplayOrder)displayOrder + gapScale:displayGap + isMinSizeNormal:isMinSizeNormal + isShowingStatusBar:isShowingStatusBar]; + + [[windowController view] setDisplayMainVideoSource:displayMainSource]; + [[windowController view] setDisplayTouchVideoSource:displayTouchSource]; + + [windowController setVideoPropertiesWithoutUpdateUsingPreferGPU:videoFiltersPreferGPU + sourceDeposterize:videoSourceDeposterize + outputFilter:videoOutputFilter + pixelScaler:videoPixelScaler]; + + [[windowController view] setUseVerticalSync:useVerticalSync]; + [[windowController view] setIsHUDVisible:hudEnable]; + [[windowController view] setIsHUDVideoFPSVisible:hudShowVideoFPS]; + [[windowController view] setIsHUDRender3DFPSVisible:hudShowRender3DFPS]; + [[windowController view] setIsHUDFrameIndexVisible:hudShowFrameIndex]; + [[windowController view] setIsHUDLagFrameCountVisible:hudShowLagFrameCount]; + [[windowController view] setIsHUDCPULoadAverageVisible:hudShowCPULoadAverage]; + [[windowController view] setIsHUDRealTimeClockVisible:hudShowRTC]; + [[windowController view] setIsHUDInputVisible:hudShowInput]; + + [[windowController view] setHudColorVideoFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorVideoFPS]]; + [[windowController view] setHudColorRender3DFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorRender3DFPS]]; + [[windowController view] setHudColorFrameIndex:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorFrameIndex]]; + [[windowController view] setHudColorLagFrameCount:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorLagFrameCount]]; + [[windowController view] setHudColorCPULoadAverage:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorCPULoadAverage]]; + [[windowController view] setHudColorRTC:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorRTC]]; + [[windowController view] setHudColorInputPendingAndApplied:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorInputPendingAndApplied]]; + [[windowController view] setHudColorInputAppliedOnly:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorInputAppliedOnly]]; + [[windowController view] setHudColorInputPendingOnly:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorInputPendingOnly]]; + + [[windowController masterWindow] setFrameOrigin:NSMakePoint(frameX, frameY)]; + + // If this is the last window in the list, make this window key and main. + // Otherwise, just order the window to the front so that the windows will + // stack in a deterministic order. + [[windowController view] setAllowViewUpdates:YES]; + [[[windowController view] cdsVideoOutput] handleReloadReprocessRedraw]; + + if (windowProperties == [windowPropertiesList lastObject]) + { + [[windowController window] makeKeyAndOrderFront:self]; + [[windowController window] makeMainWindow]; + } + else + { + [[windowController window] orderFront:self]; + } + + // If this window is set to full screen mode, its associated screen index must + // exist. If not, this window will not enter full screen mode. This is necessary, + // since the user's screen configuration could change in between app launches, + // and since we don't want a window to go full screen on the wrong screen. + if (isInFullScreenMode && + ([[NSScreen screens] indexOfObject:[[windowController window] screen]] == screenIndex)) + { + [windowController toggleFullScreenDisplay:self]; + } + } + } +} + +- (void) saveDisplayWindowStates +{ + const BOOL willRestoreWindows = [[NSUserDefaults standardUserDefaults] boolForKey:@"General_WillRestoreDisplayWindows"]; + + if (willRestoreWindows && [windowList count] > 0) + { + NSMutableArray *windowPropertiesList = [NSMutableArray arrayWithCapacity:[windowList count]]; + + for (DisplayWindowController *windowController in windowList) + { + const NSUInteger screenIndex = [[NSScreen screens] indexOfObject:[[windowController masterWindow] screen]]; + + const NSRect windowFrame = [windowController masterWindowFrame]; + NSString *windowFrameStr = [NSString stringWithFormat:@"%i %i %i %i", + (int)windowFrame.origin.x, (int)windowFrame.origin.y, (int)windowFrame.size.width, (int)windowFrame.size.height]; + + NSDictionary *windowProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInteger:[windowController displayMode]], @"displayMode", + [NSNumber numberWithDouble:[windowController masterWindowScale]], @"displayScale", + [NSNumber numberWithDouble:[windowController displayRotation]], @"displayRotation", + [NSNumber numberWithInteger:[[windowController view] displayMainVideoSource]], @"displayMainVideoSource", + [NSNumber numberWithInteger:[[windowController view] displayTouchVideoSource]], @"displayTouchVideoSource", + [NSNumber numberWithInteger:[windowController displayOrientation]], @"displayOrientation", + [NSNumber numberWithInteger:[windowController displayOrder]], @"displayOrder", + [NSNumber numberWithDouble:[windowController displayGap]], @"displayGap", + [NSNumber numberWithBool:[[windowController view] videoFiltersPreferGPU]], @"videoFiltersPreferGPU", + [NSNumber numberWithInteger:[[windowController view] pixelScaler]], @"videoFilterType", + [NSNumber numberWithInteger:[[windowController view] outputFilter]], @"videoOutputFilter", + [NSNumber numberWithBool:[[windowController view] sourceDeposterize]], @"videoSourceDeposterize", + [NSNumber numberWithBool:[[windowController view] useVerticalSync]], @"useVerticalSync", + [NSNumber numberWithBool:[[windowController view] isHUDVisible]], @"hudEnable", + [NSNumber numberWithBool:[[windowController view] isHUDVideoFPSVisible]], @"hudShowVideoFPS", + [NSNumber numberWithBool:[[windowController view] isHUDRender3DFPSVisible]], @"hudShowRender3DFPS", + [NSNumber numberWithBool:[[windowController view] isHUDFrameIndexVisible]], @"hudShowFrameIndex", + [NSNumber numberWithBool:[[windowController view] isHUDLagFrameCountVisible]], @"hudShowLagFrameCount", + [NSNumber numberWithBool:[[windowController view] isHUDCPULoadAverageVisible]], @"hudShowCPULoadAverage", + [NSNumber numberWithBool:[[windowController view] isHUDRealTimeClockVisible]], @"hudShowRTC", + [NSNumber numberWithBool:[[windowController view] isHUDInputVisible]], @"hudShowInput", + [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorVideoFPS]]], @"hudColorVideoFPS", + [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorRender3DFPS]]], @"hudColorRender3DFPS", + [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorFrameIndex]]], @"hudColorFrameIndex", + [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorLagFrameCount]]], @"hudColorLagFrameCount", + [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorCPULoadAverage]]], @"hudColorCPULoadAverage", + [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorRTC]]], @"hudColorRTC", + [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorInputPendingAndApplied]]], @"hudColorInputPendingAndApplied", + [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorInputAppliedOnly]]], @"hudColorInputAppliedOnly", + [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorInputPendingOnly]]], @"hudColorInputPendingOnly", + [NSNumber numberWithBool:[windowController isMinSizeNormal]], @"isMinSizeNormal", + [NSNumber numberWithBool:[windowController masterStatusBarState]], @"isShowingStatusBar", + [NSNumber numberWithBool:[windowController isFullScreen]], @"isInFullScreenMode", + [NSNumber numberWithUnsignedInteger:screenIndex], @"screenIndex", + windowFrameStr, @"windowFrame", + nil]; + + [windowPropertiesList addObject:windowProperties]; + } + + [[NSUserDefaults standardUserDefaults] setObject:windowPropertiesList forKey:@"General_DisplayWindowRestorableStates"]; + } + else + { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"General_DisplayWindowRestorableStates"]; + } } #pragma mark NSUserInterfaceValidations Protocol diff --git a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.h b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.h index 8c489471b..60e9229e4 100644 --- a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.h +++ b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.h @@ -31,6 +31,7 @@ #endif class MacMetalFetchObject; +class MacMetalDisplayPresenter; class MacMetalDisplayView; struct DisplayViewShaderProperties @@ -155,16 +156,17 @@ typedef DisplayViewShaderProperties DisplayViewShaderProperties; @end -@interface DisplayViewMetalLayer : CAMetalLayer +@interface MacMetalDisplayPresenterObject : NSObject { - MacMetalDisplayView *_cdv; + ClientDisplay3DPresenter *cdp; MetalDisplayViewSharedData *sharedData; MTLRenderPassDescriptor *_outputRenderPassDesc; MTLRenderPassColorAttachmentDescriptor *colorAttachment0Desc; id pixelScalePipeline; - id displayOutputPipeline; - id displayRGBAOutputPipeline; + id outputRGBAPipeline; + id outputDrawablePipeline; + MTLPixelFormat drawableFormat; id _cdvPropertiesBuffer; id _displayVtxPositionBuffer; @@ -202,11 +204,15 @@ typedef DisplayViewShaderProperties DisplayViewShaderProperties; size_t _hudTouchLineLength; } +@property (readonly, nonatomic) ClientDisplay3DPresenter *cdp; @property (assign, nonatomic) MetalDisplayViewSharedData *sharedData; @property (readonly, nonatomic) MTLRenderPassColorAttachmentDescriptor *colorAttachment0Desc; +@property (readonly, nonatomic) pthread_mutex_t *mutexDisplayTextureUpdate; +@property (readonly, nonatomic) pthread_mutex_t *mutexBufferUpdate; @property (retain) id pixelScalePipeline; -@property (retain) id displayOutputPipeline; -@property (retain) id displayRGBAOutputPipeline; +@property (retain) id outputRGBAPipeline; +@property (retain) id outputDrawablePipeline; +@property (assign) MTLPixelFormat drawableFormat; @property (retain) id bufCPUFilterSrcMain; @property (retain) id bufCPUFilterSrcTouch; @property (retain) id bufCPUFilterDstMain; @@ -221,17 +227,31 @@ typedef DisplayViewShaderProperties DisplayViewShaderProperties; @property (assign, nonatomic) VideoFilterTypeID pixelScaler; @property (assign, nonatomic) OutputFilterTypeID outputFilter; +- (id) initWithDisplayPresenter:(MacMetalDisplayPresenter *)thePresenter; - (id) newCommandBuffer; -- (void) setupLayer; +- (void) setup; - (void) resizeCPUPixelScalerUsingFilterID:(const VideoFilterTypeID)filterID; - (void) copyHUDFontUsingFace:(const FT_Face &)fontFace size:(const size_t)glyphSize tileSize:(const size_t)glyphTileSize info:(GlyphInfo *)glyphInfo; - (void) processDisplays; - (void) updateRenderBuffers; - (void) renderForCommandBuffer:(id)cb - displayPipelineState:(id)displayPipelineState + outputPipelineState:(id)outputPipelineState hudPipelineState:(id)hudPipelineState; -- (void) renderAndDownloadToBuffer:(uint32_t *)dstBuffer; -- (void) renderAndFlushDrawable; +- (void) renderToBuffer:(uint32_t *)dstBuffer; + +@end + +@interface DisplayViewMetalLayer : CAMetalLayer +{ + MacDisplayLayeredView *_cdv; + MacMetalDisplayPresenterObject *presenterObject; +} + +@property (readonly, nonatomic) MacMetalDisplayPresenterObject *presenterObject; + +- (id) initWithDisplayPresenterObject:(MacMetalDisplayPresenterObject *)thePresenterObject; +- (void) setupLayer; +- (void) renderToDrawable; @end @@ -260,11 +280,14 @@ public: #pragma mark - -class MacMetalDisplayView : public ClientDisplay3DView, public DisplayViewCALayerInterface +class MacMetalDisplayPresenter : public ClientDisplay3DPresenter, public MacDisplayPresenterInterface { +private: + void __InstanceInit(MacClientSharedObject *sharedObject); + protected: - pthread_mutex_t *_mutexProcessPtr; - OSSpinLock _spinlockViewNeedsFlush; + MacMetalDisplayPresenterObject *_presenterObject; + pthread_mutex_t _mutexProcessPtr; virtual void _UpdateNormalSize(); virtual void _UpdateOrder(); @@ -273,17 +296,17 @@ protected: virtual void _UpdateViewScale(); virtual void _LoadNativeDisplayByID(const NDSDisplayID displayID); virtual void _ResizeCPUPixelScaler(const VideoFilterTypeID filterID); - -public: - MacMetalDisplayView(); - virtual ~MacMetalDisplayView(); - pthread_mutex_t* GetMutexProcessPtr() const; +public: + MacMetalDisplayPresenter(); + MacMetalDisplayPresenter(MacClientSharedObject *sharedObject); + virtual ~MacMetalDisplayPresenter(); + + MacMetalDisplayPresenterObject* GetPresenterObject() const; + pthread_mutex_t* GetMutexProcessPtr(); virtual void Init(); - virtual bool GetViewNeedsFlush(); - virtual void SetAllowViewFlushes(bool allowFlushes); - + virtual void SetSharedData(MacClientSharedObject *sharedObject); virtual void CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo); // NDS screen filters @@ -293,12 +316,35 @@ public: // Client view interface virtual void ProcessDisplays(); - virtual void UpdateView(); - virtual void FlushView(); + virtual void UpdateLayout(); virtual void CopyFrameToBuffer(uint32_t *dstBuffer); }; +class MacMetalDisplayView : public MacDisplayLayeredView +{ +private: + void __InstanceInit(MacClientSharedObject *sharedObject); + +protected: + OSSpinLock _spinlockViewNeedsFlush; + +public: + MacMetalDisplayView(); + MacMetalDisplayView(MacClientSharedObject *sharedObject); + virtual ~MacMetalDisplayView(); + + virtual void Init(); + + virtual bool GetViewNeedsFlush(); + virtual void SetViewNeedsFlush(); + + virtual void SetAllowViewFlushes(bool allowFlushes); + + // Client view interface + virtual void FlushView(); +}; + #pragma mark - void SetupHQnxLUTs_Metal(id &device, id &texLQ2xLUT, id &texHQ2xLUT, id &texHQ3xLUT, id &texHQ4xLUT); void DeleteHQnxLUTs_Metal(id &texLQ2xLUT, id &texHQ2xLUT, id &texHQ3xLUT, id &texHQ4xLUT); diff --git a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm index f8f9968a4..2f8df6f43 100644 --- a/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm +++ b/desmume/src/frontend/cocoa/userinterface/MacMetalDisplayView.mm @@ -728,13 +728,17 @@ @end -@implementation DisplayViewMetalLayer +@implementation MacMetalDisplayPresenterObject +@synthesize cdp; @synthesize sharedData; @synthesize colorAttachment0Desc; +@dynamic mutexDisplayTextureUpdate; +@dynamic mutexBufferUpdate; @synthesize pixelScalePipeline; -@synthesize displayOutputPipeline; -@synthesize displayRGBAOutputPipeline; +@synthesize outputRGBAPipeline; +@synthesize outputDrawablePipeline; +@synthesize drawableFormat; @synthesize bufCPUFilterSrcMain; @synthesize bufCPUFilterSrcTouch; @synthesize bufCPUFilterDstMain; @@ -749,7 +753,7 @@ @dynamic pixelScaler; @dynamic outputFilter; -- (id)init +- (id) initWithDisplayPresenter:(MacMetalDisplayPresenter *)thePresenter { self = [super init]; if(self == nil) @@ -757,10 +761,16 @@ return nil; } - sharedData = nil; + cdp = thePresenter; - _cdv = new MacMetalDisplayView(); - _cdv->SetFrontendLayer(self); + if (thePresenter != NULL) + { + sharedData = (MetalDisplayViewSharedData *)thePresenter->GetSharedData(); + } + else + { + sharedData = nil; + } _outputRenderPassDesc = [[MTLRenderPassDescriptor renderPassDescriptor] retain]; colorAttachment0Desc = [[_outputRenderPassDesc colorAttachments] objectAtIndexedSubscript:0]; @@ -770,8 +780,9 @@ [colorAttachment0Desc setTexture:nil]; pixelScalePipeline = nil; - displayOutputPipeline = nil; - displayRGBAOutputPipeline = nil; + outputRGBAPipeline = nil; + outputDrawablePipeline = nil; + drawableFormat = MTLPixelFormatInvalid; _cdvPropertiesBuffer = nil; _displayVtxPositionBuffer = nil; @@ -794,8 +805,6 @@ _texDisplayOutput[1] = nil; texHUDCharMap = nil; - [self setOpaque:YES]; - _pixelScalerThreadsPerGroup = MTLSizeMake(1, 1, 1); _pixelScalerThreadGroupsPerGrid = MTLSizeMake(1, 1, 1); @@ -812,6 +821,7 @@ - (void)dealloc { + [[self colorAttachment0Desc] setTexture:nil]; [_outputRenderPassDesc release]; [_cdvPropertiesBuffer release]; @@ -833,14 +843,12 @@ [self setTexDisplayPixelScaleMain:nil]; [self setTexDisplayPixelScaleTouch:nil]; - [[self colorAttachment0Desc] setTexture:nil]; [self setPixelScalePipeline:nil]; - [self setDisplayOutputPipeline:nil]; - [self setDisplayRGBAOutputPipeline:nil]; + [self setOutputRGBAPipeline:nil]; + [self setOutputDrawablePipeline:nil]; [self setTexHUDCharMap:nil]; [self setSharedData:nil]; - delete _cdv; pthread_mutex_destroy(&_mutexDisplayTextureUpdate); pthread_mutex_destroy(&_mutexBufferUpdate); @@ -848,14 +856,19 @@ [super dealloc]; } -- (ClientDisplay3DView *)clientDisplay3DView +- (pthread_mutex_t *) mutexDisplayTextureUpdate { - return _cdv; + return &_mutexDisplayTextureUpdate; +} + +- (pthread_mutex_t *) mutexBufferUpdate +{ + return &_mutexBufferUpdate; } - (VideoFilterTypeID) pixelScaler { - return _cdv->GetPixelScaler(); + return cdp->GetPixelScaler(); } - (void) setPixelScaler:(VideoFilterTypeID)filterID @@ -865,91 +878,91 @@ switch (filterID) { case VideoFilterTypeID_Nearest2X: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_nearest2x"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_nearest2x"] error:nil]]; break; case VideoFilterTypeID_Scanline: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_scanline"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_scanline"] error:nil]]; break; case VideoFilterTypeID_EPX: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xEPX"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xEPX"] error:nil]]; break; case VideoFilterTypeID_EPXPlus: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xEPXPlus"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xEPXPlus"] error:nil]]; break; case VideoFilterTypeID_2xSaI: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xSaI"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xSaI"] error:nil]]; break; case VideoFilterTypeID_Super2xSaI: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_Super2xSaI"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_Super2xSaI"] error:nil]]; break; case VideoFilterTypeID_SuperEagle: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xSuperEagle"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xSuperEagle"] error:nil]]; break; case VideoFilterTypeID_LQ2X: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_LQ2x"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_LQ2x"] error:nil]]; currentHQnxLUT = [sharedData texLQ2xLUT]; break; case VideoFilterTypeID_LQ2XS: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_LQ2xS"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_LQ2xS"] error:nil]]; currentHQnxLUT = [sharedData texLQ2xLUT]; break; case VideoFilterTypeID_HQ2X: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ2x"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ2x"] error:nil]]; currentHQnxLUT = [sharedData texHQ2xLUT]; break; case VideoFilterTypeID_HQ2XS: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ2xS"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ2xS"] error:nil]]; currentHQnxLUT = [sharedData texHQ2xLUT]; break; case VideoFilterTypeID_HQ3X: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ3x"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ3x"] error:nil]]; currentHQnxLUT = [sharedData texHQ3xLUT]; break; case VideoFilterTypeID_HQ3XS: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ3xS"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ3xS"] error:nil]]; currentHQnxLUT = [sharedData texHQ3xLUT]; break; case VideoFilterTypeID_HQ4X: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ4x"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ4x"] error:nil]]; currentHQnxLUT = [sharedData texHQ4xLUT]; break; case VideoFilterTypeID_HQ4XS: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ4xS"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_HQ4xS"] error:nil]]; currentHQnxLUT = [sharedData texHQ4xLUT]; break; case VideoFilterTypeID_2xBRZ: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xBRZ"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_2xBRZ"] error:nil]]; break; case VideoFilterTypeID_3xBRZ: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_3xBRZ"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_3xBRZ"] error:nil]]; break; case VideoFilterTypeID_4xBRZ: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_4xBRZ"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_4xBRZ"] error:nil]]; break; case VideoFilterTypeID_5xBRZ: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_5xBRZ"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_5xBRZ"] error:nil]]; break; case VideoFilterTypeID_6xBRZ: - [self setPixelScalePipeline:[[self device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_6xBRZ"] error:nil]]; + [self setPixelScalePipeline:[[sharedData device] newComputePipelineStateWithFunction:[[sharedData defaultLibrary] newFunctionWithName:@"pixel_scaler_6xBRZ"] error:nil]]; break; case VideoFilterTypeID_None: @@ -972,8 +985,8 @@ [texDisplayPixelScaleDesc setStorageMode:MTLStorageModePrivate]; [texDisplayPixelScaleDesc setUsage:MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite]; - [self setTexDisplayPixelScaleMain:[[self device] newTextureWithDescriptor:texDisplayPixelScaleDesc]]; - [self setTexDisplayPixelScaleTouch:[[self device] newTextureWithDescriptor:texDisplayPixelScaleDesc]]; + [self setTexDisplayPixelScaleMain:[[sharedData device] newTextureWithDescriptor:texDisplayPixelScaleDesc]]; + [self setTexDisplayPixelScaleTouch:[[sharedData device] newTextureWithDescriptor:texDisplayPixelScaleDesc]]; if ([self pixelScalePipeline] != nil) { @@ -999,7 +1012,7 @@ - (OutputFilterTypeID) outputFilter { - return _cdv->GetOutputFilter(); + return cdp->GetOutputFilter(); } - (void) setOutputFilter:(OutputFilterTypeID)filterID @@ -1041,11 +1054,14 @@ break; } - [[[outputPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setPixelFormat:[self pixelFormat]]; - [self setDisplayOutputPipeline:[[self device] newRenderPipelineStateWithDescriptor:outputPipelineDesc error:nil]]; - [[[outputPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setPixelFormat:MTLPixelFormatRGBA8Unorm]; - [self setDisplayRGBAOutputPipeline:[[self device] newRenderPipelineStateWithDescriptor:outputPipelineDesc error:nil]]; + [self setOutputRGBAPipeline:[[sharedData device] newRenderPipelineStateWithDescriptor:outputPipelineDesc error:nil]]; + + if ([self drawableFormat] != MTLPixelFormatInvalid) + { + [[[outputPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setPixelFormat:[self drawableFormat]]; + [self setOutputDrawablePipeline:[[sharedData device] newRenderPipelineStateWithDescriptor:outputPipelineDesc error:nil]]; + } [outputPipelineDesc release]; } @@ -1055,35 +1071,36 @@ return [[sharedData commandQueue] commandBufferWithUnretainedReferences]; } -- (void) setupLayer +- (void) setup { - [self setDevice:[sharedData device]]; - MTLRenderPipelineDescriptor *outputPipelineDesc = [[MTLRenderPipelineDescriptor alloc] init]; [outputPipelineDesc setAlphaToOneEnabled:YES]; [outputPipelineDesc setVertexFunction:[[sharedData defaultLibrary] newFunctionWithName:@"display_output_vertex"]]; [outputPipelineDesc setFragmentFunction:[[sharedData defaultLibrary] newFunctionWithName:@"output_filter_bilinear"]]; - [[[outputPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setPixelFormat:[self pixelFormat]]; - displayOutputPipeline = [[[self device] newRenderPipelineStateWithDescriptor:outputPipelineDesc error:nil] retain]; - [[[outputPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setPixelFormat:MTLPixelFormatRGBA8Unorm]; - displayRGBAOutputPipeline = [[[self device] newRenderPipelineStateWithDescriptor:outputPipelineDesc error:nil] retain]; + outputRGBAPipeline = [[[sharedData device] newRenderPipelineStateWithDescriptor:outputPipelineDesc error:nil] retain]; + + if ([self drawableFormat] != MTLPixelFormatInvalid) + { + [[[outputPipelineDesc colorAttachments] objectAtIndexedSubscript:0] setPixelFormat:[self drawableFormat]]; + outputDrawablePipeline = [[[sharedData device] newRenderPipelineStateWithDescriptor:outputPipelineDesc error:nil] retain]; + } [outputPipelineDesc release]; - _cdvPropertiesBuffer = [[[self device] newBufferWithLength:sizeof(DisplayViewShaderProperties) options:MTLResourceStorageModeManaged] retain]; - _displayVtxPositionBuffer = [[[self device] newBufferWithLength:(sizeof(float) * (4 * 8)) options:MTLResourceStorageModeManaged] retain]; - _displayTexCoordBuffer = [[[self device] newBufferWithLength:(sizeof(float) * (4 * 8)) options:MTLResourceStorageModeManaged] retain]; - _hudVtxPositionBuffer = [[[self device] newBufferWithLength:HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE options:MTLResourceStorageModeManaged] retain]; - _hudVtxColorBuffer = [[[self device] newBufferWithLength:HUD_VERTEX_COLOR_ATTRIBUTE_BUFFER_SIZE options:MTLResourceStorageModeManaged] retain]; - _hudTexCoordBuffer = [[[self device] newBufferWithLength:HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE options:MTLResourceStorageModeManaged] retain]; + _cdvPropertiesBuffer = [[[sharedData device] newBufferWithLength:sizeof(DisplayViewShaderProperties) options:MTLResourceStorageModeManaged] retain]; + _displayVtxPositionBuffer = [[[sharedData device] newBufferWithLength:(sizeof(float) * (4 * 8)) options:MTLResourceStorageModeManaged] retain]; + _displayTexCoordBuffer = [[[sharedData device] newBufferWithLength:(sizeof(float) * (4 * 8)) options:MTLResourceStorageModeManaged] retain]; + _hudVtxPositionBuffer = [[[sharedData device] newBufferWithLength:HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE options:MTLResourceStorageModeManaged] retain]; + _hudVtxColorBuffer = [[[sharedData device] newBufferWithLength:HUD_VERTEX_COLOR_ATTRIBUTE_BUFFER_SIZE options:MTLResourceStorageModeManaged] retain]; + _hudTexCoordBuffer = [[[sharedData device] newBufferWithLength:HUD_VERTEX_ATTRIBUTE_BUFFER_SIZE options:MTLResourceStorageModeManaged] retain]; DisplayViewShaderProperties *viewProps = (DisplayViewShaderProperties *)[_cdvPropertiesBuffer contents]; - viewProps->width = _cdv->GetViewProperties().clientWidth; - viewProps->height = _cdv->GetViewProperties().clientHeight; - viewProps->rotation = _cdv->GetViewProperties().rotation; - viewProps->viewScale = _cdv->GetViewProperties().viewScale; + viewProps->width = cdp->GetPresenterProperties().clientWidth; + viewProps->height = cdp->GetPresenterProperties().clientHeight; + viewProps->rotation = cdp->GetPresenterProperties().rotation; + viewProps->viewScale = cdp->GetPresenterProperties().viewScale; viewProps->lowerHUDMipMapLevel = 0; [_cdvPropertiesBuffer didModifyRange:NSMakeRange(0, sizeof(DisplayViewShaderProperties))]; @@ -1096,10 +1113,10 @@ [texDisplaySrcDesc setStorageMode:MTLStorageModePrivate]; [texDisplaySrcDesc setUsage:MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite]; - _texDisplaySrcDeposterize[NDSDisplayID_Main][0] = [[[self device] newTextureWithDescriptor:texDisplaySrcDesc] retain]; - _texDisplaySrcDeposterize[NDSDisplayID_Touch][0] = [[[self device] newTextureWithDescriptor:texDisplaySrcDesc] retain]; - _texDisplaySrcDeposterize[NDSDisplayID_Main][1] = [[[self device] newTextureWithDescriptor:texDisplaySrcDesc] retain]; - _texDisplaySrcDeposterize[NDSDisplayID_Touch][1] = [[[self device] newTextureWithDescriptor:texDisplaySrcDesc] retain]; + _texDisplaySrcDeposterize[NDSDisplayID_Main][0] = [[[sharedData device] newTextureWithDescriptor:texDisplaySrcDesc] retain]; + _texDisplaySrcDeposterize[NDSDisplayID_Touch][0] = [[[sharedData device] newTextureWithDescriptor:texDisplaySrcDesc] retain]; + _texDisplaySrcDeposterize[NDSDisplayID_Main][1] = [[[sharedData device] newTextureWithDescriptor:texDisplaySrcDesc] retain]; + _texDisplaySrcDeposterize[NDSDisplayID_Touch][1] = [[[sharedData device] newTextureWithDescriptor:texDisplaySrcDesc] retain]; MTLTextureDescriptor *texDisplayPixelScaleDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm width:GPU_FRAMEBUFFER_NATIVE_WIDTH*2 @@ -1109,33 +1126,33 @@ [texDisplayPixelScaleDesc setStorageMode:MTLStorageModePrivate]; [texDisplayPixelScaleDesc setUsage:MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite]; - [self setTexDisplayPixelScaleMain:[[self device] newTextureWithDescriptor:texDisplayPixelScaleDesc]]; - [self setTexDisplayPixelScaleTouch:[[self device] newTextureWithDescriptor:texDisplayPixelScaleDesc]]; + [self setTexDisplayPixelScaleMain:[[sharedData device] newTextureWithDescriptor:texDisplayPixelScaleDesc]]; + [self setTexDisplayPixelScaleTouch:[[sharedData device] newTextureWithDescriptor:texDisplayPixelScaleDesc]]; _texDisplayOutput[NDSDisplayID_Main] = [sharedData texDisplayFetch32NativeMain]; _texDisplayOutput[NDSDisplayID_Touch] = [sharedData texDisplayFetch32NativeTouch]; - VideoFilter *vfMain = _cdv->GetPixelScalerObject(NDSDisplayID_Main); - [self setBufCPUFilterSrcMain:[[self device] newBufferWithBytesNoCopy:vfMain->GetSrcBufferPtr() - length:vfMain->GetSrcWidth() * vfMain->GetSrcHeight() * sizeof(uint32_t) - options:MTLResourceStorageModeManaged - deallocator:nil]]; + VideoFilter *vfMain = cdp->GetPixelScalerObject(NDSDisplayID_Main); + [self setBufCPUFilterSrcMain:[[sharedData device] newBufferWithBytesNoCopy:vfMain->GetSrcBufferPtr() + length:vfMain->GetSrcWidth() * vfMain->GetSrcHeight() * sizeof(uint32_t) + options:MTLResourceStorageModeManaged + deallocator:nil]]; - [self setBufCPUFilterDstMain:[[self device] newBufferWithBytesNoCopy:vfMain->GetDstBufferPtr() - length:vfMain->GetDstWidth() * vfMain->GetDstHeight() * sizeof(uint32_t) - options:MTLResourceStorageModeManaged - deallocator:nil]]; + [self setBufCPUFilterDstMain:[[sharedData device] newBufferWithBytesNoCopy:vfMain->GetDstBufferPtr() + length:vfMain->GetDstWidth() * vfMain->GetDstHeight() * sizeof(uint32_t) + options:MTLResourceStorageModeManaged + deallocator:nil]]; - VideoFilter *vfTouch = _cdv->GetPixelScalerObject(NDSDisplayID_Touch); - [self setBufCPUFilterSrcTouch:[[self device] newBufferWithBytesNoCopy:vfTouch->GetSrcBufferPtr() - length:vfTouch->GetSrcWidth() * vfTouch->GetSrcHeight() * sizeof(uint32_t) - options:MTLResourceStorageModeManaged - deallocator:nil]]; + VideoFilter *vfTouch = cdp->GetPixelScalerObject(NDSDisplayID_Touch); + [self setBufCPUFilterSrcTouch:[[sharedData device] newBufferWithBytesNoCopy:vfTouch->GetSrcBufferPtr() + length:vfTouch->GetSrcWidth() * vfTouch->GetSrcHeight() * sizeof(uint32_t) + options:MTLResourceStorageModeManaged + deallocator:nil]]; - [self setBufCPUFilterDstTouch:[[self device] newBufferWithBytesNoCopy:vfTouch->GetDstBufferPtr() - length:vfTouch->GetDstWidth() * vfTouch->GetDstHeight() * sizeof(uint32_t) - options:MTLResourceStorageModeManaged - deallocator:nil]]; + [self setBufCPUFilterDstTouch:[[sharedData device] newBufferWithBytesNoCopy:vfTouch->GetDstBufferPtr() + length:vfTouch->GetDstWidth() * vfTouch->GetDstHeight() * sizeof(uint32_t) + options:MTLResourceStorageModeManaged + deallocator:nil]]; texHUDCharMap = nil; } @@ -1150,17 +1167,17 @@ [cb commit]; [cb waitUntilCompleted]; - VideoFilter *vfMain = _cdv->GetPixelScalerObject(NDSDisplayID_Main); - [self setBufCPUFilterDstMain:[[self device] newBufferWithBytesNoCopy:vfMain->GetDstBufferPtr() - length:(vfMain->GetSrcWidth() * vfAttr.scaleMultiply / vfAttr.scaleDivide) * (vfMain->GetSrcHeight() * vfAttr.scaleMultiply / vfAttr.scaleDivide) * sizeof(uint32_t) - options:MTLResourceStorageModeManaged - deallocator:nil]]; + VideoFilter *vfMain = cdp->GetPixelScalerObject(NDSDisplayID_Main); + [self setBufCPUFilterDstMain:[[sharedData device] newBufferWithBytesNoCopy:vfMain->GetDstBufferPtr() + length:(vfMain->GetSrcWidth() * vfAttr.scaleMultiply / vfAttr.scaleDivide) * (vfMain->GetSrcHeight() * vfAttr.scaleMultiply / vfAttr.scaleDivide) * sizeof(uint32_t) + options:MTLResourceStorageModeManaged + deallocator:nil]]; - VideoFilter *vfTouch = _cdv->GetPixelScalerObject(NDSDisplayID_Touch); - [self setBufCPUFilterDstTouch:[[self device] newBufferWithBytesNoCopy:vfTouch->GetDstBufferPtr() - length:(vfTouch->GetSrcWidth() * vfAttr.scaleMultiply / vfAttr.scaleDivide) * (vfTouch->GetSrcHeight() * vfAttr.scaleMultiply / vfAttr.scaleDivide) * sizeof(uint32_t) - options:MTLResourceStorageModeManaged - deallocator:nil]]; + VideoFilter *vfTouch = cdp->GetPixelScalerObject(NDSDisplayID_Touch); + [self setBufCPUFilterDstTouch:[[sharedData device] newBufferWithBytesNoCopy:vfTouch->GetDstBufferPtr() + length:(vfTouch->GetSrcWidth() * vfAttr.scaleMultiply / vfAttr.scaleDivide) * (vfTouch->GetSrcHeight() * vfAttr.scaleMultiply / vfAttr.scaleDivide) * sizeof(uint32_t) + options:MTLResourceStorageModeManaged + deallocator:nil]]; cb = [self newCommandBuffer]; dummyEncoder = [cb blitCommandEncoder]; @@ -1189,7 +1206,7 @@ [texHUDCharMapDesc setUsage:MTLTextureUsageShaderRead]; [texHUDCharMapDesc setMipmapLevelCount:texLevel]; - [self setTexHUDCharMap:[[self device] newTextureWithDescriptor:texHUDCharMapDesc]]; + [self setTexHUDCharMap:[[sharedData device] newTextureWithDescriptor:texHUDCharMapDesc]]; texLevel = 0; for (size_t tileSize = glyphTileSize, gSize = glyphSize; tileSize >= 4; texLevel++, tileSize >>= 1, gSize = (GLfloat)tileSize * 0.75f) @@ -1268,10 +1285,10 @@ - (void) processDisplays { - const NDSDisplayInfo &fetchDisplayInfo = _cdv->GetEmuDisplayInfo(); - const ClientDisplayMode mode = _cdv->GetViewProperties().mode; - const bool useDeposterize = _cdv->GetSourceDeposterize(); - const NDSDisplayID selectedDisplaySource[2] = { _cdv->GetSelectedDisplaySourceForDisplay(NDSDisplayID_Main), _cdv->GetSelectedDisplaySourceForDisplay(NDSDisplayID_Touch) }; + const NDSDisplayInfo &fetchDisplayInfo = cdp->GetEmuDisplayInfo(); + const ClientDisplayMode mode = cdp->GetPresenterProperties().mode; + const bool useDeposterize = cdp->GetSourceDeposterize(); + const NDSDisplayID selectedDisplaySource[2] = { cdp->GetSelectedDisplaySourceForDisplay(NDSDisplayID_Main), cdp->GetSelectedDisplaySourceForDisplay(NDSDisplayID_Touch) }; pthread_mutex_lock(&_mutexDisplayTextureUpdate); @@ -1293,14 +1310,14 @@ _texDisplayOutput[NDSDisplayID_Touch] = [sharedData texDisplaySrcTargetMain]; } - if ( (fetchDisplayInfo.pixelBytes != 0) && (useDeposterize || (_cdv->GetPixelScaler() != VideoFilterTypeID_None)) ) + if ( (fetchDisplayInfo.pixelBytes != 0) && (useDeposterize || (cdp->GetPixelScaler() != VideoFilterTypeID_None)) ) { - const bool willFilterOnGPU = _cdv->WillFilterOnGPU(); - const bool shouldProcessDisplay[2] = { (!fetchDisplayInfo.didPerformCustomRender[selectedDisplaySource[NDSDisplayID_Main]] || !fetchDisplayInfo.isCustomSizeRequested) && _cdv->IsSelectedDisplayEnabled(NDSDisplayID_Main) && (mode == ClientDisplayMode_Main || mode == ClientDisplayMode_Dual), - (!fetchDisplayInfo.didPerformCustomRender[selectedDisplaySource[NDSDisplayID_Touch]] || !fetchDisplayInfo.isCustomSizeRequested) && _cdv->IsSelectedDisplayEnabled(NDSDisplayID_Touch) && (mode == ClientDisplayMode_Touch || mode == ClientDisplayMode_Dual) && (selectedDisplaySource[NDSDisplayID_Main] != selectedDisplaySource[NDSDisplayID_Touch]) }; + const bool willFilterOnGPU = cdp->WillFilterOnGPU(); + const bool shouldProcessDisplay[2] = { (!fetchDisplayInfo.didPerformCustomRender[selectedDisplaySource[NDSDisplayID_Main]] || !fetchDisplayInfo.isCustomSizeRequested) && cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main) && (mode == ClientDisplayMode_Main || mode == ClientDisplayMode_Dual), + (!fetchDisplayInfo.didPerformCustomRender[selectedDisplaySource[NDSDisplayID_Touch]] || !fetchDisplayInfo.isCustomSizeRequested) && cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch) && (mode == ClientDisplayMode_Touch || mode == ClientDisplayMode_Dual) && (selectedDisplaySource[NDSDisplayID_Main] != selectedDisplaySource[NDSDisplayID_Touch]) }; - VideoFilter *vfMain = _cdv->GetPixelScalerObject(NDSDisplayID_Main); - VideoFilter *vfTouch = _cdv->GetPixelScalerObject(NDSDisplayID_Touch); + VideoFilter *vfMain = cdp->GetPixelScalerObject(NDSDisplayID_Main); + VideoFilter *vfTouch = cdp->GetPixelScalerObject(NDSDisplayID_Touch); id cb = [self newCommandBuffer]; id cce = [cb computeCommandEncoder]; @@ -1342,7 +1359,7 @@ } // Run the pixel scalers. First attempt on the GPU. - if ( (_cdv->GetPixelScaler() != VideoFilterTypeID_None) && willFilterOnGPU ) + if ( (cdp->GetPixelScaler() != VideoFilterTypeID_None) && willFilterOnGPU ) { [cce setComputePipelineState:[self pixelScalePipeline]]; @@ -1370,7 +1387,7 @@ [cce endEncoding]; // If the pixel scaler didn't already run on the GPU, then run the pixel scaler on the CPU. - if ( (_cdv->GetPixelScaler() != VideoFilterTypeID_None) && !willFilterOnGPU ) + if ( (cdp->GetPixelScaler() != VideoFilterTypeID_None) && !willFilterOnGPU ) { id bce = [cb blitCommandEncoder]; @@ -1408,7 +1425,7 @@ } } - pthread_mutex_lock(_cdv->GetMutexProcessPtr()); + pthread_mutex_lock(((MacMetalDisplayPresenter *)cdp)->GetMutexProcessPtr()); if (shouldProcessDisplay[NDSDisplayID_Main]) { @@ -1454,7 +1471,7 @@ _texDisplayOutput[NDSDisplayID_Touch] = [self texDisplayPixelScaleTouch]; } - pthread_mutex_unlock(_cdv->GetMutexProcessPtr()); + pthread_mutex_unlock(((MacMetalDisplayPresenter *)cdp)->GetMutexProcessPtr()); [bce endEncoding]; } @@ -1468,9 +1485,9 @@ } // Update the texture coordinates - _cdv->SetScreenTextureCoordinates((float)[_texDisplayOutput[NDSDisplayID_Main] width], (float)[_texDisplayOutput[NDSDisplayID_Main] height], - (float)[_texDisplayOutput[NDSDisplayID_Touch] width], (float)[_texDisplayOutput[NDSDisplayID_Touch] height], - (float *)[_displayTexCoordBuffer contents]); + cdp->SetScreenTextureCoordinates((float)[_texDisplayOutput[NDSDisplayID_Main] width], (float)[_texDisplayOutput[NDSDisplayID_Main] height], + (float)[_texDisplayOutput[NDSDisplayID_Touch] width], (float)[_texDisplayOutput[NDSDisplayID_Touch] height], + (float *)[_displayTexCoordBuffer contents]); [_displayTexCoordBuffer didModifyRange:NSMakeRange(0, sizeof(float) * (4 * 8))]; pthread_mutex_unlock(&_mutexDisplayTextureUpdate); @@ -1478,7 +1495,7 @@ - (void) updateRenderBuffers { - const NDSDisplayInfo &displayInfo = _cdv->GetEmuDisplayInfo(); + const NDSDisplayInfo &displayInfo = cdp->GetEmuDisplayInfo(); // Set up the view properties. bool didChangeViewProperties = false; @@ -1487,8 +1504,8 @@ MTLViewport newViewport; newViewport.originX = 0.0; newViewport.originY = 0.0; - newViewport.width = _cdv->GetViewProperties().clientWidth; - newViewport.height = _cdv->GetViewProperties().clientHeight; + newViewport.width = cdp->GetPresenterProperties().clientWidth; + newViewport.height = cdp->GetPresenterProperties().clientHeight; newViewport.znear = 0.0; newViewport.zfar = 1.0; @@ -1499,8 +1516,8 @@ needEncodeViewport = true; DisplayViewShaderProperties *viewProps = (DisplayViewShaderProperties *)[_cdvPropertiesBuffer contents]; - viewProps->width = _cdv->GetViewProperties().clientWidth; - viewProps->height = _cdv->GetViewProperties().clientHeight; + viewProps->width = cdp->GetPresenterProperties().clientWidth; + viewProps->height = cdp->GetPresenterProperties().clientHeight; didChangeViewProperties = true; [self setNeedsViewportUpdate:NO]; @@ -1509,9 +1526,9 @@ if ([self needsRotationScaleUpdate]) { DisplayViewShaderProperties *viewProps = (DisplayViewShaderProperties *)[_cdvPropertiesBuffer contents]; - viewProps->rotation = _cdv->GetViewProperties().rotation; - viewProps->viewScale = _cdv->GetViewProperties().viewScale; - viewProps->lowerHUDMipMapLevel = ( ((float)HUD_TEXTBOX_BASE_SCALE * _cdv->GetHUDObjectScale() / _cdv->GetScaleFactor()) >= (2.0/3.0) ) ? 0 : 1; + viewProps->rotation = cdp->GetPresenterProperties().rotation; + viewProps->viewScale = cdp->GetPresenterProperties().viewScale; + viewProps->lowerHUDMipMapLevel = ( ((float)HUD_TEXTBOX_BASE_SCALE * cdp->GetHUDObjectScale() / cdp->GetScaleFactor()) >= (2.0/3.0) ) ? 0 : 1; didChangeViewProperties = true; [self setNeedsRotationScaleUpdate:NO]; @@ -1526,22 +1543,22 @@ bool willDrawDisplays = (displayInfo.pixelBytes != 0); if (willDrawDisplays && [self needsScreenVerticesUpdate]) { - _cdv->SetScreenVertices((float *)[_displayVtxPositionBuffer contents]); + cdp->SetScreenVertices((float *)[_displayVtxPositionBuffer contents]); [_displayVtxPositionBuffer didModifyRange:NSMakeRange(0, sizeof(float) * (4 * 8))]; [self setNeedsScreenVerticesUpdate:NO]; } // Set up the HUD properties. - size_t hudLength = _cdv->GetHUDString().length(); + size_t hudLength = cdp->GetHUDString().length(); size_t hudTouchLineLength = 0; - bool willDrawHUD = _cdv->GetHUDVisibility() && ([self texHUDCharMap] != nil); + bool willDrawHUD = cdp->GetHUDVisibility() && ([self texHUDCharMap] != nil); - if (_cdv->GetHUDShowInput()) + if (cdp->GetHUDShowInput()) { hudLength += HUD_INPUT_ELEMENT_LENGTH; - switch (_cdv->GetMode()) + switch (cdp->GetMode()) { case ClientDisplayMode_Main: case ClientDisplayMode_Touch: @@ -1550,7 +1567,7 @@ case ClientDisplayMode_Dual: { - switch (_cdv->GetLayout()) + switch (cdp->GetLayout()) { case ClientDisplayLayout_Vertical: case ClientDisplayLayout_Horizontal: @@ -1573,33 +1590,33 @@ willDrawHUD = willDrawHUD && (hudLength > 1); - if (willDrawHUD && _cdv->HUDNeedsUpdate()) + if (willDrawHUD && cdp->HUDNeedsUpdate()) { - _cdv->SetHUDPositionVertices((float)_cdv->GetViewProperties().clientWidth, (float)_cdv->GetViewProperties().clientHeight, (float *)[_hudVtxPositionBuffer contents]); + cdp->SetHUDPositionVertices((float)cdp->GetPresenterProperties().clientWidth, (float)cdp->GetPresenterProperties().clientHeight, (float *)[_hudVtxPositionBuffer contents]); [_hudVtxPositionBuffer didModifyRange:NSMakeRange(0, sizeof(float) * hudLength * 8)]; - _cdv->SetHUDColorVertices((uint32_t *)[_hudVtxColorBuffer contents]); + cdp->SetHUDColorVertices((uint32_t *)[_hudVtxColorBuffer contents]); [_hudVtxColorBuffer didModifyRange:NSMakeRange(0, sizeof(uint32_t) * hudLength * 4)]; - _cdv->SetHUDTextureCoordinates((float *)[_hudTexCoordBuffer contents]); + cdp->SetHUDTextureCoordinates((float *)[_hudTexCoordBuffer contents]); [_hudTexCoordBuffer didModifyRange:NSMakeRange(0, sizeof(float) * hudLength * 8)]; - _cdv->ClearHUDNeedsUpdate(); + cdp->ClearHUDNeedsUpdate(); } _needEncodeViewport = needEncodeViewport; _newViewport = newViewport; _willDrawDisplays = willDrawDisplays; _willDrawHUD = willDrawHUD; - _willDrawHUDInput = _cdv->GetHUDShowInput(); - _hudStringLength = _cdv->GetHUDString().length(); + _willDrawHUDInput = cdp->GetHUDShowInput(); + _hudStringLength = cdp->GetHUDString().length(); _hudTouchLineLength = hudTouchLineLength; pthread_mutex_unlock(&_mutexBufferUpdate); } - (void) renderForCommandBuffer:(id)cb - displayPipelineState:(id)displayPipelineState + outputPipelineState:(id)outputPipelineState hudPipelineState:(id)hudPipelineState { id rce = [cb renderCommandEncoderWithDescriptor:_outputRenderPassDesc]; @@ -1612,16 +1629,16 @@ // Draw the NDS displays. if (_willDrawDisplays) { - [rce setRenderPipelineState:displayPipelineState]; + [rce setRenderPipelineState:outputPipelineState]; [rce setVertexBuffer:_displayVtxPositionBuffer offset:0 atIndex:0]; [rce setVertexBuffer:_displayTexCoordBuffer offset:0 atIndex:1]; [rce setVertexBuffer:_cdvPropertiesBuffer offset:0 atIndex:2]; - switch (_cdv->GetViewProperties().mode) + switch (cdp->GetPresenterProperties().mode) { case ClientDisplayMode_Main: { - if (_cdv->IsSelectedDisplayEnabled(NDSDisplayID_Main)) + if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main)) { [rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0]; [rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; @@ -1631,7 +1648,7 @@ case ClientDisplayMode_Touch: { - if (_cdv->IsSelectedDisplayEnabled(NDSDisplayID_Touch)) + if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch)) { [rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0]; [rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4]; @@ -1641,16 +1658,16 @@ case ClientDisplayMode_Dual: { - const NDSDisplayID majorDisplayID = (_cdv->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch; - const size_t majorDisplayVtx = (_cdv->GetViewProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12; + const NDSDisplayID majorDisplayID = (cdp->GetPresenterProperties().order == ClientDisplayOrder_MainFirst) ? NDSDisplayID_Main : NDSDisplayID_Touch; + const size_t majorDisplayVtx = (cdp->GetPresenterProperties().order == ClientDisplayOrder_MainFirst) ? 8 : 12; - switch (_cdv->GetViewProperties().layout) + switch (cdp->GetPresenterProperties().layout) { case ClientDisplayLayout_Hybrid_2_1: case ClientDisplayLayout_Hybrid_16_9: case ClientDisplayLayout_Hybrid_16_10: { - if (_cdv->IsSelectedDisplayEnabled(majorDisplayID)) + if (cdp->IsSelectedDisplayEnabled(majorDisplayID)) { [rce setFragmentTexture:_texDisplayOutput[majorDisplayID] atIndex:0]; [rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:majorDisplayVtx vertexCount:4]; @@ -1662,13 +1679,13 @@ break; } - if (_cdv->IsSelectedDisplayEnabled(NDSDisplayID_Main)) + if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main)) { [rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0]; [rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; } - if (_cdv->IsSelectedDisplayEnabled(NDSDisplayID_Touch)) + if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch)) { [rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0]; [rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4]; @@ -1735,10 +1752,10 @@ [rce endEncoding]; } -- (void) renderAndDownloadToBuffer:(uint32_t *)dstBuffer +- (void) renderToBuffer:(uint32_t *)dstBuffer { - const size_t clientWidth = _cdv->GetViewProperties().clientWidth; - const size_t clientHeight = _cdv->GetViewProperties().clientHeight; + const size_t clientWidth = cdp->GetPresenterProperties().clientWidth; + const size_t clientHeight = cdp->GetPresenterProperties().clientHeight; @autoreleasepool { @@ -1750,8 +1767,8 @@ [texRenderDesc setStorageMode:MTLStorageModePrivate]; [texRenderDesc setUsage:MTLTextureUsageRenderTarget]; - id texRender = [[[self device] newTextureWithDescriptor:texRenderDesc] retain]; - id dstMTLBuffer = [[[self device] newBufferWithLength:clientWidth * clientHeight * sizeof(uint32_t) options:MTLResourceStorageModeManaged] retain]; + id texRender = [[[sharedData device] newTextureWithDescriptor:texRenderDesc] retain]; + id dstMTLBuffer = [[[sharedData device] newBufferWithLength:clientWidth * clientHeight * sizeof(uint32_t) options:MTLResourceStorageModeManaged] retain]; pthread_mutex_lock(&_mutexDisplayTextureUpdate); pthread_mutex_lock(&_mutexBufferUpdate); @@ -1760,7 +1777,7 @@ [colorAttachment0Desc setTexture:texRender]; id cb = [self newCommandBuffer]; - [self renderForCommandBuffer:cb displayPipelineState:[self displayRGBAOutputPipeline] hudPipelineState:[sharedData hudRGBAPipeline]]; + [self renderForCommandBuffer:cb outputPipelineState:[self outputRGBAPipeline] hudPipelineState:[sharedData hudRGBAPipeline]]; id bce = [cb blitCommandEncoder]; @@ -1792,24 +1809,64 @@ } } -- (void) renderAndFlushDrawable +@end + +@implementation DisplayViewMetalLayer + +@synthesize _cdv; +@synthesize presenterObject; + +- (id) initWithDisplayPresenterObject:(MacMetalDisplayPresenterObject *)thePresenterObject +{ + self = [super init]; + if(self == nil) + { + return nil; + } + + _cdv = NULL; + + presenterObject = thePresenterObject; + if (thePresenterObject != nil) + { + [self setDevice:[[thePresenterObject sharedData] device]]; + [thePresenterObject setDrawableFormat:[self pixelFormat]]; + } + + [self setOpaque:YES]; + + return self; +} + +- (void) setupLayer +{ + if ([self device] == nil) + { + [self setDevice:[[presenterObject sharedData] device]]; + [presenterObject setDrawableFormat:[self pixelFormat]]; + } +} + +- (void) renderToDrawable { @autoreleasepool { - pthread_mutex_lock(&_mutexDisplayTextureUpdate); - pthread_mutex_lock(&_mutexBufferUpdate); + pthread_mutex_lock([presenterObject mutexDisplayTextureUpdate]); + pthread_mutex_lock([presenterObject mutexBufferUpdate]); // Now that everything is set up, go ahead and draw everything. id layerDrawable = [self nextDrawable]; - [colorAttachment0Desc setTexture:[layerDrawable texture]]; - id cb = [self newCommandBuffer]; + [[presenterObject colorAttachment0Desc] setTexture:[layerDrawable texture]]; + id cb = [presenterObject newCommandBuffer]; - [self renderForCommandBuffer:cb displayPipelineState:[self displayOutputPipeline] hudPipelineState:[sharedData hudPipeline]]; + [presenterObject renderForCommandBuffer:cb + outputPipelineState:[presenterObject outputDrawablePipeline] + hudPipelineState:[[presenterObject sharedData] hudPipeline]]; [cb presentDrawable:layerDrawable]; [cb addCompletedHandler:^(id block) { - pthread_mutex_unlock(&_mutexBufferUpdate); - pthread_mutex_unlock(&_mutexDisplayTextureUpdate); + pthread_mutex_unlock([presenterObject mutexBufferUpdate]); + pthread_mutex_unlock([presenterObject mutexDisplayTextureUpdate]); }]; [cb commit]; @@ -1922,22 +1979,187 @@ void MacMetalFetchObject::_FetchCustomDisplayByID(const NDSDisplayID displayID, #pragma mark - -MacMetalDisplayView::MacMetalDisplayView() +MacMetalDisplayPresenter::MacMetalDisplayPresenter() +{ + __InstanceInit(nil); +} + +MacMetalDisplayPresenter::MacMetalDisplayPresenter(MacClientSharedObject *sharedObject) : MacDisplayPresenterInterface(sharedObject) +{ + __InstanceInit(sharedObject); +} + +MacMetalDisplayPresenter::~MacMetalDisplayPresenter() +{ + [this->_presenterObject release]; + + pthread_mutex_destroy(&this->_mutexProcessPtr); +} + +void MacMetalDisplayPresenter::__InstanceInit(MacClientSharedObject *sharedObject) { - _allowViewUpdates = false; _canFilterOnGPU = true; _filtersPreferGPU = true; _willFilterOnGPU = true; - _spinlockViewNeedsFlush = OS_SPINLOCK_INIT; - _mutexProcessPtr = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); - pthread_mutex_init(_mutexProcessPtr, NULL); + if (sharedObject != nil) + { + SetFetchObject([sharedObject GPUFetchObject]); + } + + _presenterObject = [[MacMetalDisplayPresenterObject alloc] initWithDisplayPresenter:this]; + + pthread_mutex_init(&_mutexProcessPtr, NULL); +} + +void MacMetalDisplayPresenter::_UpdateNormalSize() +{ + [this->_presenterObject setNeedsScreenVerticesUpdate:YES]; +} + +void MacMetalDisplayPresenter::_UpdateOrder() +{ + [this->_presenterObject setNeedsScreenVerticesUpdate:YES]; +} + +void MacMetalDisplayPresenter::_UpdateRotation() +{ + [this->_presenterObject setNeedsRotationScaleUpdate:YES]; +} + +void MacMetalDisplayPresenter::_UpdateClientSize() +{ + [this->_presenterObject setNeedsViewportUpdate:YES]; + [this->_presenterObject setNeedsHUDVerticesUpdate:YES]; + this->ClientDisplay3DPresenter::_UpdateClientSize(); +} + +void MacMetalDisplayPresenter::_UpdateViewScale() +{ + this->ClientDisplay3DPresenter::_UpdateViewScale(); + [this->_presenterObject setNeedsRotationScaleUpdate:YES]; +} + +void MacMetalDisplayPresenter::_LoadNativeDisplayByID(const NDSDisplayID displayID) +{ + if ((this->GetPixelScaler() != VideoFilterTypeID_None) && !this->WillFilterOnGPU() && !this->GetSourceDeposterize()) + { + MacMetalFetchObject &fetchObjMutable = (MacMetalFetchObject &)this->GetFetchObject(); + VideoFilter *vf = this->GetPixelScalerObject(displayID); + + fetchObjMutable.CopyFromSrcClone(vf->GetSrcBufferPtr(), displayID, this->GetEmuDisplayInfo().bufferIndex); + } +} + +void MacMetalDisplayPresenter::_ResizeCPUPixelScaler(const VideoFilterTypeID filterID) +{ + this->ClientDisplay3DPresenter::_ResizeCPUPixelScaler(filterID); + [this->_presenterObject resizeCPUPixelScalerUsingFilterID:filterID]; +} + +MacMetalDisplayPresenterObject* MacMetalDisplayPresenter::GetPresenterObject() const +{ + return this->_presenterObject; +} + +pthread_mutex_t* MacMetalDisplayPresenter::GetMutexProcessPtr() +{ + return &this->_mutexProcessPtr; +} + +void MacMetalDisplayPresenter::Init() +{ + [this->_presenterObject setup]; +} + +void MacMetalDisplayPresenter::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo) +{ + [this->_presenterObject copyHUDFontUsingFace:fontFace size:glyphSize tileSize:glyphTileSize info:glyphInfo]; +} + +void MacMetalDisplayPresenter::SetSharedData(MacClientSharedObject *sharedObject) +{ + [this->_presenterObject setSharedData:(MetalDisplayViewSharedData *)sharedObject]; + this->SetFetchObject([sharedObject GPUFetchObject]); +} + +// NDS screen filters +void MacMetalDisplayPresenter::SetPixelScaler(const VideoFilterTypeID filterID) +{ + pthread_mutex_lock(&this->_mutexProcessPtr); + + this->ClientDisplay3DPresenter::SetPixelScaler(filterID); + [this->_presenterObject setPixelScaler:this->_pixelScaler]; + this->_willFilterOnGPU = (this->GetFiltersPreferGPU()) ? ([this->_presenterObject pixelScalePipeline] != nil) : false; + + pthread_mutex_unlock(&this->_mutexProcessPtr); +} + +void MacMetalDisplayPresenter::SetOutputFilter(const OutputFilterTypeID filterID) +{ + this->ClientDisplay3DPresenter::SetOutputFilter(filterID); + [this->_presenterObject setOutputFilter:filterID]; +} + +void MacMetalDisplayPresenter::SetFiltersPreferGPU(const bool preferGPU) +{ + pthread_mutex_lock(&this->_mutexProcessPtr); + + this->_filtersPreferGPU = preferGPU; + this->_willFilterOnGPU = (preferGPU) ? ([this->_presenterObject pixelScalePipeline] != nil) : false; + + pthread_mutex_unlock(&this->_mutexProcessPtr); +} + +// NDS GPU interface +void MacMetalDisplayPresenter::ProcessDisplays() +{ + [this->_presenterObject processDisplays]; +} + +void MacMetalDisplayPresenter::UpdateLayout() +{ + [this->_presenterObject updateRenderBuffers]; +} + +void MacMetalDisplayPresenter::CopyFrameToBuffer(uint32_t *dstBuffer) +{ + [this->_presenterObject renderToBuffer:dstBuffer]; +} + +#pragma mark - + +MacMetalDisplayView::MacMetalDisplayView() +{ + __InstanceInit(nil); +} + +MacMetalDisplayView::MacMetalDisplayView(MacClientSharedObject *sharedObject) +{ + __InstanceInit(sharedObject); } MacMetalDisplayView::~MacMetalDisplayView() { - pthread_mutex_destroy(this->_mutexProcessPtr); - free(this->_mutexProcessPtr); + [this->_caLayer release]; +} + +void MacMetalDisplayView::__InstanceInit(MacClientSharedObject *sharedObject) +{ + _allowViewUpdates = false; + _spinlockViewNeedsFlush = OS_SPINLOCK_INIT; + + MacMetalDisplayPresenter *newMetalPresenter = new MacMetalDisplayPresenter(sharedObject); + _presenter = newMetalPresenter; + + _caLayer = [[DisplayViewMetalLayer alloc] initWithDisplayPresenterObject:newMetalPresenter->GetPresenterObject()]; + [_caLayer setClientDisplayView:this]; +} + +void MacMetalDisplayView::Init() +{ + [(DisplayViewMetalLayer *)this->_caLayer setupLayer]; + MacDisplayLayeredView::Init(); } bool MacMetalDisplayView::GetViewNeedsFlush() @@ -1949,114 +2171,9 @@ bool MacMetalDisplayView::GetViewNeedsFlush() return viewNeedsFlush; } -void MacMetalDisplayView::SetAllowViewFlushes(bool allowFlushes) +void MacMetalDisplayView::SetViewNeedsFlush() { - CGDirectDisplayID displayID = (CGDirectDisplayID)this->GetDisplayViewID(); - MacClientSharedObject *sharedData = this->GetSharedData(); - - if (![sharedData isDisplayLinkRunningUsingID:displayID]) - { - [sharedData displayLinkStartUsingID:displayID]; - } -} - -void MacMetalDisplayView::_UpdateNormalSize() -{ - [(DisplayViewMetalLayer *)this->GetFrontendLayer() setNeedsScreenVerticesUpdate:YES]; -} - -void MacMetalDisplayView::_UpdateOrder() -{ - [(DisplayViewMetalLayer *)this->GetFrontendLayer() setNeedsScreenVerticesUpdate:YES]; -} - -void MacMetalDisplayView::_UpdateRotation() -{ - [(DisplayViewMetalLayer *)this->GetFrontendLayer() setNeedsRotationScaleUpdate:YES]; -} - -void MacMetalDisplayView::_UpdateClientSize() -{ - [(DisplayViewMetalLayer *)this->GetFrontendLayer() setNeedsViewportUpdate:YES]; - [(DisplayViewMetalLayer *)this->GetFrontendLayer() setNeedsHUDVerticesUpdate:YES]; - this->ClientDisplay3DView::_UpdateClientSize(); -} - -void MacMetalDisplayView::_UpdateViewScale() -{ - this->ClientDisplay3DView::_UpdateViewScale(); - [(DisplayViewMetalLayer *)this->GetFrontendLayer() setNeedsRotationScaleUpdate:YES]; -} - -void MacMetalDisplayView::_LoadNativeDisplayByID(const NDSDisplayID displayID) -{ - if ((this->GetPixelScaler() != VideoFilterTypeID_None) && !this->WillFilterOnGPU() && !this->GetSourceDeposterize()) - { - MacMetalFetchObject &fetchObjMutable = (MacMetalFetchObject &)this->GetFetchObject(); - VideoFilter *vf = this->GetPixelScalerObject(displayID); - - fetchObjMutable.CopyFromSrcClone(vf->GetSrcBufferPtr(), displayID, this->GetEmuDisplayInfo().bufferIndex); - } -} - -void MacMetalDisplayView::_ResizeCPUPixelScaler(const VideoFilterTypeID filterID) -{ - this->ClientDisplay3DView::_ResizeCPUPixelScaler(filterID); - [(DisplayViewMetalLayer *)this->GetFrontendLayer() resizeCPUPixelScalerUsingFilterID:filterID]; -} - -pthread_mutex_t* MacMetalDisplayView::GetMutexProcessPtr() const -{ - return this->_mutexProcessPtr; -} - -void MacMetalDisplayView::Init() -{ - [(DisplayViewMetalLayer *)this->GetFrontendLayer() setupLayer]; -} - -void MacMetalDisplayView::CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo) -{ - [(DisplayViewMetalLayer *)this->GetFrontendLayer() copyHUDFontUsingFace:fontFace size:glyphSize tileSize:glyphTileSize info:glyphInfo]; -} - -// NDS screen filters -void MacMetalDisplayView::SetPixelScaler(const VideoFilterTypeID filterID) -{ - pthread_mutex_lock(this->_mutexProcessPtr); - - this->ClientDisplay3DView::SetPixelScaler(filterID); - [(DisplayViewMetalLayer *)this->GetFrontendLayer() setPixelScaler:this->_pixelScaler]; - this->_willFilterOnGPU = (this->GetFiltersPreferGPU()) ? ([(DisplayViewMetalLayer *)this->GetFrontendLayer() pixelScalePipeline] != nil) : false; - - pthread_mutex_unlock(this->_mutexProcessPtr); -} - -void MacMetalDisplayView::SetOutputFilter(const OutputFilterTypeID filterID) -{ - this->ClientDisplay3DView::SetOutputFilter(filterID); - [(DisplayViewMetalLayer *)this->GetFrontendLayer() setOutputFilter:filterID]; -} - -void MacMetalDisplayView::SetFiltersPreferGPU(const bool preferGPU) -{ - pthread_mutex_lock(this->_mutexProcessPtr); - - this->_filtersPreferGPU = preferGPU; - this->_willFilterOnGPU = (preferGPU) ? ([(DisplayViewMetalLayer *)this->GetFrontendLayer() pixelScalePipeline] != nil) : false; - - pthread_mutex_unlock(this->_mutexProcessPtr); -} - -// NDS GPU interface -void MacMetalDisplayView::ProcessDisplays() -{ - [(DisplayViewMetalLayer *)this->GetFrontendLayer() processDisplays]; -} - -void MacMetalDisplayView::UpdateView() -{ - if (!this->_allowViewUpdates || (this->GetNSView() == nil)) + if (!this->_allowViewUpdates || (this->_presenter == nil) || (this->GetNSView() == nil)) { return; } @@ -2065,25 +2182,31 @@ void MacMetalDisplayView::UpdateView() // will eventually get flushed. this->SetAllowViewFlushes(true); - [(DisplayViewMetalLayer *)this->GetFrontendLayer() updateRenderBuffers]; + this->_presenter->UpdateLayout(); OSSpinLockLock(&this->_spinlockViewNeedsFlush); this->_viewNeedsFlush = true; OSSpinLockUnlock(&this->_spinlockViewNeedsFlush); } +void MacMetalDisplayView::SetAllowViewFlushes(bool allowFlushes) +{ + CGDirectDisplayID displayID = (CGDirectDisplayID)this->GetDisplayViewID(); + MacClientSharedObject *sharedData = ((MacMetalDisplayPresenter *)this->_presenter)->GetSharedData(); + + if (![sharedData isDisplayLinkRunningUsingID:displayID]) + { + [sharedData displayLinkStartUsingID:displayID]; + } +} + void MacMetalDisplayView::FlushView() { OSSpinLockLock(&this->_spinlockViewNeedsFlush); this->_viewNeedsFlush = false; OSSpinLockUnlock(&this->_spinlockViewNeedsFlush); - [(DisplayViewMetalLayer *)this->GetFrontendLayer() renderAndFlushDrawable]; -} - -void MacMetalDisplayView::CopyFrameToBuffer(uint32_t *dstBuffer) -{ - [(DisplayViewMetalLayer *)this->GetFrontendLayer() renderAndDownloadToBuffer:dstBuffer]; + [(DisplayViewMetalLayer *)this->_caLayer renderToDrawable]; } #pragma mark - diff --git a/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.h b/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.h index 43be41273..7db875a55 100644 --- a/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.h +++ b/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.h @@ -39,8 +39,9 @@ class MacOGLDisplayView; @interface DisplayViewOpenGLLayer : CAOpenGLLayer { - MacOGLDisplayView *_cdv; + MacDisplayLayeredView *_cdv; } + @end class MacOGLClientFetchObject : public OGLClientFetchObject @@ -61,19 +62,21 @@ public: virtual void FetchFromBufferIndex(const u8 index); }; -class MacOGLDisplayView : public OGLVideoOutput, public DisplayViewCALayerInterface +class MacOGLDisplayPresenter : public OGLVideoOutput, public MacDisplayPresenterInterface { +private: + void __InstanceInit(MacClientSharedObject *sharedObject); + protected: NSOpenGLContext *_nsContext; NSOpenGLPixelFormat *_nsPixelFormat; CGLContextObj _context; CGLPixelFormatObj _pixelFormat; - OSSpinLock _spinlockViewNeedsFlush; - public: void operator delete(void *ptr); - MacOGLDisplayView(); + MacOGLDisplayPresenter(); + MacOGLDisplayPresenter(MacClientSharedObject *sharedObject); virtual void Init(); @@ -82,12 +85,7 @@ public: CGLPixelFormatObj GetPixelFormat() const; CGLContextObj GetContext() const; - virtual bool GetViewNeedsFlush(); - virtual void SetAllowViewFlushes(bool allowFlushes); - virtual void LoadHUDFont(); - - virtual void SetUseVerticalSync(const bool useVerticalSync); virtual void SetScaleFactor(const double scaleFactor); // NDS screen filters @@ -98,12 +96,34 @@ public: // Client view interface virtual void LoadDisplays(); virtual void ProcessDisplays(); - virtual void UpdateView(); - virtual void FlushView(); virtual void CopyFrameToBuffer(uint32_t *dstBuffer); virtual void FinishFrameAtIndex(const uint8_t bufferIndex); virtual void LockDisplayTextures(); virtual void UnlockDisplayTextures(); }; +class MacOGLDisplayView : public MacDisplayLayeredView +{ +private: + void __InstanceInit(MacClientSharedObject *sharedObject); + +protected: + OSSpinLock _spinlockViewNeedsFlush; + +public: + MacOGLDisplayView(); + MacOGLDisplayView(MacClientSharedObject *sharedObject); + virtual ~MacOGLDisplayView(); + + virtual bool GetViewNeedsFlush(); + virtual void SetViewNeedsFlush(); + + virtual void SetAllowViewFlushes(bool allowFlushes); + + virtual void SetUseVerticalSync(const bool useVerticalSync); + + // Client view interface + virtual void FlushView(); +}; + #endif // _MAC_OGLDISPLAYOUTPUT_H_ diff --git a/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.mm b/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.mm index d8ca89faf..0a497f162 100644 --- a/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.mm +++ b/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.mm @@ -21,6 +21,8 @@ @implementation DisplayViewOpenGLLayer +@synthesize _cdv; + - (id)init { self = [super init]; @@ -29,8 +31,7 @@ return nil; } - _cdv = new MacOGLDisplayView(); - _cdv->SetFrontendLayer(self); + _cdv = NULL; [self setBounds:CGRectMake(0.0f, 0.0f, (float)GPU_FRAMEBUFFER_NATIVE_WIDTH, (float)GPU_FRAMEBUFFER_NATIVE_HEIGHT)]; [self setAsynchronous:NO]; @@ -39,21 +40,9 @@ return self; } -- (void)dealloc -{ - delete _cdv; - - [super dealloc]; -} - - (OGLContextInfo *) contextInfo { - return _cdv->GetContextInfo(); -} - -- (ClientDisplay3DView *)clientDisplay3DView -{ - return _cdv; + return ((MacOGLDisplayPresenter *)(_cdv->Get3DPresenter()))->GetContextInfo(); } - (BOOL)isAsynchronous @@ -63,19 +52,19 @@ - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask { - return _cdv->GetPixelFormat(); + return ((MacOGLDisplayPresenter *)(_cdv->Get3DPresenter()))->GetPixelFormat(); } - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat { - return _cdv->GetContext(); + return ((MacOGLDisplayPresenter *)(_cdv->Get3DPresenter()))->GetContext(); } - (void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp { CGLSetCurrentContext(glContext); CGLLockContext(glContext); - _cdv->RenderFrameOGL(false); + ((MacOGLDisplayPresenter *)(_cdv->Get3DPresenter()))->RenderFrameOGL(false); [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp]; CGLUnlockContext(glContext); } @@ -214,18 +203,18 @@ void MacOGLClientFetchObject::FetchFromBufferIndex(const u8 index) #pragma mark - -void MacOGLDisplayView::operator delete(void *ptr) +void MacOGLDisplayPresenter::operator delete(void *ptr) { - CGLContextObj context = ((MacOGLDisplayView *)ptr)->GetContext(); + CGLContextObj context = ((MacOGLDisplayPresenter *)ptr)->GetContext(); if (context != NULL) { - OGLContextInfo *contextInfo = ((MacOGLDisplayView *)ptr)->GetContextInfo(); + OGLContextInfo *contextInfo = ((MacOGLDisplayPresenter *)ptr)->GetContextInfo(); CGLContextObj prevContext = CGLGetCurrentContext(); CGLSetCurrentContext(context); - [((MacOGLDisplayView *)ptr)->GetNSContext() release]; - [((MacOGLDisplayView *)ptr)->GetNSPixelFormat() release]; + [((MacOGLDisplayPresenter *)ptr)->GetNSContext() release]; + [((MacOGLDisplayPresenter *)ptr)->GetNSPixelFormat() release]; delete contextInfo; ::operator delete(ptr); @@ -233,7 +222,17 @@ void MacOGLDisplayView::operator delete(void *ptr) } } -MacOGLDisplayView::MacOGLDisplayView() +MacOGLDisplayPresenter::MacOGLDisplayPresenter() +{ + __InstanceInit(nil); +} + +MacOGLDisplayPresenter::MacOGLDisplayPresenter(MacClientSharedObject *sharedObject) : MacDisplayPresenterInterface(sharedObject) +{ + __InstanceInit(sharedObject); +} + +void MacOGLDisplayPresenter::__InstanceInit(MacClientSharedObject *sharedObject) { // Initialize the OpenGL context. // @@ -241,7 +240,6 @@ MacOGLDisplayView::MacOGLDisplayView() // [NSOpenGLContext CGLContextObj] is available on macOS 10.5 Leopard, but // [NSOpenGLContext initWithCGLContextObj:] is only available on macOS 10.6 // Snow Leopard. - bool useContext_3_2 = false; NSOpenGLPixelFormatAttribute attributes[] = { NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24, NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8, @@ -255,7 +253,7 @@ MacOGLDisplayView::MacOGLDisplayView() #ifdef _OGLDISPLAYOUTPUT_3_2_H_ // If we can support a 3.2 Core Profile context, then request that in our // pixel format attributes. - useContext_3_2 = IsOSXVersionSupported(10, 7, 0); + bool useContext_3_2 = IsOSXVersionSupported(10, 7, 0); if (useContext_3_2) { attributes[9] = NSOpenGLPFAOpenGLProfile; @@ -277,11 +275,14 @@ MacOGLDisplayView::MacOGLDisplayView() _nsContext = nil; _context = nil; - _allowViewUpdates = false; - _spinlockViewNeedsFlush = OS_SPINLOCK_INIT; + + if (sharedObject != nil) + { + SetFetchObject([sharedObject GPUFetchObject]); + } } -void MacOGLDisplayView::Init() +void MacOGLDisplayPresenter::Init() { this->_nsContext = [[NSOpenGLContext alloc] initWithFormat:this->_nsPixelFormat shareContext:((MacOGLClientFetchObject *)this->_fetchObject)->GetNSContext()]; @@ -308,26 +309,146 @@ void MacOGLDisplayView::Init() CGLSetCurrentContext(prevContext); } -NSOpenGLPixelFormat* MacOGLDisplayView::GetNSPixelFormat() const +NSOpenGLPixelFormat* MacOGLDisplayPresenter::GetNSPixelFormat() const { return this->_nsPixelFormat; } -NSOpenGLContext* MacOGLDisplayView::GetNSContext() const +NSOpenGLContext* MacOGLDisplayPresenter::GetNSContext() const { return this->_nsContext; } -CGLPixelFormatObj MacOGLDisplayView::GetPixelFormat() const +CGLPixelFormatObj MacOGLDisplayPresenter::GetPixelFormat() const { return this->_pixelFormat; } -CGLContextObj MacOGLDisplayView::GetContext() const +CGLContextObj MacOGLDisplayPresenter::GetContext() const { return this->_context; } +void MacOGLDisplayPresenter::LoadHUDFont() +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::LoadHUDFont(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayPresenter::SetScaleFactor(const double scaleFactor) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetScaleFactor(scaleFactor); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayPresenter::SetFiltersPreferGPU(const bool preferGPU) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetFiltersPreferGPU(preferGPU); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayPresenter::SetOutputFilter(const OutputFilterTypeID filterID) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetOutputFilter(filterID); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayPresenter::SetPixelScaler(const VideoFilterTypeID filterID) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::SetPixelScaler(filterID); + CGLUnlockContext(this->_context); +} + +// NDS GPU Interface +void MacOGLDisplayPresenter::LoadDisplays() +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::LoadDisplays(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayPresenter::ProcessDisplays() +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::ProcessDisplays(); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayPresenter::CopyFrameToBuffer(uint32_t *dstBuffer) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::CopyFrameToBuffer(dstBuffer); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayPresenter::FinishFrameAtIndex(const uint8_t bufferIndex) +{ + CGLLockContext(this->_context); + CGLSetCurrentContext(this->_context); + this->OGLVideoOutput::FinishFrameAtIndex(bufferIndex); + CGLUnlockContext(this->_context); +} + +void MacOGLDisplayPresenter::LockDisplayTextures() +{ + const GPUClientFetchObject &fetchObj = this->GetFetchObject(); + const u8 bufferIndex = this->_emuDisplayInfo.bufferIndex; + MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)fetchObj.GetClientData(); + + pthread_rwlock_rdlock([sharedViewObject rwlockFramebufferAtIndex:bufferIndex]); +} + +void MacOGLDisplayPresenter::UnlockDisplayTextures() +{ + const GPUClientFetchObject &fetchObj = this->GetFetchObject(); + const u8 bufferIndex = this->_emuDisplayInfo.bufferIndex; + MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)fetchObj.GetClientData(); + + pthread_rwlock_unlock([sharedViewObject rwlockFramebufferAtIndex:bufferIndex]); +} + +#pragma mark - + +MacOGLDisplayView::MacOGLDisplayView() +{ + __InstanceInit(nil); +} + +MacOGLDisplayView::MacOGLDisplayView(MacClientSharedObject *sharedObject) +{ + __InstanceInit(sharedObject); +} + +MacOGLDisplayView::~MacOGLDisplayView() +{ + [this->_caLayer release]; +} + +void MacOGLDisplayView::__InstanceInit(MacClientSharedObject *sharedObject) +{ + _allowViewUpdates = false; + _spinlockViewNeedsFlush = OS_SPINLOCK_INIT; + + MacOGLDisplayPresenter *newOpenGLPresenter = new MacOGLDisplayPresenter(sharedObject); + _presenter = newOpenGLPresenter; + + _caLayer = [[DisplayViewOpenGLLayer alloc] init]; + [_caLayer setClientDisplayView:this]; +} + bool MacOGLDisplayView::GetViewNeedsFlush() { OSSpinLockLock(&this->_spinlockViewNeedsFlush); @@ -337,88 +458,9 @@ bool MacOGLDisplayView::GetViewNeedsFlush() return viewNeedsFlush; } -void MacOGLDisplayView::SetAllowViewFlushes(bool allowFlushes) +void MacOGLDisplayView::SetViewNeedsFlush() { - CGDirectDisplayID displayID = (CGDirectDisplayID)this->GetDisplayViewID(); - MacClientSharedObject *sharedData = this->GetSharedData(); - - if (![sharedData isDisplayLinkRunningUsingID:displayID]) - { - [sharedData displayLinkStartUsingID:displayID]; - } -} - -void MacOGLDisplayView::LoadHUDFont() -{ - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->OGLVideoOutput::LoadHUDFont(); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::SetUseVerticalSync(const bool useVerticalSync) -{ - const GLint swapInt = (useVerticalSync) ? 1 : 0; - - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - CGLSetParameter(this->_context, kCGLCPSwapInterval, &swapInt); - this->OGLVideoOutput::SetUseVerticalSync(useVerticalSync); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::SetScaleFactor(const double scaleFactor) -{ - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->OGLVideoOutput::SetScaleFactor(scaleFactor); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::SetFiltersPreferGPU(const bool preferGPU) -{ - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->OGLVideoOutput::SetFiltersPreferGPU(preferGPU); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::SetOutputFilter(const OutputFilterTypeID filterID) -{ - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->OGLVideoOutput::SetOutputFilter(filterID); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::SetPixelScaler(const VideoFilterTypeID filterID) -{ - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->OGLVideoOutput::SetPixelScaler(filterID); - CGLUnlockContext(this->_context); -} - -// NDS GPU Interface -void MacOGLDisplayView::LoadDisplays() -{ - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->OGLVideoOutput::LoadDisplays(); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::ProcessDisplays() -{ - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->OGLVideoOutput::ProcessDisplays(); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::UpdateView() -{ - if (!this->_allowViewUpdates || (this->GetNSView() == nil)) + if (!this->_allowViewUpdates || (this->_presenter == nil) || (this->GetNSView() == nil)) { return; } @@ -439,49 +481,40 @@ void MacOGLDisplayView::UpdateView() } } +void MacOGLDisplayView::SetAllowViewFlushes(bool allowFlushes) +{ + CGDirectDisplayID displayID = (CGDirectDisplayID)this->GetDisplayViewID(); + MacClientSharedObject *sharedData = ((MacOGLDisplayPresenter *)this->_presenter)->GetSharedData(); + + if (![sharedData isDisplayLinkRunningUsingID:displayID]) + { + [sharedData displayLinkStartUsingID:displayID]; + } +} + +void MacOGLDisplayView::SetUseVerticalSync(const bool useVerticalSync) +{ + CGLContextObj context = ((MacOGLDisplayPresenter *)this->_presenter)->GetContext(); + const GLint swapInt = (useVerticalSync) ? 1 : 0; + + CGLLockContext(context); + CGLSetCurrentContext(context); + CGLSetParameter(context, kCGLCPSwapInterval, &swapInt); + MacDisplayLayeredView::SetUseVerticalSync(useVerticalSync); + CGLUnlockContext(context); +} + void MacOGLDisplayView::FlushView() { OSSpinLockLock(&this->_spinlockViewNeedsFlush); this->_viewNeedsFlush = false; OSSpinLockUnlock(&this->_spinlockViewNeedsFlush); - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->RenderFrameOGL(false); - CGLFlushDrawable(this->_context); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::CopyFrameToBuffer(uint32_t *dstBuffer) -{ - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->OGLVideoOutput::CopyFrameToBuffer(dstBuffer); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::FinishFrameAtIndex(const uint8_t bufferIndex) -{ - CGLLockContext(this->_context); - CGLSetCurrentContext(this->_context); - this->OGLVideoOutput::FinishFrameAtIndex(bufferIndex); - CGLUnlockContext(this->_context); -} - -void MacOGLDisplayView::LockDisplayTextures() -{ - const GPUClientFetchObject &fetchObj = this->GetFetchObject(); - const u8 bufferIndex = this->_emuDisplayInfo.bufferIndex; - MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)fetchObj.GetClientData(); + CGLContextObj context = ((MacOGLDisplayPresenter *)this->_presenter)->GetContext(); - pthread_rwlock_rdlock([sharedViewObject rwlockFramebufferAtIndex:bufferIndex]); -} - -void MacOGLDisplayView::UnlockDisplayTextures() -{ - const GPUClientFetchObject &fetchObj = this->GetFetchObject(); - const u8 bufferIndex = this->_emuDisplayInfo.bufferIndex; - MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)fetchObj.GetClientData(); - - pthread_rwlock_unlock([sharedViewObject rwlockFramebufferAtIndex:bufferIndex]); + CGLLockContext(context); + CGLSetCurrentContext(context); + ((MacOGLDisplayPresenter *)this->_presenter)->RenderFrameOGL(false); + CGLFlushDrawable(context); + CGLUnlockContext(context); } diff --git a/desmume/src/frontend/cocoa/userinterface/MacScreenshotCaptureTool.h b/desmume/src/frontend/cocoa/userinterface/MacScreenshotCaptureTool.h new file mode 100644 index 000000000..e01d81076 --- /dev/null +++ b/desmume/src/frontend/cocoa/userinterface/MacScreenshotCaptureTool.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 2017 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . + */ + +#ifndef _MAC_SCREENSHOTCAPTURETOOL_H_ +#define _MAC_SCREENSHOTCAPTURETOOL_H_ + +#import + +#include +#include "../ClientDisplayView.h" + +#ifdef BOOL +#undef BOOL +#endif + +@class MacClientSharedObject; + +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 +@interface MacScreenshotCaptureToolDelegate : NSObject +#else +@interface MacScreenshotCaptureToolDelegate : NSObject +#endif +{ + NSWindow *window; + + MacClientSharedObject *sharedData; + + NSString *saveDirectoryPath; + NSString *romName; + NSBitmapFormat fileFormat; + NSInteger displayMode; + NSInteger displayLayout; + NSInteger displayOrder; + NSInteger displaySeparation; + NSInteger displayRotation; + BOOL useDeposterize; + NSInteger outputFilterID; + NSInteger pixelScalerID; +} + +@property (readonly) IBOutlet NSWindow *window; + +@property (retain) MacClientSharedObject *sharedData; + +@property (copy) NSString *saveDirectoryPath; +@property (copy) NSString *romName; +@property (assign) NSBitmapFormat fileFormat; +@property (assign) NSInteger displayMode; +@property (assign) NSInteger displayLayout; +@property (assign) NSInteger displayOrder; +@property (assign) NSInteger displaySeparation; +@property (assign) NSInteger displayRotation; +@property (assign) BOOL useDeposterize; +@property (assign) NSInteger outputFilterID; +@property (assign) NSInteger pixelScalerID; + +- (IBAction) chooseDirectoryPath:(id)sender; +- (IBAction) takeScreenshot:(id)sender; + +- (void) chooseDirectoryPathDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; + +- (void) readUserDefaults; +- (void) writeUserDefaults; + +@end + +class MacScreenshotCaptureToolParams +{ +public: + MacClientSharedObject *sharedData; + + NSBitmapImageFileType fileFormat; + std::string savePath; + std::string romName; + bool useDeposterize; + OutputFilterTypeID outputFilterID; + VideoFilterTypeID pixelScalerID; + ClientDisplayPresenterProperties cdpProperty; +}; + +static void* RunFileWriteThread(void *arg); + +#endif // _MAC_SCREENSHOTCAPTURETOOL_H_ diff --git a/desmume/src/frontend/cocoa/userinterface/MacScreenshotCaptureTool.mm b/desmume/src/frontend/cocoa/userinterface/MacScreenshotCaptureTool.mm new file mode 100644 index 000000000..493a17160 --- /dev/null +++ b/desmume/src/frontend/cocoa/userinterface/MacScreenshotCaptureTool.mm @@ -0,0 +1,346 @@ +/* + Copyright (C) 2017 DeSmuME team + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the this software. If not, see . + */ + +#include + +#import "../cocoa_file.h" +#import "../cocoa_GPU.h" +#import "../cocoa_globals.h" +#import "MacScreenshotCaptureTool.h" +#import "MacOGLDisplayView.h" + +#ifdef ENABLE_APPLE_METAL +#include "MacMetalDisplayView.h" +#endif + +@implementation MacScreenshotCaptureToolDelegate + +@synthesize window; +@synthesize sharedData; +@synthesize saveDirectoryPath; +@synthesize romName; +@synthesize fileFormat; +@synthesize displayMode; +@synthesize displayLayout; +@synthesize displayOrder; +@synthesize displaySeparation; +@synthesize displayRotation; +@synthesize useDeposterize; +@synthesize outputFilterID; +@synthesize pixelScalerID; + +- (id)init +{ + self = [super init]; + if(self == nil) + { + return nil; + } + + sharedData = nil; + saveDirectoryPath = nil; + romName = @"No_ROM_loaded"; + + return self; +} + +- (void)dealloc +{ + [self setSharedData:nil]; + [self setSaveDirectoryPath:nil]; + [self setRomName:nil]; + + [super dealloc]; +} + +- (IBAction) chooseDirectoryPath:(id)sender +{ + NSOpenPanel *panel = [NSOpenPanel openPanel]; + [panel setCanCreateDirectories:YES]; + [panel setCanChooseDirectories:YES]; + [panel setCanChooseFiles:NO]; + [panel setResolvesAliases:YES]; + [panel setAllowsMultipleSelection:NO]; + [panel setTitle:NSSTRING_TITLE_SAVE_SCREENSHOT_PANEL]; + +#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 + [panel beginSheetModalForWindow:[self window] + completionHandler:^(NSInteger result) { + [self chooseDirectoryPathDidEnd:panel returnCode:result contextInfo:nil]; + } ]; +#else + [panel beginSheetForDirectory:nil + file:nil + types:nil + modalForWindow:[self window] + modalDelegate:self + didEndSelector:@selector(chooseDirectoryPathDidEnd:returnCode:contextInfo:) + contextInfo:nil]; +#endif +} + +- (IBAction) takeScreenshot:(id)sender +{ + NSString *savePath = [self saveDirectoryPath]; + + if ( (savePath != nil) && ([savePath length] > 0) ) + { + savePath = [savePath stringByExpandingTildeInPath]; + } + else + { + [self chooseDirectoryPath:self]; + } + + NSFileManager *fileManager = [[NSFileManager alloc] init]; + BOOL isDirectoryFound = [fileManager createDirectoryAtPath:savePath withIntermediateDirectories:YES attributes:nil error:nil]; + [fileManager release]; + + if (!isDirectoryFound) + { + [self chooseDirectoryPath:self]; + + isDirectoryFound = [fileManager createDirectoryAtPath:savePath withIntermediateDirectories:YES attributes:nil error:nil]; + if (!isDirectoryFound) + { + // This was the last chance for the user to try to get a working writable directory. + // If the directory is still invalid, then just bail. + return; + } + } + + // Note: We're allocating the parameter's memory block here, but we will be freeing it once we copy it in the detached thread. + MacScreenshotCaptureToolParams *param = new MacScreenshotCaptureToolParams; + param->sharedData = [self sharedData]; + param->fileFormat = (NSBitmapImageFileType)[self fileFormat]; + param->savePath = std::string([savePath cStringUsingEncoding:NSUTF8StringEncoding]); + param->romName = std::string([romName cStringUsingEncoding:NSUTF8StringEncoding]); + param->useDeposterize = [self useDeposterize] ? true : false; + param->outputFilterID = (OutputFilterTypeID)[self outputFilterID]; + param->pixelScalerID = (VideoFilterTypeID)[self pixelScalerID]; + + param->cdpProperty.mode = (ClientDisplayMode)[self displayMode]; + param->cdpProperty.layout = (ClientDisplayLayout)[self displayLayout]; + param->cdpProperty.order = (ClientDisplayOrder)[self displayOrder]; + param->cdpProperty.gapScale = (float)[self displaySeparation] / 100.0f; + param->cdpProperty.rotation = (float)[self displayRotation]; + + pthread_t fileWriteThread; + pthread_attr_t fileWriteThreadAttr; + + pthread_attr_init(&fileWriteThreadAttr); + pthread_attr_setdetachstate(&fileWriteThreadAttr, PTHREAD_CREATE_DETACHED); + pthread_create(&fileWriteThread, &fileWriteThreadAttr, &RunFileWriteThread, param); + pthread_attr_destroy(&fileWriteThreadAttr); +} + +- (void) chooseDirectoryPathDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + [sheet orderOut:self]; + + if (returnCode == NSCancelButton) + { + return; + } + + NSURL *selectedFileURL = [[sheet URLs] lastObject]; //hopefully also the first object + if(selectedFileURL == nil) + { + return; + } + + [self setSaveDirectoryPath:[selectedFileURL path]]; +} + +- (void) readUserDefaults +{ + [self setSaveDirectoryPath:[[NSUserDefaults standardUserDefaults] stringForKey:@"ScreenshotCaptureTool_DirectoryPath"]]; + [self setFileFormat:[[NSUserDefaults standardUserDefaults] integerForKey:@"ScreenshotCaptureTool_FileFormat"]]; + [self setUseDeposterize:[[NSUserDefaults standardUserDefaults] boolForKey:@"ScreenshotCaptureTool_Deposterize"]]; + [self setOutputFilterID:[[NSUserDefaults standardUserDefaults] integerForKey:@"ScreenshotCaptureTool_OutputFilter"]]; + [self setPixelScalerID:[[NSUserDefaults standardUserDefaults] integerForKey:@"ScreenshotCaptureTool_PixelScaler"]]; + [self setDisplayMode:[[NSUserDefaults standardUserDefaults] integerForKey:@"ScreenshotCaptureTool_DisplayMode"]]; + [self setDisplayLayout:[[NSUserDefaults standardUserDefaults] integerForKey:@"ScreenshotCaptureTool_DisplayLayout"]]; + [self setDisplayOrder:[[NSUserDefaults standardUserDefaults] integerForKey:@"ScreenshotCaptureTool_DisplayOrder"]]; + [self setDisplaySeparation:[[NSUserDefaults standardUserDefaults] integerForKey:@"ScreenshotCaptureTool_DisplaySeparation"]]; + [self setDisplayRotation:[[NSUserDefaults standardUserDefaults] integerForKey:@"ScreenshotCaptureTool_DisplayRotation"]]; +} + +- (void) writeUserDefaults +{ + [[NSUserDefaults standardUserDefaults] setObject:[self saveDirectoryPath] forKey:@"ScreenshotCaptureTool_DirectoryPath"]; + [[NSUserDefaults standardUserDefaults] setInteger:[self fileFormat] forKey:@"ScreenshotCaptureTool_FileFormat"]; + [[NSUserDefaults standardUserDefaults] setBool:[self useDeposterize] forKey:@"ScreenshotCaptureTool_Deposterize"]; + [[NSUserDefaults standardUserDefaults] setInteger:[self outputFilterID] forKey:@"ScreenshotCaptureTool_OutputFilter"]; + [[NSUserDefaults standardUserDefaults] setInteger:[self pixelScalerID] forKey:@"ScreenshotCaptureTool_PixelScaler"]; + [[NSUserDefaults standardUserDefaults] setInteger:[self displayMode] forKey:@"ScreenshotCaptureTool_DisplayMode"]; + [[NSUserDefaults standardUserDefaults] setInteger:[self displayLayout] forKey:@"ScreenshotCaptureTool_DisplayLayout"]; + [[NSUserDefaults standardUserDefaults] setInteger:[self displayOrder] forKey:@"ScreenshotCaptureTool_DisplayOrder"]; + [[NSUserDefaults standardUserDefaults] setInteger:[self displaySeparation] forKey:@"ScreenshotCaptureTool_DisplaySeparation"]; + [[NSUserDefaults standardUserDefaults] setInteger:[self displayRotation] forKey:@"ScreenshotCaptureTool_DisplayRotation"]; +} + +@end + +static void* RunFileWriteThread(void *arg) +{ + // Copy the rendering properties from the calling thread. + MacScreenshotCaptureToolParams *inParams = (MacScreenshotCaptureToolParams *)arg; + MacScreenshotCaptureToolParams param; + + param.sharedData = inParams->sharedData; + param.fileFormat = inParams->fileFormat; + param.savePath = inParams->savePath; + param.romName = inParams->romName; + param.useDeposterize = inParams->useDeposterize; + param.outputFilterID = inParams->outputFilterID; + param.pixelScalerID = inParams->pixelScalerID; + + param.cdpProperty.mode = inParams->cdpProperty.mode; + param.cdpProperty.layout = inParams->cdpProperty.layout; + param.cdpProperty.order = inParams->cdpProperty.order; + param.cdpProperty.gapScale = inParams->cdpProperty.gapScale; + param.cdpProperty.rotation = inParams->cdpProperty.rotation; + + delete inParams; + inParams = NULL; + + // Do a few sanity checks before proceeding. + if (param.sharedData == nil) + { + return NULL; + } + + GPUClientFetchObject *fetchObject = [param.sharedData GPUFetchObject]; + if (fetchObject == NULL) + { + return NULL; + } + + const NDSDisplayInfo &displayInfo = fetchObject->GetFetchDisplayInfoForBufferIndex( fetchObject->GetLastFetchIndex() ); + + if ( (displayInfo.renderedWidth[NDSDisplayID_Main] == 0) || (displayInfo.renderedHeight[NDSDisplayID_Main] == 0) || + (displayInfo.renderedWidth[NDSDisplayID_Touch] == 0) || (displayInfo.renderedHeight[NDSDisplayID_Touch] == 0) ) + { + return NULL; + } + + // Set up the rendering properties. + ClientDisplayPresenter::CalculateNormalSize(param.cdpProperty.mode, param.cdpProperty.layout, param.cdpProperty.gapScale, param.cdpProperty.normalWidth, param.cdpProperty.normalHeight); + double transformedWidth = param.cdpProperty.normalWidth; + double transformedHeight = param.cdpProperty.normalHeight; + + param.cdpProperty.viewScale = (double)displayInfo.customWidth / (double)GPU_FRAMEBUFFER_NATIVE_WIDTH; + ClientDisplayPresenter::ConvertNormalToTransformedBounds(param.cdpProperty.viewScale, param.cdpProperty.rotation, transformedWidth, transformedHeight); + + param.cdpProperty.clientWidth = transformedWidth; + param.cdpProperty.clientHeight = transformedHeight; + param.cdpProperty.gapDistance = (double)DS_DISPLAY_UNSCALED_GAP * param.cdpProperty.gapScale; + + // Render the frame to an NSBitmapImageRep. + NSAutoreleasePool *autoreleasePool = [[NSAutoreleasePool alloc] init]; + + NSUInteger w = param.cdpProperty.clientWidth; + NSUInteger h = param.cdpProperty.clientHeight; + + NSBitmapImageRep *newImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL + pixelsWide:w + pixelsHigh:h + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSCalibratedRGBColorSpace + bytesPerRow:w * 4 + bitsPerPixel:32]; + if (newImageRep == nil) + { + [autoreleasePool release]; + return NULL; + } + + ClientDisplay3DPresenter *cdp = NULL; + bool filtersPreferGPU = true; + +#ifdef ENABLE_APPLE_METAL + if ([param.sharedData isKindOfClass:[MetalDisplayViewSharedData class]]) + { + if ([(MetalDisplayViewSharedData *)param.sharedData device] == nil) + { + [newImageRep release]; + [autoreleasePool release]; + return NULL; + } + + cdp = new MacMetalDisplayPresenter(param.sharedData); + } + else +#endif + { + cdp = new MacOGLDisplayPresenter(param.sharedData); + filtersPreferGPU = false; // Just in case we're capturing the screenshot on an older GPU, perform the filtering on the CPU to avoid potential issues. + } + + cdp->Init(); + cdp->SetFiltersPreferGPU(filtersPreferGPU); + cdp->SetHUDVisibility(false); + cdp->CommitPresenterProperties(param.cdpProperty); + cdp->SetupPresenterProperties(); + cdp->SetSourceDeposterize(param.useDeposterize); + + if ( (cdp->GetViewScale() > 0.999) && (cdp->GetViewScale() < 1.001) ) + { + // Special case stuff for when capturing the screenshot at the native resolution. + if ( (param.cdpProperty.layout == ClientDisplayLayout_Vertical) || (param.cdpProperty.layout == ClientDisplayLayout_Horizontal) ) + { + cdp->SetOutputFilter(OutputFilterTypeID_NearestNeighbor); + } + else + { + cdp->SetOutputFilter(param.outputFilterID); + } + } + else + { + // For custom-sized resolutions, apply all the filters as normal. + cdp->SetPixelScaler(param.pixelScalerID); + cdp->SetOutputFilter(param.outputFilterID); + } + + cdp->LoadDisplays(); + cdp->ProcessDisplays(); + cdp->UpdateLayout(); + cdp->CopyFrameToBuffer((uint32_t *)[newImageRep bitmapData]); + + // Write the file. + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"yyyyMMdd_HH-mm-ss.SSS "]; + NSString *fileName = [[dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:[NSString stringWithCString:param.romName.c_str() encoding:NSUTF8StringEncoding]]; + [dateFormatter release]; + + NSString *savePath = [NSString stringWithCString:param.savePath.c_str() encoding:NSUTF8StringEncoding]; + NSURL *fileURL = [NSURL fileURLWithPath:[savePath stringByAppendingPathComponent:fileName]]; + [CocoaDSFile saveScreenshot:fileURL bitmapData:newImageRep fileType:param.fileFormat]; + + // Clean up. + delete cdp; + + [newImageRep release]; + [autoreleasePool release]; + + return NULL; +} diff --git a/desmume/src/frontend/cocoa/userinterface/appDelegate.h b/desmume/src/frontend/cocoa/userinterface/appDelegate.h index 70f298030..a4fa6e126 100644 --- a/desmume/src/frontend/cocoa/userinterface/appDelegate.h +++ b/desmume/src/frontend/cocoa/userinterface/appDelegate.h @@ -19,9 +19,7 @@ #import @class InputPrefsView; -@class InputManager; @class FileMigrationDelegate; -@class RomInfoPanel; #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 @@ -34,21 +32,12 @@ NSObjectController *aboutWindowController; NSObjectController *emuControlController; - NSObjectController *cdsSoundController; - NSObjectController *romInfoPanelController; NSObjectController *prefWindowController; - NSObjectController *cheatWindowController; NSObjectController *cdsCoreController; - NSArrayController *inputDeviceListController; FileMigrationDelegate *migrationDelegate; - InputManager *inputManager; - RomInfoPanel *romInfoPanel; NSWindow *prefWindow; NSWindow *troubleshootingWindow; - NSWindow *cheatListWindow; - NSWindow *slot2Window; - NSView *prefGeneralView; InputPrefsView *inputPrefsView; NSMenu *mLoadStateSlot; @@ -62,23 +51,14 @@ @property (readonly) IBOutlet NSObjectController *aboutWindowController; @property (readonly) IBOutlet NSObjectController *emuControlController; -@property (readonly) IBOutlet NSObjectController *cdsSoundController; -@property (readonly) IBOutlet NSObjectController *romInfoPanelController; @property (readonly) IBOutlet NSObjectController *prefWindowController; -@property (readonly) IBOutlet NSObjectController *cheatWindowController; @property (readonly) IBOutlet NSObjectController *cdsCoreController; -@property (readonly) IBOutlet NSArrayController *inputDeviceListController; @property (readonly) IBOutlet FileMigrationDelegate *migrationDelegate; -@property (readonly) IBOutlet InputManager *inputManager; @property (readonly) IBOutlet NSWindow *prefWindow; @property (readonly) IBOutlet NSWindow *troubleshootingWindow; -@property (readonly) IBOutlet NSWindow *cheatListWindow; -@property (readonly) IBOutlet NSWindow *slot2Window; -@property (readonly) IBOutlet NSView *prefGeneralView; @property (readonly) IBOutlet NSMenu *mLoadStateSlot; @property (readonly) IBOutlet NSMenu *mSaveStateSlot; @property (readonly) IBOutlet InputPrefsView *inputPrefsView; -@property (readonly) IBOutlet RomInfoPanel *romInfoPanel; @property (assign) BOOL isAppRunningOnIntel; @property (assign) BOOL isDeveloperPlusBuild; @@ -91,7 +71,5 @@ - (void) setupSlotMenuItems; - (NSMenuItem *) addSlotMenuItem:(NSMenu *)menu slotNumber:(NSUInteger)slotNumber; - (void) setupUserDefaults; -- (void) restoreDisplayWindowStates; -- (void) saveDisplayWindowStates; @end diff --git a/desmume/src/frontend/cocoa/userinterface/appDelegate.mm b/desmume/src/frontend/cocoa/userinterface/appDelegate.mm index a7475d1b6..fac9832ce 100644 --- a/desmume/src/frontend/cocoa/userinterface/appDelegate.mm +++ b/desmume/src/frontend/cocoa/userinterface/appDelegate.mm @@ -20,8 +20,6 @@ #import "DisplayWindowController.h" #import "EmuControllerDelegate.h" #import "FileMigrationDelegate.h" -#import "RomInfoPanel.h" -#import "Slot2WindowDelegate.h" #import "preferencesWindowDelegate.h" #import "troubleshootingWindowDelegate.h" #import "cheatWindowDelegate.h" @@ -43,23 +41,14 @@ @dynamic dummyObject; @synthesize prefWindow; @synthesize troubleshootingWindow; -@synthesize cheatListWindow; -@synthesize slot2Window; -@synthesize prefGeneralView; @synthesize mLoadStateSlot; @synthesize mSaveStateSlot; @synthesize inputPrefsView; @synthesize aboutWindowController; @synthesize emuControlController; -@synthesize cdsSoundController; -@synthesize romInfoPanelController; @synthesize prefWindowController; @synthesize cdsCoreController; -@synthesize inputDeviceListController; -@synthesize cheatWindowController; @synthesize migrationDelegate; -@synthesize inputManager; -@synthesize romInfoPanel; @synthesize isAppRunningOnIntel; @synthesize isDeveloperPlusBuild; @@ -136,8 +125,6 @@ EmuControllerDelegate *emuControl = (EmuControllerDelegate *)[emuControlController content]; PreferencesWindowDelegate *prefWindowDelegate = (PreferencesWindowDelegate *)[prefWindow delegate]; - CheatWindowDelegate *cheatWindowDelegate = (CheatWindowDelegate *)[cheatListWindow delegate]; - Slot2WindowDelegate *slot2WindowDelegate = (Slot2WindowDelegate *)[slot2Window delegate]; // Create the needed directories in Application Support if they haven't already // been created. @@ -149,6 +136,14 @@ [CocoaDSFile setupAllFilePaths]; + // On macOS v10.13 and later, some unwanted menu items will show up in the View menu. + // Disable automatic window tabbing for all NSWindows in order to rid ourselves of + // these unwanted menu items. + if ([[NSWindow class] respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)]) + { + [NSWindow setAllowsAutomaticWindowTabbing:NO]; + } + // Setup the About window. NSString *descriptionStr = [[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"] stringByAppendingString:@" "] stringByAppendingString:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]]; descriptionStr = [[descriptionStr stringByAppendingString:@"\n"] stringByAppendingString:@STRING_DESMUME_SHORT_DESCRIPTION]; @@ -193,16 +188,11 @@ [newCore addOutput:newSpeaker]; [emuControl setCdsSpeaker:newSpeaker]; - // Update the SLOT-2 device list after the emulation core is initialized. - [slot2WindowDelegate update]; - [slot2WindowDelegate setHidManager:[inputManager hidManager]]; - [slot2WindowDelegate setAutoSelectedDeviceText:[[slot2WindowDelegate deviceManager] autoSelectedDeviceName]]; - // Set up all the object controllers. [cdsCoreController setContent:newCore]; - [romInfoPanelController setContent:[CocoaDSRom romNotLoadedBindings]]; [prefWindowController setContent:[prefWindowDelegate bindings]]; - [cheatWindowController setContent:[cheatWindowDelegate bindings]]; + + [emuControl appInit]; } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification @@ -241,7 +231,7 @@ // Bring the application to the front [NSApp activateIgnoringOtherApps:YES]; - [self restoreDisplayWindowStates]; + [emuControl restoreDisplayWindowStates]; // Load a new ROM on launch per user preferences. if ([[NSUserDefaults standardUserDefaults] objectForKey:@"General_AutoloadROMOnLaunch"] != nil) @@ -337,8 +327,9 @@ CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; // Save some settings to user defaults before app termination - [self saveDisplayWindowStates]; - [romInfoPanel writeDefaults]; + [emuControl saveDisplayWindowStates]; + [emuControl writeUserDefaults]; + [[NSUserDefaults standardUserDefaults] setBool:[[cdsCore cdsController] hardwareMicMute] forKey:@"Microphone_HardwareMicMute"]; [[NSUserDefaults standardUserDefaults] setDouble:[emuControl currentVolumeValue] forKey:@"Sound_Volume"]; [[NSUserDefaults standardUserDefaults] setDouble:[emuControl lastSetSpeedScalar] forKey:@"CoreControl_SpeedScalar"]; @@ -428,7 +419,6 @@ { EmuControllerDelegate *emuControl = (EmuControllerDelegate *)[emuControlController content]; PreferencesWindowDelegate *prefWindowDelegate = [prefWindow delegate]; - Slot2WindowDelegate *slot2WindowDelegate = (Slot2WindowDelegate *)[slot2Window delegate]; CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; // Set the emulation flags. @@ -520,244 +510,11 @@ [cdsCore setGdbStubPortARM7:0]; #endif - // Set up the user's default input settings. - NSDictionary *userMappings = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"Input_ControllerMappings"]; - if (userMappings == nil) - { - NSDictionary *defaultKeyMappingsDict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"DefaultKeyMappings" ofType:@"plist"]]; - NSArray *internalDefaultProfilesList = (NSArray *)[defaultKeyMappingsDict valueForKey:@"DefaultInputProfiles"]; - userMappings = [(NSDictionary *)[internalDefaultProfilesList objectAtIndex:0] valueForKey:@"Mappings"]; - } - - [inputManager setMappingsWithMappings:userMappings]; - [[inputManager hidManager] setDeviceListController:inputDeviceListController]; - - // Set up the ROM Info panel. - [romInfoPanel setupUserDefaults]; + // Set up the rest of the emulation-related user defaults. + [emuControl readUserDefaults]; // Set up the preferences window. [prefWindowDelegate setupUserDefaults]; - - // Set up the default SLOT-2 device. - [slot2WindowDelegate setupUserDefaults]; - - // Set up the rest of the emulation-related user defaults. - [emuControl setupUserDefaults]; -} - -- (void) restoreDisplayWindowStates -{ - EmuControllerDelegate *emuControl = (EmuControllerDelegate *)[emuControlController content]; - NSArray *windowPropertiesList = [[NSUserDefaults standardUserDefaults] arrayForKey:@"General_DisplayWindowRestorableStates"]; - const BOOL willRestoreWindows = [[NSUserDefaults standardUserDefaults] boolForKey:@"General_WillRestoreDisplayWindows"]; - - if (!willRestoreWindows || windowPropertiesList == nil || [windowPropertiesList count] < 1) - { - // If no windows were saved for restoring (the user probably closed all windows before - // app termination), then simply create a new display window per user defaults. - [emuControl newDisplayWindow:self]; - } - else - { - for (NSDictionary *windowProperties in windowPropertiesList) - { - DisplayWindowController *windowController = [[DisplayWindowController alloc] initWithWindowNibName:@"DisplayWindow" emuControlDelegate:emuControl]; - - if (windowController == nil) - { - continue; - } - - const NSInteger displayMode = ([windowProperties objectForKey:@"displayMode"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayMode"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_Mode"]; - const double displayScale = ([windowProperties objectForKey:@"displayScale"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayScale"] doubleValue] : ([[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayView_Size"] / 100.0); - const double displayRotation = ([windowProperties objectForKey:@"displayRotation"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayRotation"] doubleValue] : [[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayView_Rotation"]; - const NSInteger displayOrientation = ([windowProperties objectForKey:@"displayOrientation"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayOrientation"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Orientation"]; - const NSInteger displayOrder = ([windowProperties objectForKey:@"displayOrder"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayOrder"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Order"]; - const double displayGap = ([windowProperties objectForKey:@"displayGap"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayGap"] doubleValue] : ([[NSUserDefaults standardUserDefaults] doubleForKey:@"DisplayViewCombo_Gap"] / 100.0); - - const NSInteger displayMainSource = ([windowProperties objectForKey:@"displayMainVideoSource"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayMainVideoSource"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_DisplayMainVideoSource"]; - const NSInteger displayTouchSource = ([windowProperties objectForKey:@"displayTouchVideoSource"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"displayTouchVideoSource"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_DisplayTouchVideoSource"]; - - const BOOL videoFiltersPreferGPU = ([windowProperties objectForKey:@"videoFiltersPreferGPU"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"videoFiltersPreferGPU"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_FiltersPreferGPU"]; - const BOOL videoSourceDeposterize = ([windowProperties objectForKey:@"videoSourceDeposterize"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"videoSourceDeposterize"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_Deposterize"]; - const NSInteger videoPixelScaler = ([windowProperties objectForKey:@"videoFilterType"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"videoFilterType"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_VideoFilter"]; - const NSInteger videoOutputFilter = ([windowProperties objectForKey:@"videoOutputFilter"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"videoOutputFilter"] integerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_OutputFilter"]; - - const BOOL hudEnable = ([windowProperties objectForKey:@"hudEnable"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudEnable"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_EnableHUD"]; - const BOOL hudShowVideoFPS = ([windowProperties objectForKey:@"hudShowVideoFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowVideoFPS"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowVideoFPS"]; - const BOOL hudShowRender3DFPS = ([windowProperties objectForKey:@"hudShowRender3DFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowRender3DFPS"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowRender3DFPS"]; - const BOOL hudShowFrameIndex = ([windowProperties objectForKey:@"hudShowFrameIndex"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowFrameIndex"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowFrameIndex"]; - const BOOL hudShowLagFrameCount = ([windowProperties objectForKey:@"hudShowLagFrameCount"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowLagFrameCount"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowLagFrameCount"]; - const BOOL hudShowCPULoadAverage = ([windowProperties objectForKey:@"hudShowCPULoadAverage"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowCPULoadAverage"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowCPULoadAverage"]; - const BOOL hudShowRTC = ([windowProperties objectForKey:@"hudShowRTC"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowRTC"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowRTC"]; - const BOOL hudShowInput = ([windowProperties objectForKey:@"hudShowInput"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudShowInput"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"HUD_ShowInput"]; - - const NSUInteger hudColorVideoFPS = ([windowProperties objectForKey:@"hudColorVideoFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorVideoFPS"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_VideoFPS"]; - const NSUInteger hudColorRender3DFPS = ([windowProperties objectForKey:@"hudColorRender3DFPS"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorRender3DFPS"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Render3DFPS"]; - const NSUInteger hudColorFrameIndex = ([windowProperties objectForKey:@"hudColorFrameIndex"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorFrameIndex"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_FrameIndex"]; - const NSUInteger hudColorLagFrameCount = ([windowProperties objectForKey:@"hudColorLagFrameCount"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorLagFrameCount"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_LagFrameCount"]; - const NSUInteger hudColorCPULoadAverage = ([windowProperties objectForKey:@"hudColorCPULoadAverage"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorCPULoadAverage"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_CPULoadAverage"]; - const NSUInteger hudColorRTC = ([windowProperties objectForKey:@"hudColorRTC"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorRTC"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_RTC"]; - const NSUInteger hudColorInputPendingAndApplied = ([windowProperties objectForKey:@"hudColorInputPendingAndApplied"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorInputPendingAndApplied"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Input_PendingAndApplied"]; - const NSUInteger hudColorInputAppliedOnly = ([windowProperties objectForKey:@"hudColorInputAppliedOnly"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorInputAppliedOnly"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Input_AppliedOnly"]; - const NSUInteger hudColorInputPendingOnly = ([windowProperties objectForKey:@"hudColorInputPendingOnly"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"hudColorInputPendingOnly"] unsignedIntegerValue] : [[NSUserDefaults standardUserDefaults] integerForKey:@"HUD_Color_Input_PendingOnly"]; - - const NSInteger screenshotFileFormat = ([windowProperties objectForKey:@"screenshotFileFormat"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"screenshotFileFormat"] integerValue] : NSTIFFFileType; - const BOOL useVerticalSync = ([windowProperties objectForKey:@"useVerticalSync"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"useVerticalSync"] boolValue] : YES; - const BOOL isMinSizeNormal = ([windowProperties objectForKey:@"isMinSizeNormal"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"isMinSizeNormal"] boolValue] : YES; - const BOOL isShowingStatusBar = ([windowProperties objectForKey:@"isShowingStatusBar"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"isShowingStatusBar"] boolValue] : [[NSUserDefaults standardUserDefaults] boolForKey:@"DisplayView_ShowStatusBar"]; - const BOOL isInFullScreenMode = ([windowProperties objectForKey:@"isInFullScreenMode"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"isInFullScreenMode"] boolValue] : NO; - const NSUInteger screenIndex = ([windowProperties objectForKey:@"screenIndex"] != nil) ? [(NSNumber *)[windowProperties valueForKey:@"screenIndex"] unsignedIntegerValue] : 0; - NSString *windowFrameStr = (NSString *)[windowProperties valueForKey:@"windowFrame"]; - - int frameX = 0; - int frameY = 0; - int frameWidth = 256; - int frameHeight = 192*2; - const char *frameCStr = [windowFrameStr cStringUsingEncoding:NSUTF8StringEncoding]; - sscanf(frameCStr, "%i %i %i %i", &frameX, &frameY, &frameWidth, &frameHeight); - - // Force the window to load now so that we can overwrite its internal defaults with the user's defaults. - [windowController window]; - - [windowController setDisplayMode:(ClientDisplayMode)displayMode - viewScale:displayScale - rotation:displayRotation - layout:(ClientDisplayLayout)displayOrientation - order:(ClientDisplayOrder)displayOrder - gapScale:displayGap - isMinSizeNormal:isMinSizeNormal - isShowingStatusBar:isShowingStatusBar]; - - [[windowController view] setDisplayMainVideoSource:displayMainSource]; - [[windowController view] setDisplayTouchVideoSource:displayTouchSource]; - - [windowController setVideoPropertiesWithoutUpdateUsingPreferGPU:videoFiltersPreferGPU - sourceDeposterize:videoSourceDeposterize - outputFilter:videoOutputFilter - pixelScaler:videoPixelScaler]; - - [windowController setScreenshotFileFormat:screenshotFileFormat]; - [[windowController view] setUseVerticalSync:useVerticalSync]; - [[windowController view] setIsHUDVisible:hudEnable]; - [[windowController view] setIsHUDVideoFPSVisible:hudShowVideoFPS]; - [[windowController view] setIsHUDRender3DFPSVisible:hudShowRender3DFPS]; - [[windowController view] setIsHUDFrameIndexVisible:hudShowFrameIndex]; - [[windowController view] setIsHUDLagFrameCountVisible:hudShowLagFrameCount]; - [[windowController view] setIsHUDCPULoadAverageVisible:hudShowCPULoadAverage]; - [[windowController view] setIsHUDRealTimeClockVisible:hudShowRTC]; - [[windowController view] setIsHUDInputVisible:hudShowInput]; - - [[windowController view] setHudColorVideoFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorVideoFPS]]; - [[windowController view] setHudColorRender3DFPS:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorRender3DFPS]]; - [[windowController view] setHudColorFrameIndex:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorFrameIndex]]; - [[windowController view] setHudColorLagFrameCount:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorLagFrameCount]]; - [[windowController view] setHudColorCPULoadAverage:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorCPULoadAverage]]; - [[windowController view] setHudColorRTC:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorRTC]]; - [[windowController view] setHudColorInputPendingAndApplied:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorInputPendingAndApplied]]; - [[windowController view] setHudColorInputAppliedOnly:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorInputAppliedOnly]]; - [[windowController view] setHudColorInputPendingOnly:[CocoaDSUtil NSColorFromRGBA8888:(uint32_t)hudColorInputPendingOnly]]; - - [[windowController masterWindow] setFrameOrigin:NSMakePoint(frameX, frameY)]; - - // If this is the last window in the list, make this window key and main. - // Otherwise, just order the window to the front so that the windows will - // stack in a deterministic order. - [[windowController view] setAllowViewUpdates:YES]; - [[[windowController view] cdsVideoOutput] handleReloadReprocessRedraw]; - - if (windowProperties == [windowPropertiesList lastObject]) - { - [[windowController window] makeKeyAndOrderFront:self]; - [[windowController window] makeMainWindow]; - } - else - { - [[windowController window] orderFront:self]; - } - - // If this window is set to full screen mode, its associated screen index must - // exist. If not, this window will not enter full screen mode. This is necessary, - // since the user's screen configuration could change in between app launches, - // and since we don't want a window to go full screen on the wrong screen. - if (isInFullScreenMode && - ([[NSScreen screens] indexOfObject:[[windowController window] screen]] == screenIndex)) - { - [windowController toggleFullScreenDisplay:self]; - } - } - } -} - -- (void) saveDisplayWindowStates -{ - EmuControllerDelegate *emuControl = (EmuControllerDelegate *)[emuControlController content]; - NSArray *windowList = [emuControl windowList]; - const BOOL willRestoreWindows = [[NSUserDefaults standardUserDefaults] boolForKey:@"General_WillRestoreDisplayWindows"]; - - if (willRestoreWindows && [windowList count] > 0) - { - NSMutableArray *windowPropertiesList = [NSMutableArray arrayWithCapacity:[windowList count]]; - - for (DisplayWindowController *windowController in windowList) - { - const NSUInteger screenIndex = [[NSScreen screens] indexOfObject:[[windowController masterWindow] screen]]; - - const NSRect windowFrame = [windowController masterWindowFrame]; - NSString *windowFrameStr = [NSString stringWithFormat:@"%i %i %i %i", - (int)windowFrame.origin.x, (int)windowFrame.origin.y, (int)windowFrame.size.width, (int)windowFrame.size.height]; - - NSDictionary *windowProperties = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInteger:[windowController displayMode]], @"displayMode", - [NSNumber numberWithDouble:[windowController masterWindowScale]], @"displayScale", - [NSNumber numberWithDouble:[windowController displayRotation]], @"displayRotation", - [NSNumber numberWithInteger:[[windowController view] displayMainVideoSource]], @"displayMainVideoSource", - [NSNumber numberWithInteger:[[windowController view] displayTouchVideoSource]], @"displayTouchVideoSource", - [NSNumber numberWithInteger:[windowController displayOrientation]], @"displayOrientation", - [NSNumber numberWithInteger:[windowController displayOrder]], @"displayOrder", - [NSNumber numberWithDouble:[windowController displayGap]], @"displayGap", - [NSNumber numberWithBool:[[windowController view] videoFiltersPreferGPU]], @"videoFiltersPreferGPU", - [NSNumber numberWithInteger:[[windowController view] pixelScaler]], @"videoFilterType", - [NSNumber numberWithInteger:[windowController screenshotFileFormat]], @"screenshotFileFormat", - [NSNumber numberWithInteger:[[windowController view] outputFilter]], @"videoOutputFilter", - [NSNumber numberWithBool:[[windowController view] sourceDeposterize]], @"videoSourceDeposterize", - [NSNumber numberWithBool:[[windowController view] useVerticalSync]], @"useVerticalSync", - [NSNumber numberWithBool:[[windowController view] isHUDVisible]], @"hudEnable", - [NSNumber numberWithBool:[[windowController view] isHUDVideoFPSVisible]], @"hudShowVideoFPS", - [NSNumber numberWithBool:[[windowController view] isHUDRender3DFPSVisible]], @"hudShowRender3DFPS", - [NSNumber numberWithBool:[[windowController view] isHUDFrameIndexVisible]], @"hudShowFrameIndex", - [NSNumber numberWithBool:[[windowController view] isHUDLagFrameCountVisible]], @"hudShowLagFrameCount", - [NSNumber numberWithBool:[[windowController view] isHUDCPULoadAverageVisible]], @"hudShowCPULoadAverage", - [NSNumber numberWithBool:[[windowController view] isHUDRealTimeClockVisible]], @"hudShowRTC", - [NSNumber numberWithBool:[[windowController view] isHUDInputVisible]], @"hudShowInput", - [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorVideoFPS]]], @"hudColorVideoFPS", - [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorRender3DFPS]]], @"hudColorRender3DFPS", - [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorFrameIndex]]], @"hudColorFrameIndex", - [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorLagFrameCount]]], @"hudColorLagFrameCount", - [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorCPULoadAverage]]], @"hudColorCPULoadAverage", - [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorRTC]]], @"hudColorRTC", - [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorInputPendingAndApplied]]], @"hudColorInputPendingAndApplied", - [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorInputAppliedOnly]]], @"hudColorInputAppliedOnly", - [NSNumber numberWithUnsignedInteger:[CocoaDSUtil RGBA8888FromNSColor:[[windowController view] hudColorInputPendingOnly]]], @"hudColorInputPendingOnly", - [NSNumber numberWithBool:[windowController isMinSizeNormal]], @"isMinSizeNormal", - [NSNumber numberWithBool:[windowController masterStatusBarState]], @"isShowingStatusBar", - [NSNumber numberWithBool:[windowController isFullScreen]], @"isInFullScreenMode", - [NSNumber numberWithUnsignedInteger:screenIndex], @"screenIndex", - windowFrameStr, @"windowFrame", - nil]; - - // TODO: Show HUD Input. - //[NSNumber numberWithBool:[[windowController view] isHUDInputVisible]], @"hudShowInput", - - [windowPropertiesList addObject:windowProperties]; - } - - [[NSUserDefaults standardUserDefaults] setObject:windowPropertiesList forKey:@"General_DisplayWindowRestorableStates"]; - } - else - { - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"General_DisplayWindowRestorableStates"]; - } } @end