diff --git a/desmume/src/frontend/cocoa/ClientDisplayView.cpp b/desmume/src/frontend/cocoa/ClientDisplayView.cpp
index ad50f4ee2..5885f2853 100644
--- a/desmume/src/frontend/cocoa/ClientDisplayView.cpp
+++ b/desmume/src/frontend/cocoa/ClientDisplayView.cpp
@@ -81,6 +81,7 @@ void ClientDisplayPresenter::__InstanceInit(const ClientDisplayPresenterProperti
_hudObjectScale = 1.0;
_isHUDVisible = false;
+ _showExecutionSpeed = false;
_showVideoFPS = true;
_showRender3DFPS = false;
_showFrameIndex = false;
@@ -89,6 +90,7 @@ void ClientDisplayPresenter::__InstanceInit(const ClientDisplayPresenterProperti
_showRTC = false;
_showInputs = false;
+ _hudColorExecutionSpeed = LE_TO_LOCAL_32(0xFFFFFFFF);
_hudColorVideoFPS = LE_TO_LOCAL_32(0xFFFFFFFF);
_hudColorRender3DFPS = LE_TO_LOCAL_32(0xFFFFFFFF);
_hudColorFrameIndex = LE_TO_LOCAL_32(0xFFFFFFFF);
@@ -149,6 +151,22 @@ void ClientDisplayPresenter::_UpdateHUDString()
std::ostringstream ss;
ss << "\x01"; // This represents the text box. It must always be the first character.
+ if (this->_showExecutionSpeed)
+ {
+ if (this->_ndsFrameInfo.executionSpeed < 0.0001)
+ {
+ ss << "Execution Speed: -----%\n";
+ }
+ else
+ {
+ char buffer[48];
+ memset(buffer, 0, sizeof(buffer));
+ snprintf(buffer, 47, "Execution Speed: %3.01f%%\n", this->_ndsFrameInfo.executionSpeed);
+
+ ss << buffer;
+ }
+ }
+
if (this->_showVideoFPS)
{
ss << "Video FPS: " << this->_clientFrameInfo.videoFPS << "\n";
@@ -516,6 +534,17 @@ void ClientDisplayPresenter::SetHUDVisibility(const bool visibleState)
this->UpdateLayout();
}
+bool ClientDisplayPresenter::GetHUDShowExecutionSpeed() const
+{
+ return this->_showExecutionSpeed;
+}
+
+void ClientDisplayPresenter::SetHUDShowExecutionSpeed(const bool visibleState)
+{
+ this->_SetHUDShowInfoItem(this->_showExecutionSpeed, visibleState);
+ this->UpdateLayout();
+}
+
bool ClientDisplayPresenter::GetHUDShowVideoFPS() const
{
return this->_showVideoFPS;
@@ -593,6 +622,22 @@ void ClientDisplayPresenter::SetHUDShowInput(const bool visibleState)
this->UpdateLayout();
}
+uint32_t ClientDisplayPresenter::GetHUDColorExecutionSpeed() const
+{
+ return this->_hudColorExecutionSpeed;
+}
+
+void ClientDisplayPresenter::SetHUDColorExecutionSpeed(uint32_t color32)
+{
+ this->_hudColorExecutionSpeed = color32;
+
+ pthread_mutex_lock(&this->_mutexHUDString);
+ this->_hudNeedsUpdate = true;
+ pthread_mutex_unlock(&this->_mutexHUDString);
+
+ this->UpdateLayout();
+}
+
uint32_t ClientDisplayPresenter::GetHUDColorVideoFPS() const
{
return this->_hudColorVideoFPS;
@@ -1790,6 +1835,7 @@ void ClientDisplay3DPresenter::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
vtxColorBufferPtr[3] = currentColor;
// Calculate the colors of the remaining characters in the string.
+ bool alreadyColoredExecutionSpeed = false;
bool alreadyColoredVideoFPS = false;
bool alreadyColoredRender3DFPS = false;
bool alreadyColoredFrameIndex = false;
@@ -1797,7 +1843,12 @@ void ClientDisplay3DPresenter::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
bool alreadyColoredCPULoadAverage = false;
bool alreadyColoredRTC = false;
- if (this->_showVideoFPS)
+ if (this->_showExecutionSpeed)
+ {
+ currentColor = this->_hudColorExecutionSpeed;
+ alreadyColoredExecutionSpeed = true;
+ }
+ else if (this->_showVideoFPS)
{
currentColor = this->_hudColorVideoFPS;
alreadyColoredVideoFPS = true;
@@ -1837,7 +1888,12 @@ void ClientDisplay3DPresenter::SetHUDColorVertices(uint32_t *vtxColorBufferPtr)
if (c == '\n')
{
- if (this->_showVideoFPS && !alreadyColoredVideoFPS)
+ if (this->_showExecutionSpeed && !alreadyColoredExecutionSpeed)
+ {
+ currentColor = this->_hudColorExecutionSpeed;
+ alreadyColoredExecutionSpeed = true;
+ }
+ else if (this->_showVideoFPS && !alreadyColoredVideoFPS)
{
currentColor = this->_hudColorVideoFPS;
alreadyColoredVideoFPS = true;
diff --git a/desmume/src/frontend/cocoa/ClientDisplayView.h b/desmume/src/frontend/cocoa/ClientDisplayView.h
index 870a177d4..4a26fb1df 100644
--- a/desmume/src/frontend/cocoa/ClientDisplayView.h
+++ b/desmume/src/frontend/cocoa/ClientDisplayView.h
@@ -155,6 +155,7 @@ protected:
double _hudObjectScale;
bool _isHUDVisible;
+ bool _showExecutionSpeed;
bool _showVideoFPS;
bool _showRender3DFPS;
bool _showFrameIndex;
@@ -163,6 +164,7 @@ protected:
bool _showRTC;
bool _showInputs;
+ uint32_t _hudColorExecutionSpeed;
uint32_t _hudColorVideoFPS;
uint32_t _hudColorRender3DFPS;
uint32_t _hudColorFrameIndex;
@@ -258,6 +260,8 @@ public:
bool GetHUDVisibility() const;
virtual void SetHUDVisibility(const bool visibleState);
+ bool GetHUDShowExecutionSpeed() const;
+ virtual void SetHUDShowExecutionSpeed(const bool visibleState);
bool GetHUDShowVideoFPS() const;
virtual void SetHUDShowVideoFPS(const bool visibleState);
bool GetHUDShowRender3DFPS() const;
@@ -272,6 +276,8 @@ public:
virtual void SetHUDShowRTC(const bool visibleState);
bool GetHUDShowInput() const;
virtual void SetHUDShowInput(const bool visibleState);
+ uint32_t GetHUDColorExecutionSpeed() const;
+ virtual void SetHUDColorExecutionSpeed(uint32_t color32);
uint32_t GetHUDColorVideoFPS() const;
virtual void SetHUDColorVideoFPS(uint32_t color32);
uint32_t GetHUDColorRender3DFPS() const;
diff --git a/desmume/src/frontend/cocoa/ClientExecutionControl.cpp b/desmume/src/frontend/cocoa/ClientExecutionControl.cpp
index fb2e96276..d5da45bec 100644
--- a/desmume/src/frontend/cocoa/ClientExecutionControl.cpp
+++ b/desmume/src/frontend/cocoa/ClientExecutionControl.cpp
@@ -963,6 +963,11 @@ const NDSFrameInfo& ClientExecutionControl::GetNDSFrameInfo()
return this->_ndsFrameInfo;
}
+void ClientExecutionControl::SetFrameInfoExecutionSpeed(double executionSpeed)
+{
+ this->_ndsFrameInfo.executionSpeed = executionSpeed;
+}
+
uint64_t ClientExecutionControl::GetFrameIndex()
{
pthread_mutex_lock(&this->_mutexOutputPostNDSExec);
diff --git a/desmume/src/frontend/cocoa/ClientExecutionControl.h b/desmume/src/frontend/cocoa/ClientExecutionControl.h
index 528773eb6..40ea2e31c 100644
--- a/desmume/src/frontend/cocoa/ClientExecutionControl.h
+++ b/desmume/src/frontend/cocoa/ClientExecutionControl.h
@@ -111,6 +111,7 @@ struct NDSFrameInfo
uint32_t lagFrameCount;
uint32_t cpuLoadAvgARM9;
uint32_t cpuLoadAvgARM7;
+ double executionSpeed;
NDSInputState inputStatesPending;
uint8_t touchLocXPending;
@@ -137,6 +138,7 @@ struct NDSFrameInfo
this->lagFrameCount = 0;
this->cpuLoadAvgARM9 = 0;
this->cpuLoadAvgARM7 = 0;
+ this->executionSpeed = 0.0;
this->inputStatesPending.value = INPUT_STATES_CLEAR_VALUE;
this->touchLocXPending = 0;
@@ -164,6 +166,7 @@ struct NDSFrameInfo
this->lagFrameCount = fromObject.lagFrameCount;
this->cpuLoadAvgARM9 = fromObject.cpuLoadAvgARM9;
this->cpuLoadAvgARM7 = fromObject.cpuLoadAvgARM7;
+ this->executionSpeed = fromObject.executionSpeed;
this->inputStatesPending = fromObject.inputStatesPending;
this->touchLocXPending = fromObject.touchLocXPending;
@@ -308,6 +311,7 @@ public:
void FetchOutputPostNDSExec();
const NDSFrameInfo& GetNDSFrameInfo();
+ void SetFrameInfoExecutionSpeed(double executionSpeed);
uint64_t GetFrameIndex();
double GetFrameTime();
diff --git a/desmume/src/frontend/cocoa/DefaultUserPrefs.plist b/desmume/src/frontend/cocoa/DefaultUserPrefs.plist
index 92ceb3d50..ef6d9bc77 100644
--- a/desmume/src/frontend/cocoa/DefaultUserPrefs.plist
+++ b/desmume/src/frontend/cocoa/DefaultUserPrefs.plist
@@ -104,6 +104,8 @@
General_WillRestoreDisplayWindows
+ HUD_ShowExecutionSpeed
+
HUD_ShowVideoFPS
HUD_ShowRender3DFPS
@@ -118,6 +120,8 @@
HUD_ShowInput
+ HUD_Color_ExecutionSpeed
+ 4294967295
HUD_Color_VideoFPS
4294967295
HUD_Color_Render3DFPS
diff --git a/desmume/src/frontend/cocoa/cocoa_core.mm b/desmume/src/frontend/cocoa/cocoa_core.mm
index 4fb4b1727..f98657db5 100644
--- a/desmume/src/frontend/cocoa/cocoa_core.mm
+++ b/desmume/src/frontend/cocoa/cocoa_core.mm
@@ -1118,6 +1118,10 @@ static void* RunCoreThread(void *arg)
double startTime = 0;
double frameTime = 0; // The amount of time that is expected for the frame to run.
+ const double standardNDSFrameTime = execControl->CalculateFrameAbsoluteTime(1.0);
+ double executionSpeedAverage = 0.0;
+ double executionSpeedAverageFramesCollected = 0.0;
+
ExecutionBehavior behavior = ExecutionBehavior_Pause;
uint64_t frameJumpTarget = 0;
@@ -1176,6 +1180,26 @@ static void* RunCoreThread(void *arg)
const uint8_t framesToSkip = execControl->GetFramesToSkip();
+ if ( (behavior == ExecutionBehavior_Run) || (behavior == ExecutionBehavior_FrameJump) )
+ {
+ if ((ndsFrameInfo.frameIndex & 0x1F) == 0x1F)
+ {
+ if (executionSpeedAverageFramesCollected > 0.0001)
+ {
+ execControl->SetFrameInfoExecutionSpeed((executionSpeedAverage / executionSpeedAverageFramesCollected) * 100.0);
+ }
+
+ executionSpeedAverage = 0.0;
+ executionSpeedAverageFramesCollected = 0.0;
+ }
+ }
+ else
+ {
+ execControl->SetFrameInfoExecutionSpeed(0.0);
+ executionSpeedAverage = 0.0;
+ executionSpeedAverageFramesCollected = 0.0;
+ }
+
pthread_mutex_lock(¶m->mutexOutputList);
switch (behavior)
@@ -1267,6 +1291,10 @@ static void* RunCoreThread(void *arg)
execControl->WaitUntilAbsoluteTime(startTime + frameTime);
}
+ const double currentExecutionSpeed = standardNDSFrameTime / (execControl->GetCurrentAbsoluteTime() - startTime);
+ executionSpeedAverage += currentExecutionSpeed;
+ executionSpeedAverageFramesCollected += 1.0;
+
} while(true);
return NULL;
diff --git a/desmume/src/frontend/cocoa/cocoa_output.h b/desmume/src/frontend/cocoa/cocoa_output.h
index ffb6680bf..897db98aa 100644
--- a/desmume/src/frontend/cocoa/cocoa_output.h
+++ b/desmume/src/frontend/cocoa/cocoa_output.h
@@ -133,6 +133,7 @@
@property (readonly, nonatomic) BOOL canFilterOnGPU;
@property (readonly, nonatomic) BOOL willFilterOnGPU;
@property (assign) BOOL isHUDVisible;
+@property (assign) BOOL isHUDExecutionSpeedVisible;
@property (assign) BOOL isHUDVideoFPSVisible;
@property (assign) BOOL isHUDRender3DFPSVisible;
@property (assign) BOOL isHUDFrameIndexVisible;
@@ -140,6 +141,7 @@
@property (assign) BOOL isHUDCPULoadAverageVisible;
@property (assign) BOOL isHUDRealTimeClockVisible;
@property (assign) BOOL isHUDInputVisible;
+@property (assign) uint32_t hudColorExecutionSpeed;
@property (assign) uint32_t hudColorVideoFPS;
@property (assign) uint32_t hudColorRender3DFPS;
@property (assign) uint32_t hudColorFrameIndex;
diff --git a/desmume/src/frontend/cocoa/cocoa_output.mm b/desmume/src/frontend/cocoa/cocoa_output.mm
index 65d510e31..19c63ad9f 100644
--- a/desmume/src/frontend/cocoa/cocoa_output.mm
+++ b/desmume/src/frontend/cocoa/cocoa_output.mm
@@ -574,6 +574,7 @@
@dynamic canFilterOnGPU;
@dynamic willFilterOnGPU;
@dynamic isHUDVisible;
+@dynamic isHUDExecutionSpeedVisible;
@dynamic isHUDVideoFPSVisible;
@dynamic isHUDRender3DFPSVisible;
@dynamic isHUDFrameIndexVisible;
@@ -581,6 +582,7 @@
@dynamic isHUDCPULoadAverageVisible;
@dynamic isHUDRealTimeClockVisible;
@dynamic isHUDInputVisible;
+@dynamic hudColorExecutionSpeed;
@dynamic hudColorVideoFPS;
@dynamic hudColorRender3DFPS;
@dynamic hudColorFrameIndex;
@@ -664,6 +666,24 @@
return theState;
}
+- (void) setIsHUDExecutionSpeedVisible:(BOOL)theState
+{
+ OSSpinLockLock(&spinlockIsHUDVisible);
+ _cdv->Get3DPresenter()->SetHUDShowExecutionSpeed((theState) ? true : false);
+ OSSpinLockUnlock(&spinlockIsHUDVisible);
+
+ _cdv->SetViewNeedsFlush();
+}
+
+- (BOOL) isHUDExecutionSpeedVisible
+{
+ OSSpinLockLock(&spinlockIsHUDVisible);
+ const BOOL theState = (_cdv->Get3DPresenter()->GetHUDShowExecutionSpeed()) ? YES : NO;
+ OSSpinLockUnlock(&spinlockIsHUDVisible);
+
+ return theState;
+}
+
- (void) setIsHUDVideoFPSVisible:(BOOL)theState
{
OSSpinLockLock(&spinlockIsHUDVisible);
@@ -790,6 +810,24 @@
return theState;
}
+- (void) setHudColorExecutionSpeed:(uint32_t)theColor
+{
+ OSSpinLockLock(&spinlockIsHUDVisible);
+ _cdv->Get3DPresenter()->SetHUDColorExecutionSpeed(theColor);
+ OSSpinLockUnlock(&spinlockIsHUDVisible);
+
+ _cdv->SetViewNeedsFlush();
+}
+
+- (uint32_t) hudColorExecutionSpeed
+{
+ OSSpinLockLock(&spinlockIsHUDVisible);
+ const uint32_t color32 = _cdv->Get3DPresenter()->GetHUDColorExecutionSpeed();
+ OSSpinLockUnlock(&spinlockIsHUDVisible);
+
+ return color32;
+}
+
- (void) setHudColorVideoFPS:(uint32_t)theColor
{
OSSpinLockLock(&spinlockIsHUDVisible);
diff --git a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.strings b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.strings
index 62285fcf7..982dbf6e7 100644
Binary files a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.strings and b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.strings differ
diff --git a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib
index a4d314b72..12e666bd3 100644
--- a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib
+++ b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib
@@ -1752,6 +1752,14 @@
HUD Info Visibility