From 0e42f772bc72ce13d4acd36b3953d438c2a7c498 Mon Sep 17 00:00:00 2001 From: rogerman Date: Fri, 29 Apr 2022 12:04:49 -0700 Subject: [PATCH] Cocoa Port: Refactor a few things. --- .../src/frontend/cocoa/ClientDisplayView.cpp | 92 +++++++------- .../src/frontend/cocoa/ClientDisplayView.h | 4 +- .../frontend/cocoa/ClientExecutionControl.cpp | 118 ++++++++++-------- .../frontend/cocoa/ClientExecutionControl.h | 2 + .../src/frontend/cocoa/OGLDisplayOutput.cpp | 8 +- desmume/src/frontend/cocoa/cocoa_GPU.mm | 12 +- desmume/src/frontend/cocoa/cocoa_globals.h | 3 +- 7 files changed, 130 insertions(+), 109 deletions(-) diff --git a/desmume/src/frontend/cocoa/ClientDisplayView.cpp b/desmume/src/frontend/cocoa/ClientDisplayView.cpp index cffdf770c..638a771fa 100644 --- a/desmume/src/frontend/cocoa/ClientDisplayView.cpp +++ b/desmume/src/frontend/cocoa/ClientDisplayView.cpp @@ -63,8 +63,8 @@ ClientDisplayPresenter::~ClientDisplayPresenter() void ClientDisplayPresenter::__InstanceInit(const ClientDisplayPresenterProperties &props) { - _stagedProperty = props; - _renderProperty = _stagedProperty; + _propsPending = props; + _propsApplied = _propsPending; _useDeposterize = false; _pixelScaler = VideoFilterTypeID_None; @@ -265,14 +265,14 @@ void ClientDisplayPresenter::_UpdateClientSize() void ClientDisplayPresenter::_UpdateViewScale() { - double checkWidth = this->_renderProperty.normalWidth; - double checkHeight = this->_renderProperty.normalHeight; - ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, this->_renderProperty.rotation, checkWidth, checkHeight); - this->_renderProperty.viewScale = ClientDisplayPresenter::GetMaxScalarWithinBounds(checkWidth, checkHeight, this->_renderProperty.clientWidth, this->_renderProperty.clientHeight); + double checkWidth = this->_propsApplied.normalWidth; + double checkHeight = this->_propsApplied.normalHeight; + ClientDisplayPresenter::ConvertNormalToTransformedBounds(1.0, this->_propsApplied.rotation, checkWidth, checkHeight); + this->_propsApplied.viewScale = ClientDisplayPresenter::GetMaxScalarWithinBounds(checkWidth, checkHeight, this->_propsApplied.clientWidth, this->_propsApplied.clientHeight); - const double logicalClientWidth = this->_renderProperty.clientWidth / this->_scaleFactor; + const double logicalClientWidth = this->_propsApplied.clientWidth / this->_scaleFactor; - this->_hudObjectScale = logicalClientWidth / this->_renderProperty.normalWidth; + this->_hudObjectScale = logicalClientWidth / this->_propsApplied.normalWidth; if (this->_hudObjectScale > 1.74939175) { // If the view scale is <= 1.74939175, we scale the HUD objects linearly. Otherwise, we scale @@ -286,30 +286,30 @@ void ClientDisplayPresenter::_UpdateViewScale() // NDS screen layout const ClientDisplayPresenterProperties& ClientDisplayPresenter::GetPresenterProperties() const { - return this->_renderProperty; + return this->_propsApplied; } void ClientDisplayPresenter::CommitPresenterProperties(const ClientDisplayPresenterProperties &props) { - this->_stagedProperty = props; + this->_propsPending = props; } void ClientDisplayPresenter::SetupPresenterProperties() { // Validate the staged properties. - this->_stagedProperty.gapDistance = (double)DS_DISPLAY_UNSCALED_GAP * this->_stagedProperty.gapScale; - ClientDisplayPresenter::CalculateNormalSize(this->_stagedProperty.mode, this->_stagedProperty.layout, this->_stagedProperty.gapScale, this->_stagedProperty.normalWidth, this->_stagedProperty.normalHeight); + this->_propsPending.gapDistance = (double)DS_DISPLAY_UNSCALED_GAP * this->_propsPending.gapScale; + ClientDisplayPresenter::CalculateNormalSize(this->_propsPending.mode, this->_propsPending.layout, this->_propsPending.gapScale, this->_propsPending.normalWidth, this->_propsPending.normalHeight); - const bool didNormalSizeChange = (this->_renderProperty.mode != this->_stagedProperty.mode) || - (this->_renderProperty.layout != this->_stagedProperty.layout) || - (this->_renderProperty.gapScale != this->_stagedProperty.gapScale); + const bool didNormalSizeChange = (this->_propsApplied.mode != this->_propsPending.mode) || + (this->_propsApplied.layout != this->_propsPending.layout) || + (this->_propsApplied.gapScale != this->_propsPending.gapScale); - const bool didOrderChange = (this->_renderProperty.order != this->_stagedProperty.order); - const bool didRotationChange = (this->_renderProperty.rotation != this->_stagedProperty.rotation); - const bool didClientSizeChange = (this->_renderProperty.clientWidth != this->_stagedProperty.clientWidth) || (this->_renderProperty.clientHeight != this->_stagedProperty.clientHeight); + const bool didOrderChange = (this->_propsApplied.order != this->_propsPending.order); + const bool didRotationChange = (this->_propsApplied.rotation != this->_propsPending.rotation); + const bool didClientSizeChange = (this->_propsApplied.clientWidth != this->_propsPending.clientWidth) || (this->_propsApplied.clientHeight != this->_propsPending.clientHeight); // Copy the staged properties to the current rendering properties. - this->_renderProperty = this->_stagedProperty; + this->_propsApplied = this->_propsPending; // Update internal states based on the new render properties this->_UpdateViewScale(); @@ -346,37 +346,37 @@ void ClientDisplayPresenter::SetupPresenterProperties() double ClientDisplayPresenter::GetRotation() const { - return this->_renderProperty.rotation; + return this->_propsApplied.rotation; } double ClientDisplayPresenter::GetViewScale() const { - return this->_renderProperty.viewScale; + return this->_propsApplied.viewScale; } ClientDisplayMode ClientDisplayPresenter::GetMode() const { - return this->_renderProperty.mode; + return this->_propsApplied.mode; } ClientDisplayLayout ClientDisplayPresenter::GetLayout() const { - return this->_renderProperty.layout; + return this->_propsApplied.layout; } ClientDisplayOrder ClientDisplayPresenter::GetOrder() const { - return this->_renderProperty.order; + return this->_propsApplied.order; } double ClientDisplayPresenter::GetGapScale() const { - return this->_renderProperty.gapScale; + return this->_propsApplied.gapScale; } double ClientDisplayPresenter::GetGapDistance() const { - return this->_renderProperty.gapDistance; + return this->_propsApplied.gapDistance; } ClientDisplaySource ClientDisplayPresenter::GetDisplayVideoSource(const NDSDisplayID displayID) const @@ -942,8 +942,8 @@ void ClientDisplayPresenter::LoadDisplays() break; } - const bool loadMainScreen = this->_isSelectedDisplayEnabled[NDSDisplayID_Main] && ((this->_renderProperty.mode == ClientDisplayMode_Main) || (this->_renderProperty.mode == ClientDisplayMode_Dual)); - const bool loadTouchScreen = this->_isSelectedDisplayEnabled[NDSDisplayID_Touch] && ((this->_renderProperty.mode == ClientDisplayMode_Touch) || (this->_renderProperty.mode == ClientDisplayMode_Dual)) && (this->_selectedSourceForDisplay[NDSDisplayID_Main] != this->_selectedSourceForDisplay[NDSDisplayID_Touch]); + const bool loadMainScreen = this->_isSelectedDisplayEnabled[NDSDisplayID_Main] && ((this->_propsApplied.mode == ClientDisplayMode_Main) || (this->_propsApplied.mode == ClientDisplayMode_Dual)); + const bool loadTouchScreen = this->_isSelectedDisplayEnabled[NDSDisplayID_Touch] && ((this->_propsApplied.mode == ClientDisplayMode_Touch) || (this->_propsApplied.mode == ClientDisplayMode_Dual)) && (this->_selectedSourceForDisplay[NDSDisplayID_Main] != this->_selectedSourceForDisplay[NDSDisplayID_Touch]); if (loadMainScreen) { @@ -1647,16 +1647,16 @@ void ClientDisplay3DPresenter::SetHUDTouchLinePositionVertices(float *vtxBufferP { 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); - const float w = this->_renderProperty.normalWidth / 2.0f; - const float h = this->_renderProperty.normalHeight / 2.0f; + const float w = this->_propsApplied.normalWidth / 2.0f; + const float h = this->_propsApplied.normalHeight / 2.0f; - if (this->_renderProperty.mode == ClientDisplayMode_Dual) + if (this->_propsApplied.mode == ClientDisplayMode_Dual) { - switch (this->_renderProperty.layout) + switch (this->_propsApplied.layout) { case ClientDisplayLayout_Horizontal: { - if (this->_renderProperty.order == ClientDisplayOrder_MainFirst) + if (this->_propsApplied.order == ClientDisplayOrder_MainFirst) { vtxBufferPtr[0] = x; vtxBufferPtr[1] = h; // Vertical line, top left vtxBufferPtr[2] = x + 1.0f; vtxBufferPtr[3] = h; // Vertical line, top right @@ -1697,7 +1697,7 @@ void ClientDisplay3DPresenter::SetHUDTouchLinePositionVertices(float *vtxBufferP vtxBufferPtr[12] = w; vtxBufferPtr[13] = -h + (y/2.0f); // Minor bottom display, horizontal line, bottom right vtxBufferPtr[14] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[15] = -h + (y/2.0f); // Minor bottom display, horizontal line, bottom left - if (this->_renderProperty.order == ClientDisplayOrder_MainFirst) + if (this->_propsApplied.order == ClientDisplayOrder_MainFirst) { memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused lines } @@ -1728,7 +1728,7 @@ void ClientDisplay3DPresenter::SetHUDTouchLinePositionVertices(float *vtxBufferP vtxBufferPtr[12] = w; vtxBufferPtr[13] = -h + (y/3.0f); // Minor bottom display, horizontal line, bottom right vtxBufferPtr[14] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[15] = -h + (y/3.0f); // Minor bottom display, horizontal line, bottom left - if (this->_renderProperty.order == ClientDisplayOrder_MainFirst) + if (this->_propsApplied.order == ClientDisplayOrder_MainFirst) { memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused lines } @@ -1759,7 +1759,7 @@ void ClientDisplay3DPresenter::SetHUDTouchLinePositionVertices(float *vtxBufferP vtxBufferPtr[12] = w; vtxBufferPtr[13] = -h + (y/5.0f); // Minor bottom display, horizontal line, bottom right vtxBufferPtr[14] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[15] = -h + (y/5.0f); // Minor bottom display, horizontal line, bottom left - if (this->_renderProperty.order == ClientDisplayOrder_MainFirst) + if (this->_propsApplied.order == ClientDisplayOrder_MainFirst) { memcpy(vtxBufferPtr + (2 * 8), vtxBufferPtr + (0 * 8), sizeof(float) * (2 * 8)); // Unused lines } @@ -1780,9 +1780,9 @@ void ClientDisplay3DPresenter::SetHUDTouchLinePositionVertices(float *vtxBufferP default: // Default to vertical orientation. { - const float g = (float)this->_renderProperty.gapDistance; + const float g = (float)this->_propsApplied.gapDistance; - if (this->_renderProperty.order == ClientDisplayOrder_MainFirst) + if (this->_propsApplied.order == ClientDisplayOrder_MainFirst) { vtxBufferPtr[0] = -w + x; vtxBufferPtr[1] = -g/2.0f; // Vertical line, top left vtxBufferPtr[2] = -w + x + 1.0f; vtxBufferPtr[3] = -g/2.0f; // Vertical line, top right @@ -2053,13 +2053,13 @@ void ClientDisplay3DPresenter::SetHUDTextureCoordinates(float *texCoordBufferPtr void ClientDisplay3DPresenter::SetScreenVertices(float *vtxBufferPtr) { - const float w = this->_renderProperty.normalWidth / 2.0f; - const float h = this->_renderProperty.normalHeight / 2.0f; - const size_t f = (this->_renderProperty.order == ClientDisplayOrder_MainFirst) ? 0 : 8; + const float w = this->_propsApplied.normalWidth / 2.0f; + const float h = this->_propsApplied.normalHeight / 2.0f; + const size_t f = (this->_propsApplied.order == ClientDisplayOrder_MainFirst) ? 0 : 8; - if (this->_renderProperty.mode == ClientDisplayMode_Dual) + if (this->_propsApplied.mode == ClientDisplayMode_Dual) { - switch (this->_renderProperty.layout) + switch (this->_propsApplied.layout) { case ClientDisplayLayout_Horizontal: { @@ -2100,7 +2100,7 @@ void ClientDisplay3DPresenter::SetScreenVertices(float *vtxBufferPtr) case ClientDisplayLayout_Hybrid_16_9: { - const float g = (float)this->_renderProperty.gapDistance * (this->_renderProperty.normalWidth - (float)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; + const float g = (float)this->_propsApplied.gapDistance * (this->_propsApplied.normalWidth - (float)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[0] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[1] = -h + g + (64.0f * 2.0f); // Minor top display, top left vtxBufferPtr[2] = w; vtxBufferPtr[3] = -h + g + (64.0f * 2.0f); // Minor top display, top right @@ -2123,7 +2123,7 @@ void ClientDisplay3DPresenter::SetScreenVertices(float *vtxBufferPtr) case ClientDisplayLayout_Hybrid_16_10: { - const float g = (float)this->_renderProperty.gapDistance * (this->_renderProperty.normalWidth - (float)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; + const float g = (float)this->_propsApplied.gapDistance * (this->_propsApplied.normalWidth - (float)GPU_FRAMEBUFFER_NATIVE_WIDTH) / (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[0] = -w + (float)GPU_FRAMEBUFFER_NATIVE_WIDTH; vtxBufferPtr[1] = -h + g + (38.4f * 2.0f); // Minor top display, top left vtxBufferPtr[2] = w; vtxBufferPtr[3] = -h + g + (38.4f * 2.0f); // Minor top display, top right @@ -2146,7 +2146,7 @@ void ClientDisplay3DPresenter::SetScreenVertices(float *vtxBufferPtr) default: // Default to vertical orientation. { - const float g = (float)this->_renderProperty.gapDistance; + const float g = (float)this->_propsApplied.gapDistance; vtxBufferPtr[0+f] = -w; vtxBufferPtr[1+f] = h; // Top display, top left vtxBufferPtr[2+f] = w; vtxBufferPtr[3+f] = h; // Top display, top right diff --git a/desmume/src/frontend/cocoa/ClientDisplayView.h b/desmume/src/frontend/cocoa/ClientDisplayView.h index 1151ec0b4..2dc54d1c2 100644 --- a/desmume/src/frontend/cocoa/ClientDisplayView.h +++ b/desmume/src/frontend/cocoa/ClientDisplayView.h @@ -139,8 +139,8 @@ private: void __InstanceInit(const ClientDisplayPresenterProperties &props); protected: - ClientDisplayPresenterProperties _renderProperty; - ClientDisplayPresenterProperties _stagedProperty; + ClientDisplayPresenterProperties _propsPending; + ClientDisplayPresenterProperties _propsApplied; GPUClientFetchObject *_fetchObject; bool _useDeposterize; diff --git a/desmume/src/frontend/cocoa/ClientExecutionControl.cpp b/desmume/src/frontend/cocoa/ClientExecutionControl.cpp index 0d40f99e3..2d78afb7c 100644 --- a/desmume/src/frontend/cocoa/ClientExecutionControl.cpp +++ b/desmume/src/frontend/cocoa/ClientExecutionControl.cpp @@ -1198,72 +1198,84 @@ void ClientExecutionControl::ApplySettingsOnNDSExec() } } -void ClientExecutionControl::FetchOutputPostNDSExec() +void ClientExecutionControl::GenerateNDSFrameInfo(ClientInputHandler *inputHandler, NDSFrameInfo &outInfo) { - pthread_mutex_lock(&this->_mutexOutputPostNDSExec); + outInfo.frameIndex = currFrameCounter; + outInfo.render3DFPS = GPU->GetFPSRender3D(); + outInfo.lagFrameCount = TotalLagFrames; - this->_ndsFrameInfo.frameIndex = currFrameCounter; - this->_ndsFrameInfo.render3DFPS = GPU->GetFPSRender3D(); - this->_ndsFrameInfo.lagFrameCount = TotalLagFrames; - - if ((this->_ndsFrameInfo.frameIndex & 0xF) == 0xF) + if ((outInfo.frameIndex & 0xF) == 0xF) { - NDS_GetCPULoadAverage(this->_ndsFrameInfo.cpuLoadAvgARM9, this->_ndsFrameInfo.cpuLoadAvgARM7); + NDS_GetCPULoadAverage(outInfo.cpuLoadAvgARM9, outInfo.cpuLoadAvgARM7); } char *tempBuffer = (char *)calloc(25, sizeof(char)); rtcGetTimeAsString(tempBuffer); - this->_ndsFrameInfo.rtcString = tempBuffer; + outInfo.rtcString = std::string(tempBuffer); free(tempBuffer); - this->_ndsFrameInfo.inputStatesApplied.value = INPUT_STATES_CLEAR_VALUE; + ClientExecutionControl::UpdateNDSFrameInfoInput(inputHandler, outInfo); +} + +void ClientExecutionControl::UpdateNDSFrameInfoInput(ClientInputHandler *inputHandler, NDSFrameInfo &outInfo) +{ + outInfo.inputStatesApplied.value = INPUT_STATES_CLEAR_VALUE; - if (this->_inputHandler != NULL) + if (inputHandler == NULL) { - const ClientInput *appliedInput = this->_inputHandler->GetClientInputsApplied(); - - this->_ndsFrameInfo.inputStatesApplied.A = (appliedInput[NDSInputID_A].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.B = (appliedInput[NDSInputID_B].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Select = (appliedInput[NDSInputID_Select].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Start = (appliedInput[NDSInputID_Start].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Right = (appliedInput[NDSInputID_Right].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Left = (appliedInput[NDSInputID_Left].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Up = (appliedInput[NDSInputID_Up].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Down = (appliedInput[NDSInputID_Down].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.R = (appliedInput[NDSInputID_R].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.L = (appliedInput[NDSInputID_L].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.X = (appliedInput[NDSInputID_X].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Y = (appliedInput[NDSInputID_Y].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Debug = (appliedInput[NDSInputID_Debug].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Touch = (appliedInput[NDSInputID_Touch].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Lid = (appliedInput[NDSInputID_Lid].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoC = (appliedInput[NDSInputID_Piano_C].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoCSharp = (appliedInput[NDSInputID_Piano_CSharp].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoD = (appliedInput[NDSInputID_Piano_D].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoDSharp = (appliedInput[NDSInputID_Piano_DSharp].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoE = (appliedInput[NDSInputID_Piano_E].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoF = (appliedInput[NDSInputID_Piano_F].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoFSharp = (appliedInput[NDSInputID_Piano_FSharp].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoG = (appliedInput[NDSInputID_Piano_G].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoGSharp = (appliedInput[NDSInputID_Piano_GSharp].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoA = (appliedInput[NDSInputID_Piano_A].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoASharp = (appliedInput[NDSInputID_Piano_ASharp].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoB = (appliedInput[NDSInputID_Piano_B].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.PianoHighC = (appliedInput[NDSInputID_Piano_HighC].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.GuitarGripBlue = (appliedInput[NDSInputID_GuitarGrip_Blue].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.GuitarGripYellow = (appliedInput[NDSInputID_GuitarGrip_Yellow].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.GuitarGripRed = (appliedInput[NDSInputID_GuitarGrip_Red].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.GuitarGripGreen = (appliedInput[NDSInputID_GuitarGrip_Green].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Paddle = (appliedInput[NDSInputID_Paddle].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Microphone = (appliedInput[NDSInputID_Microphone].isPressed) ? 0 : 1; - this->_ndsFrameInfo.inputStatesApplied.Reset = (appliedInput[NDSInputID_Reset].isPressed) ? 0 : 1; - this->_ndsFrameInfo.touchLocXApplied = this->_inputHandler->GetTouchLocXApplied(); - this->_ndsFrameInfo.touchLocYApplied = this->_inputHandler->GetTouchLocYApplied(); - this->_ndsFrameInfo.touchPressureApplied = this->_inputHandler->GetTouchPressureApplied(); - this->_ndsFrameInfo.paddleValueApplied = this->_inputHandler->GetPaddleValueApplied(); - this->_ndsFrameInfo.paddleAdjustApplied = this->_inputHandler->GetPaddleAdjustApplied(); + // If the passed in input handler is NULL then this method has + // the effect of clearing the input states of the NDS frame info. + return; } + const ClientInput *appliedInput = inputHandler->GetClientInputsApplied(); + + outInfo.inputStatesApplied.A = (appliedInput[NDSInputID_A].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.B = (appliedInput[NDSInputID_B].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Select = (appliedInput[NDSInputID_Select].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Start = (appliedInput[NDSInputID_Start].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Right = (appliedInput[NDSInputID_Right].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Left = (appliedInput[NDSInputID_Left].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Up = (appliedInput[NDSInputID_Up].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Down = (appliedInput[NDSInputID_Down].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.R = (appliedInput[NDSInputID_R].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.L = (appliedInput[NDSInputID_L].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.X = (appliedInput[NDSInputID_X].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Y = (appliedInput[NDSInputID_Y].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Debug = (appliedInput[NDSInputID_Debug].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Touch = (appliedInput[NDSInputID_Touch].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Lid = (appliedInput[NDSInputID_Lid].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoC = (appliedInput[NDSInputID_Piano_C].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoCSharp = (appliedInput[NDSInputID_Piano_CSharp].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoD = (appliedInput[NDSInputID_Piano_D].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoDSharp = (appliedInput[NDSInputID_Piano_DSharp].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoE = (appliedInput[NDSInputID_Piano_E].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoF = (appliedInput[NDSInputID_Piano_F].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoFSharp = (appliedInput[NDSInputID_Piano_FSharp].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoG = (appliedInput[NDSInputID_Piano_G].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoGSharp = (appliedInput[NDSInputID_Piano_GSharp].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoA = (appliedInput[NDSInputID_Piano_A].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoASharp = (appliedInput[NDSInputID_Piano_ASharp].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoB = (appliedInput[NDSInputID_Piano_B].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.PianoHighC = (appliedInput[NDSInputID_Piano_HighC].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.GuitarGripBlue = (appliedInput[NDSInputID_GuitarGrip_Blue].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.GuitarGripYellow = (appliedInput[NDSInputID_GuitarGrip_Yellow].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.GuitarGripRed = (appliedInput[NDSInputID_GuitarGrip_Red].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.GuitarGripGreen = (appliedInput[NDSInputID_GuitarGrip_Green].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Paddle = (appliedInput[NDSInputID_Paddle].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Microphone = (appliedInput[NDSInputID_Microphone].isPressed) ? 0 : 1; + outInfo.inputStatesApplied.Reset = (appliedInput[NDSInputID_Reset].isPressed) ? 0 : 1; + outInfo.touchLocXApplied = inputHandler->GetTouchLocXApplied(); + outInfo.touchLocYApplied = inputHandler->GetTouchLocYApplied(); + outInfo.touchPressureApplied = inputHandler->GetTouchPressureApplied(); + outInfo.paddleValueApplied = inputHandler->GetPaddleValueApplied(); + outInfo.paddleAdjustApplied = inputHandler->GetPaddleAdjustApplied(); +} + +void ClientExecutionControl::FetchOutputPostNDSExec() +{ + pthread_mutex_lock(&this->_mutexOutputPostNDSExec); + ClientExecutionControl::GenerateNDSFrameInfo(this->_inputHandler, this->_ndsFrameInfo); pthread_mutex_unlock(&this->_mutexOutputPostNDSExec); } diff --git a/desmume/src/frontend/cocoa/ClientExecutionControl.h b/desmume/src/frontend/cocoa/ClientExecutionControl.h index b3e608d33..a5625be26 100644 --- a/desmume/src/frontend/cocoa/ClientExecutionControl.h +++ b/desmume/src/frontend/cocoa/ClientExecutionControl.h @@ -378,6 +378,8 @@ public: void FetchOutputPostNDSExec(); const NDSFrameInfo& GetNDSFrameInfo(); + static void GenerateNDSFrameInfo(ClientInputHandler *inputHandler, NDSFrameInfo &outInfo); + static void UpdateNDSFrameInfoInput(ClientInputHandler *inputHandler, NDSFrameInfo &outInfo); void SetFrameInfoExecutionSpeed(double executionSpeed); uint64_t GetFrameIndex(); diff --git a/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp b/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp index fc420a76c..5b0f53e95 100644 --- a/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp +++ b/desmume/src/frontend/cocoa/OGLDisplayOutput.cpp @@ -4987,8 +4987,8 @@ void OGLVideoOutput::_UpdateRotation() void OGLVideoOutput::_UpdateClientSize() { - this->_viewportWidth = (GLsizei)(this->_renderProperty.clientWidth + 0.0001); - this->_viewportHeight = (GLsizei)(this->_renderProperty.clientHeight + 0.0001); + this->_viewportWidth = (GLsizei)(this->_propsApplied.clientWidth + 0.0001); + this->_viewportHeight = (GLsizei)(this->_propsApplied.clientHeight + 0.0001); this->_needUpdateViewport = true; this->GetHUDLayer()->SetNeedsUpdateVertices(); @@ -5199,9 +5199,9 @@ void OGLVideoOutput::CopyFrameToBuffer(uint32_t *dstBuffer) this->RenderFrameOGL(true); #ifdef MSB_FIRST - glReadPixels(0, 0, this->_renderProperty.clientWidth, this->_renderProperty.clientHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, dstBuffer); + glReadPixels(0, 0, this->_propsApplied.clientWidth, this->_propsApplied.clientHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, dstBuffer); #else - glReadPixels(0, 0, this->_renderProperty.clientWidth, this->_renderProperty.clientHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, dstBuffer); + glReadPixels(0, 0, this->_propsApplied.clientWidth, this->_propsApplied.clientHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, dstBuffer); #endif glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); diff --git a/desmume/src/frontend/cocoa/cocoa_GPU.mm b/desmume/src/frontend/cocoa/cocoa_GPU.mm index b8a22163f..915ddf282 100644 --- a/desmume/src/frontend/cocoa/cocoa_GPU.mm +++ b/desmume/src/frontend/cocoa/cocoa_GPU.mm @@ -1056,7 +1056,7 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = { #ifdef ENABLE_ASYNC_FETCH const u8 bufferIndex = GPU->GetDisplayInfo().bufferIndex; - ((MacGPUFetchObjectAsync *)fetchObject)->SignalFetchAtIndex(bufferIndex, MESSAGE_FETCH_AND_PUSH_VIDEO); + ((MacGPUFetchObjectAsync *)fetchObject)->SignalFetchAtIndex(bufferIndex, MESSAGE_FETCH_AND_PERFORM_ACTIONS); #endif } @@ -1317,8 +1317,14 @@ void MacGPUFetchObjectAsync::RunFetchLoop() pthread_cond_wait(&this->_condSignalFetch, &this->_mutexFetchExecute); } + const uint32_t lastMessageID = this->_threadMessageID; this->FetchFromBufferIndex(this->_fetchIndex); - this->DoPostFetchActions(); + + if (lastMessageID == MESSAGE_FETCH_AND_PERFORM_ACTIONS) + { + this->DoPostFetchActions(); + } + this->_threadMessageID = MESSAGE_NONE; [tempPool release]; @@ -1716,7 +1722,7 @@ void GPUEventHandlerOSX::DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo & if (!isFrameSkipped) { - asyncFetchObj->SignalFetchAtIndex(latestDisplayInfo.bufferIndex, MESSAGE_FETCH_AND_PUSH_VIDEO); + asyncFetchObj->SignalFetchAtIndex(latestDisplayInfo.bufferIndex, MESSAGE_FETCH_AND_PERFORM_ACTIONS); } } diff --git a/desmume/src/frontend/cocoa/cocoa_globals.h b/desmume/src/frontend/cocoa/cocoa_globals.h index 9fd81106a..4826ff119 100644 --- a/desmume/src/frontend/cocoa/cocoa_globals.h +++ b/desmume/src/frontend/cocoa/cocoa_globals.h @@ -354,7 +354,8 @@ enum MESSAGE_SET_EMULATION_FLAGS, // Video Messages - MESSAGE_FETCH_AND_PUSH_VIDEO, + MESSAGE_FETCH_ONLY, + MESSAGE_FETCH_AND_PERFORM_ACTIONS, MESSAGE_RECEIVE_GPU_FRAME, MESSAGE_CHANGE_VIEW_PROPERTIES, MESSAGE_REDRAW_VIEW,