Cocoa Port: Continue refactoring cocoa_core.mm.

- Also fix a small off-by-one error in slot1_Change().
This commit is contained in:
rogerman 2017-08-30 15:20:08 -07:00
parent e29e825d27
commit db4982f4bc
11 changed files with 339 additions and 163 deletions

View File

@ -91,8 +91,10 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props)
_showCPULoadAverage = false;
_showRTC = false;
_clientFrameInfo.videoFPS = 0;
_ndsFrameInfo.clear();
memset(&_emuDisplayInfo, 0, sizeof(_emuDisplayInfo));
memset(&_emuFrameInfo, 0, sizeof(_emuFrameInfo));
_hudString = "\x01"; // Char value 0x01 will represent the "text box" character, which will always be first in the string.
_hudNeedsUpdate = true;
_allowViewUpdates = true;
@ -133,36 +135,36 @@ void ClientDisplayView::_UpdateHUDString()
if (this->_showVideoFPS)
{
ss << "Video FPS: " << this->_emuFrameInfo.videoFPS << "\n";
ss << "Video FPS: " << this->_clientFrameInfo.videoFPS << "\n";
}
if (this->_showRender3DFPS)
{
ss << "3D Rendering FPS: " << this->_emuFrameInfo.render3DFPS << "\n";
ss << "3D Rendering FPS: " << this->_ndsFrameInfo.render3DFPS << "\n";
}
if (this->_showFrameIndex)
{
ss << "Frame Index: " << this->_emuFrameInfo.frameIndex << "\n";
ss << "Frame Index: " << this->_ndsFrameInfo.frameIndex << "\n";
}
if (this->_showLagFrameCount)
{
ss << "Lag Frame Count: " << this->_emuFrameInfo.lagFrameCount << "\n";
ss << "Lag Frame Count: " << this->_ndsFrameInfo.lagFrameCount << "\n";
}
if (this->_showCPULoadAverage)
{
static char buffer[32];
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, 25, "CPU Load Avg: %02d%% / %02d%%\n", this->_emuFrameInfo.cpuLoadAvgARM9, this->_emuFrameInfo.cpuLoadAvgARM7);
snprintf(buffer, 25, "CPU Load Avg: %02d%% / %02d%%\n", this->_ndsFrameInfo.cpuLoadAvgARM9, this->_ndsFrameInfo.cpuLoadAvgARM7);
ss << buffer;
}
if (this->_showRTC)
{
ss << "RTC: " << this->_emuFrameInfo.rtcString << "\n";
ss << "RTC: " << this->_ndsFrameInfo.rtcString << "\n";
}
this->_hudString = ss.str();
@ -445,9 +447,11 @@ void ClientDisplayView::CopyHUDFont(const FT_Face &fontFace, const size_t glyphS
// Do nothing. This is implementation dependent.
}
void ClientDisplayView::SetHUDInfo(const NDSFrameInfo &frameInfo)
void ClientDisplayView::SetHUDInfo(const ClientFrameInfo &clientFrameInfo, const NDSFrameInfo &ndsFrameInfo)
{
this->_emuFrameInfo = frameInfo;
this->_clientFrameInfo.videoFPS = clientFrameInfo.videoFPS;
this->_ndsFrameInfo.copyFrom(ndsFrameInfo);
this->_UpdateHUDString();
}
@ -756,9 +760,8 @@ void ClientDisplayView::SetEmuDisplayInfo(const NDSDisplayInfo &ndsDisplayInfo)
this->_emuDisplayInfo = ndsDisplayInfo;
}
void ClientDisplayView::HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo)
void ClientDisplayView::HandleEmulatorFrameEndEvent()
{
this->SetHUDInfo(frameInfo);
this->UpdateView();
}

View File

@ -23,6 +23,8 @@
#include "../../filter/videofilter.h"
#include "../../GPU.h"
#include "ClientExecutionControl.h"
#include <ft2build.h>
#include FT_FREETYPE_H
@ -97,17 +99,11 @@ struct LUTValues
};
typedef struct LUTValues LUTValues;
struct NDSFrameInfo
struct ClientFrameInfo
{
uint32_t videoFPS;
uint32_t render3DFPS;
uint32_t frameIndex;
uint32_t lagFrameCount;
uint32_t cpuLoadAvgARM9;
uint32_t cpuLoadAvgARM7;
char rtcString[25];
};
typedef struct NDSFrameInfo NDSFrameInfo;
typedef struct ClientFrameInfo ClientFrameInfo;
struct ClientDisplayViewProperties
{
@ -163,8 +159,10 @@ protected:
bool _showCPULoadAverage;
bool _showRTC;
ClientFrameInfo _clientFrameInfo;
NDSFrameInfo _ndsFrameInfo;
NDSDisplayInfo _emuDisplayInfo;
NDSFrameInfo _emuFrameInfo;
std::string _hudString;
bool _hudNeedsUpdate;
bool _allowViewUpdates;
@ -237,7 +235,7 @@ public:
void SetHUDFontPath(const char *filePath);
virtual void LoadHUDFont();
virtual void CopyHUDFont(const FT_Face &fontFace, const size_t glyphSize, const size_t glyphTileSize, GlyphInfo *glyphInfo);
virtual void SetHUDInfo(const NDSFrameInfo &frameInfo);
virtual void SetHUDInfo(const ClientFrameInfo &clientFrameInfo, const NDSFrameInfo &ndsFrameInfo);
const std::string& GetHUDString() const;
float GetHUDObjectScale() const;
@ -275,7 +273,7 @@ public:
// Emulator interface
const NDSDisplayInfo& GetEmuDisplayInfo() const;
void SetEmuDisplayInfo(const NDSDisplayInfo &ndsDisplayInfo);
virtual void HandleEmulatorFrameEndEvent(const NDSFrameInfo &frameInfo);
virtual void HandleEmulatorFrameEndEvent();
// Touch screen input handling
void GetNDSPoint(const int inputID, const bool isInitialTouchPress,

View File

@ -19,6 +19,9 @@
#include <mach/mach_time.h>
#include "NDSSystem.h"
#include "GPU.h"
#include "movie.h"
#include "rtc.h"
#include "ClientExecutionControl.h"
@ -35,40 +38,55 @@ ClientExecutionControl::ClientExecutionControl()
_framesToSkip = 0;
_prevExecBehavior = ExecutionBehavior_Pause;
_settingsPending.cpuEngineID = CPUEmulationEngineID_Interpreter;
_settingsPending.JITMaxBlockSize = 12;
_settingsPending.filePathARM9BIOS = std::string();
_settingsPending.filePathARM7BIOS = std::string();
_settingsPending.filePathFirmware = std::string();
_settingsPending.cpuEngineID = CPUEmulationEngineID_Interpreter;
_settingsPending.JITMaxBlockSize = 12;
_settingsPending.slot1DeviceType = NDS_SLOT1_RETAIL_AUTO;
_settingsPending.filePathARM9BIOS = std::string();
_settingsPending.filePathARM7BIOS = std::string();
_settingsPending.filePathFirmware = std::string();
_settingsPending.filePathSlot1R4 = std::string();
_settingsPending.cpuEmulationEngineName = "Interpreter";
_settingsPending.slot1DeviceName = "Uninitialized";
_settingsPending.enableAdvancedBusLevelTiming = true;
_settingsPending.enableRigorous3DRenderingTiming = false;
_settingsPending.enableGameSpecificHacks = true;
_settingsPending.enableExternalBIOS = false;
_settingsPending.enableBIOSInterrupts = false;
_settingsPending.enableBIOSPatchDelayLoop = false;
_settingsPending.enableExternalFirmware = false;
_settingsPending.enableFirmwareBoot = false;
_settingsPending.enableDebugConsole = false;
_settingsPending.enableEnsataEmulation = false;
_settingsPending.enableAdvancedBusLevelTiming = true;
_settingsPending.enableRigorous3DRenderingTiming = false;
_settingsPending.enableGameSpecificHacks = true;
_settingsPending.enableExternalBIOS = false;
_settingsPending.enableBIOSInterrupts = false;
_settingsPending.enableBIOSPatchDelayLoop = false;
_settingsPending.enableExternalFirmware = false;
_settingsPending.enableFirmwareBoot = false;
_settingsPending.enableDebugConsole = false;
_settingsPending.enableEnsataEmulation = false;
_settingsPending.enableExecutionSpeedLimiter = true;
_settingsPending.executionSpeed = SPEED_SCALAR_NORMAL;
_settingsPending.enableExecutionSpeedLimiter = true;
_settingsPending.executionSpeed = SPEED_SCALAR_NORMAL;
_settingsPending.enableFrameSkip = true;
_settingsPending.frameJumpTarget = 0;
_settingsPending.enableFrameSkip = true;
_settingsPending.frameJumpTarget = 0;
_settingsPending.execBehavior = ExecutionBehavior_Pause;
_settingsPending.jumpBehavior = FrameJumpBehavior_Forward;
_settingsPending.execBehavior = ExecutionBehavior_Pause;
_settingsPending.jumpBehavior = FrameJumpBehavior_Forward;
_settingsApplied = _settingsPending;
_settingsApplied.filePathARM9BIOS = std::string();
_settingsApplied.filePathARM7BIOS = std::string();
_settingsApplied.filePathFirmware = std::string();
_settingsApplied.filePathARM9BIOS = _settingsPending.filePathARM9BIOS;
_settingsApplied.filePathARM7BIOS = _settingsPending.filePathARM7BIOS;
_settingsApplied.filePathFirmware = _settingsPending.filePathFirmware;
_settingsApplied.filePathSlot1R4 = _settingsPending.filePathSlot1R4;
_settingsApplied.cpuEmulationEngineName = _settingsPending.cpuEmulationEngineName;
_settingsApplied.slot1DeviceName = _settingsPending.slot1DeviceName;
_ndsFrameInfo.clear();
_ndsFrameInfo.cpuEmulationEngineName = _settingsPending.cpuEmulationEngineName;
_ndsFrameInfo.slot1DeviceName = _settingsPending.slot1DeviceName;
_cpuEmulationEngineNameOut = _ndsFrameInfo.cpuEmulationEngineName;
_slot1DeviceNameOut = _ndsFrameInfo.slot1DeviceName;
pthread_mutex_init(&_mutexSettingsPendingOnReset, NULL);
pthread_mutex_init(&_mutexSettingsPendingOnExecutionLoopStart, NULL);
pthread_mutex_init(&_mutexSettingsPendingOnNDSExec, NULL);
pthread_mutex_init(&_mutexOutputPostNDSExec, NULL);
}
ClientExecutionControl::~ClientExecutionControl()
@ -76,6 +94,7 @@ ClientExecutionControl::~ClientExecutionControl()
pthread_mutex_destroy(&this->_mutexSettingsPendingOnReset);
pthread_mutex_destroy(&this->_mutexSettingsPendingOnExecutionLoopStart);
pthread_mutex_destroy(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_destroy(&this->_mutexOutputPostNDSExec);
}
CPUEmulationEngineID ClientExecutionControl::GetCPUEmulationEngineID()
@ -87,7 +106,16 @@ CPUEmulationEngineID ClientExecutionControl::GetCPUEmulationEngineID()
return engineID;
}
void ClientExecutionControl::SetCPUEmulationEngineID(CPUEmulationEngineID engineID)
const char* ClientExecutionControl::GetCPUEmulationEngineName()
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
this->_cpuEmulationEngineNameOut = this->_settingsPending.cpuEmulationEngineName;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
return this->_cpuEmulationEngineNameOut.c_str();
}
void ClientExecutionControl::SetCPUEmulationEngineByID(CPUEmulationEngineID engineID)
{
#if !defined(__i386__) && !defined(__x86_64__)
engineID = CPUEmulationEngine_Interpreter;
@ -96,6 +124,21 @@ void ClientExecutionControl::SetCPUEmulationEngineID(CPUEmulationEngineID engine
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
this->_settingsPending.cpuEngineID = engineID;
switch (engineID)
{
case CPUEmulationEngineID_Interpreter:
this->_settingsPending.cpuEmulationEngineName = "Interpreter";
break;
case CPUEmulationEngineID_DynamicRecompiler:
this->_settingsPending.cpuEmulationEngineName = "Dynamic Recompiler";
break;
default:
this->_settingsPending.cpuEmulationEngineName = "Unknown Engine";
break;
}
this->_newSettingsPendingOnReset = true;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
}
@ -127,6 +170,42 @@ void ClientExecutionControl::SetJITMaxBlockSize(uint8_t blockSize)
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
}
NDS_SLOT1_TYPE ClientExecutionControl::GetSlot1DeviceType()
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
const NDS_SLOT1_TYPE type = this->_settingsPending.slot1DeviceType;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
return type;
}
const char* ClientExecutionControl::GetSlot1DeviceName()
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
this->_slot1DeviceNameOut = this->_settingsPending.slot1DeviceName;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
return this->_slot1DeviceNameOut.c_str();
}
void ClientExecutionControl::SetSlot1DeviceByType(NDS_SLOT1_TYPE type)
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
this->_settingsPending.slot1DeviceType = type;
if ( (type < 0) || type >= (NDS_SLOT1_COUNT) )
{
this->_settingsPending.slot1DeviceName = "Uninitialized";
}
else
{
this->_settingsPending.slot1DeviceName = slot1_List[type]->info()->name();
}
this->_newSettingsPendingOnReset = true;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
}
const char* ClientExecutionControl::GetARM9ImagePath()
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
@ -205,6 +284,32 @@ void ClientExecutionControl::SetFirmwareImagePath(const char *filePath)
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
}
const char* ClientExecutionControl::GetSlot1R4Path()
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
const char *filePath = this->_settingsPending.filePathSlot1R4.c_str();
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
return filePath;
}
void ClientExecutionControl::SetSlot1R4Path(const char *filePath)
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
if (filePath == NULL)
{
this->_settingsPending.filePathSlot1R4.clear();
}
else
{
this->_settingsPending.filePathSlot1R4 = std::string(filePath);
}
this->_newSettingsPendingOnReset = true;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
}
bool ClientExecutionControl::GetEnableAdvancedBusLevelTiming()
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnNDSExec);
@ -558,12 +663,24 @@ void ClientExecutionControl::ApplySettingsOnReset()
if (this->_newSettingsPendingOnReset)
{
this->_settingsApplied.cpuEngineID = this->_settingsPending.cpuEngineID;
this->_settingsApplied.JITMaxBlockSize = this->_settingsPending.JITMaxBlockSize;
this->_settingsApplied.cpuEngineID = this->_settingsPending.cpuEngineID;
this->_settingsApplied.JITMaxBlockSize = this->_settingsPending.JITMaxBlockSize;
this->_settingsApplied.filePathARM9BIOS = this->_settingsPending.filePathARM9BIOS;
this->_settingsApplied.filePathARM7BIOS = this->_settingsPending.filePathARM7BIOS;
this->_settingsApplied.filePathFirmware = this->_settingsPending.filePathFirmware;
this->_settingsApplied.filePathARM9BIOS = this->_settingsPending.filePathARM9BIOS;
this->_settingsApplied.filePathARM7BIOS = this->_settingsPending.filePathARM7BIOS;
this->_settingsApplied.filePathFirmware = this->_settingsPending.filePathFirmware;
this->_settingsApplied.filePathSlot1R4 = this->_settingsPending.filePathSlot1R4;
this->_settingsApplied.cpuEmulationEngineName = this->_settingsPending.cpuEmulationEngineName;
this->_settingsApplied.slot1DeviceName = this->_settingsPending.slot1DeviceName;
this->_ndsFrameInfo.cpuEmulationEngineName = this->_settingsApplied.cpuEmulationEngineName;
this->_ndsFrameInfo.slot1DeviceName = this->_settingsApplied.slot1DeviceName;
const bool didChangeSlot1Type = (this->_settingsApplied.slot1DeviceType != this->_settingsPending.slot1DeviceType);
if (didChangeSlot1Type)
{
this->_settingsApplied.slot1DeviceType = this->_settingsPending.slot1DeviceType;
}
this->_newSettingsPendingOnReset = false;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
@ -597,6 +714,16 @@ void ClientExecutionControl::ApplySettingsOnReset()
{
strlcpy(CommonSettings.Firmware, this->_settingsApplied.filePathFirmware.c_str(), sizeof(CommonSettings.Firmware));
}
if (this->_settingsApplied.filePathSlot1R4.length() > 0)
{
slot1_SetFatDir(this->_settingsApplied.filePathSlot1R4);
}
if (didChangeSlot1Type)
{
slot1_Change(this->_settingsApplied.slot1DeviceType);
}
}
else
{
@ -705,6 +832,32 @@ void ClientExecutionControl::ApplySettingsOnNDSExec()
}
}
void ClientExecutionControl::FetchOutputPostNDSExec()
{
pthread_mutex_lock(&this->_mutexOutputPostNDSExec);
this->_ndsFrameInfo.frameIndex = currFrameCounter;
this->_ndsFrameInfo.render3DFPS = GPU->GetFPSRender3D();
this->_ndsFrameInfo.lagFrameCount = TotalLagFrames;
if ((this->_ndsFrameInfo.frameIndex & 0xF) == 0xF)
{
NDS_GetCPULoadAverage(this->_ndsFrameInfo.cpuLoadAvgARM9, this->_ndsFrameInfo.cpuLoadAvgARM7);
}
char *tempBuffer = (char *)calloc(25, sizeof(char));
rtcGetTimeAsString(tempBuffer);
this->_ndsFrameInfo.rtcString = tempBuffer;
free(tempBuffer);
pthread_mutex_unlock(&this->_mutexOutputPostNDSExec);
}
const NDSFrameInfo& ClientExecutionControl::GetNDSFrameInfo()
{
return this->_ndsFrameInfo;
}
double ClientExecutionControl::GetFrameTime()
{
return this->_frameTime;

View File

@ -21,6 +21,9 @@
#include <pthread.h>
#include <string>
#include "../../slot1.h"
#undef BOOL
#define SPEED_SCALAR_QUARTER 0.25 // Speed scalar for quarter execution speed.
#define SPEED_SCALAR_HALF 0.5 // Speed scalar for half execution speed.
#define SPEED_SCALAR_THREE_QUARTER 0.75 // Speed scalar for three quarters execution speed.
@ -61,9 +64,14 @@ typedef struct ClientExecutionControlSettings
{
CPUEmulationEngineID cpuEngineID;
uint8_t JITMaxBlockSize;
NDS_SLOT1_TYPE slot1DeviceType;
std::string filePathARM9BIOS;
std::string filePathARM7BIOS;
std::string filePathFirmware;
std::string filePathSlot1R4;
std::string cpuEmulationEngineName;
std::string slot1DeviceName;
bool enableAdvancedBusLevelTiming;
bool enableRigorous3DRenderingTiming;
@ -89,12 +97,51 @@ typedef struct ClientExecutionControlSettings
} ClientExecutionControlSettings;
struct NDSFrameInfo
{
std::string cpuEmulationEngineName;
std::string slot1DeviceName;
std::string rtcString;
uint64_t frameIndex;
uint32_t render3DFPS;
uint32_t lagFrameCount;
uint32_t cpuLoadAvgARM9;
uint32_t cpuLoadAvgARM7;
void clear()
{
this->cpuEmulationEngineName = std::string();
this->slot1DeviceName = std::string();
this->rtcString = std::string();
this->frameIndex = 0;
this->render3DFPS = 0;
this->lagFrameCount = 0;
this->cpuLoadAvgARM9 = 0;
this->cpuLoadAvgARM7 = 0;
}
void copyFrom(const NDSFrameInfo &fromObject)
{
this->cpuEmulationEngineName = fromObject.cpuEmulationEngineName;
this->slot1DeviceName = fromObject.slot1DeviceName;
this->rtcString = fromObject.rtcString;
this->frameIndex = fromObject.frameIndex;
this->render3DFPS = fromObject.render3DFPS;
this->lagFrameCount = fromObject.lagFrameCount;
this->cpuLoadAvgARM9 = fromObject.cpuLoadAvgARM9;
this->cpuLoadAvgARM7 = fromObject.cpuLoadAvgARM7;
}
};
class ClientExecutionControl
{
private:
ClientExecutionControlSettings _settingsPending;
ClientExecutionControlSettings _settingsApplied;
NDSFrameInfo _ndsFrameInfo;
bool _newSettingsPendingOnReset;
bool _newSettingsPendingOnExecutionLoopStart;
bool _newSettingsPendingOnNDSExec;
@ -105,20 +152,30 @@ private:
uint8_t _framesToSkip;
ExecutionBehavior _prevExecBehavior;
std::string _cpuEmulationEngineNameOut;
std::string _slot1DeviceNameOut;
std::string _rtcStringOut;
pthread_mutex_t _mutexSettingsPendingOnReset;
pthread_mutex_t _mutexSettingsPendingOnExecutionLoopStart;
pthread_mutex_t _mutexSettingsPendingOnNDSExec;
pthread_mutex_t _mutexOutputPostNDSExec;
public:
ClientExecutionControl();
~ClientExecutionControl();
CPUEmulationEngineID GetCPUEmulationEngineID();
void SetCPUEmulationEngineID(CPUEmulationEngineID engineID);
const char* GetCPUEmulationEngineName();
void SetCPUEmulationEngineByID(CPUEmulationEngineID engineID);
uint8_t GetJITMaxBlockSize();
void SetJITMaxBlockSize(uint8_t blockSize);
NDS_SLOT1_TYPE GetSlot1DeviceType();
const char* GetSlot1DeviceName();
void SetSlot1DeviceByType(NDS_SLOT1_TYPE type);
const char* GetARM9ImagePath();
void SetARM9ImagePath(const char *filePath);
@ -128,6 +185,9 @@ public:
const char* GetFirmwareImagePath();
void SetFirmwareImagePath(const char *filePath);
const char* GetSlot1R4Path();
void SetSlot1R4Path(const char *filePath);
bool GetEnableAdvancedBusLevelTiming();
void SetEnableAdvancedBusLevelTiming(bool enable);
@ -191,6 +251,9 @@ public:
void ApplySettingsOnExecutionLoopStart();
void ApplySettingsOnNDSExec();
void FetchOutputPostNDSExec();
const NDSFrameInfo& GetNDSFrameInfo();
double GetFrameTime();
uint8_t CalculateFrameSkip(double startAbsoluteTime, double frameAbsoluteTime);

View File

@ -37,7 +37,6 @@
class OGLVideoOutput;
struct NDSFrameInfo;
enum ShaderSupportTier
{

View File

@ -53,8 +53,6 @@ typedef struct
pthread_t coreThread;
CoreThreadParam threadParam;
std::string _slot1R4Path;
NSTimer *_fpsTimer;
BOOL _isTimerAtSecond;
@ -67,13 +65,10 @@ typedef struct
volatile gdbstub_handle_t gdbStubHandleARM9;
volatile gdbstub_handle_t gdbStubHandleARM7;
NSInteger slot1DeviceType;
NSString *slot1StatusText;
NSString *frameStatus;
NSString *executionSpeedStatus;
NSURL *slot1R4URL;
OSSpinLock spinlockCdsController;
OSSpinLock spinlockMasterExecute;
}
@ -120,7 +115,7 @@ typedef struct
@property (copy) NSURL *arm9ImageURL;
@property (copy) NSURL *arm7ImageURL;
@property (copy) NSURL *firmwareImageURL;
@property (retain) NSURL *slot1R4URL;
@property (copy) NSURL *slot1R4URL;
@property (readonly) pthread_rwlock_t *rwlockCoreExecute;
@ -129,7 +124,7 @@ typedef struct
- (void) changeRomSaveType:(NSInteger)saveTypeID;
- (void) updateExecutionSpeedStatus;
- (BOOL) applySlot1Device;
- (void) updateSlot1DeviceStatus;
- (void) restoreCoreState;
- (void) reset;

View File

@ -108,7 +108,7 @@ volatile bool execute = true;
@dynamic emuFlagEmulateEnsata;
@dynamic cpuEmulationEngine;
@dynamic maxJITBlockSize;
@synthesize slot1DeviceType;
@dynamic slot1DeviceType;
@synthesize slot1StatusText;
@synthesize frameStatus;
@synthesize executionSpeedStatus;
@ -116,7 +116,7 @@ volatile bool execute = true;
@dynamic arm9ImageURL;
@dynamic arm7ImageURL;
@dynamic firmwareImageURL;
@synthesize slot1R4URL;
@dynamic slot1R4URL;
@dynamic rwlockCoreExecute;
@ -155,15 +155,11 @@ volatile bool execute = true;
cdsGPU = [[[[CocoaDSGPU alloc] init] autorelease] retain];
cdsOutputList = [[[[NSMutableArray alloc] initWithCapacity:32] autorelease] retain];
slot1DeviceType = NDS_SLOT1_RETAIL_AUTO;
slot1StatusText = NSSTRING_STATUS_EMULATION_NOT_RUNNING;
spinlockMasterExecute = OS_SPINLOCK_INIT;
spinlockCdsController = OS_SPINLOCK_INIT;
slot1R4URL = nil;
_slot1R4Path = "";
threadParam.cdsCore = self;
pthread_mutex_init(&threadParam.mutexOutputList, NULL);
@ -531,7 +527,7 @@ volatile bool execute = true;
- (void) setCpuEmulationEngine:(NSInteger)engineID
{
execControl->SetCPUEmulationEngineID((CPUEmulationEngineID)engineID);
execControl->SetCPUEmulationEngineByID((CPUEmulationEngineID)engineID);
}
- (NSInteger) cpuEmulationEngine
@ -549,6 +545,16 @@ volatile bool execute = true;
return (NSInteger)execControl->GetJITMaxBlockSize();
}
- (void) setSlot1DeviceType:(NSInteger)theType
{
execControl->SetSlot1DeviceByType((NDS_SLOT1_TYPE)theType);
}
- (NSInteger) slot1DeviceType
{
return (NSInteger)execControl->GetSlot1DeviceType();
}
- (void) setCoreState:(NSInteger)coreState
{
pthread_mutex_lock(&threadParam.mutexThreadExecute);
@ -680,6 +686,18 @@ volatile bool execute = true;
return [NSURL fileURLWithPath:[NSString stringWithCString:filePath encoding:NSUTF8StringEncoding]];
}
- (void) setSlot1R4URL:(NSURL *)fileURL
{
const char *filePath = (fileURL != NULL) ? [[fileURL path] cStringUsingEncoding:NSUTF8StringEncoding] : NULL;
execControl->SetSlot1R4Path(filePath);
}
- (NSURL *) slot1R4URL
{
const char *filePath = execControl->GetSlot1R4Path();
return [NSURL fileURLWithPath:[NSString stringWithCString:filePath encoding:NSUTF8StringEncoding]];
}
- (pthread_rwlock_t *) rwlockCoreExecute
{
return &threadParam.rwlockCoreExecute;
@ -719,19 +737,9 @@ volatile bool execute = true;
}
}
- (BOOL) applySlot1Device
- (void) updateSlot1DeviceStatus
{
const NSInteger deviceTypeID = [self slot1DeviceType];
NSString *r4Path = [[self slot1R4URL] path];
pthread_mutex_lock(&threadParam.mutexThreadExecute);
_slot1R4Path = (r4Path != nil) ? std::string([r4Path cStringUsingEncoding:NSUTF8StringEncoding]) : "";
slot1_SetFatDir(_slot1R4Path);
BOOL result = slot1_Change((NDS_SLOT1_TYPE)deviceTypeID);
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
const NDS_SLOT1_TYPE deviceTypeID = execControl->GetSlot1DeviceType();
switch (deviceTypeID)
{
@ -759,8 +767,6 @@ volatile bool execute = true;
[self setSlot1StatusText:NSSTRING_STATUS_SLOT1_UNKNOWN_STATE];
break;
}
return result;
}
- (void) restoreCoreState
@ -771,13 +777,13 @@ volatile bool execute = true;
- (void) reset
{
[self setCoreState:ExecutionBehavior_Pause];
[self applySlot1Device];
pthread_mutex_lock(&threadParam.mutexThreadExecute);
execControl->ApplySettingsOnReset();
NDS_Reset();
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
[self updateSlot1DeviceStatus];
[self restoreCoreState];
[self setMasterExecute:YES];
[[self cdsController] reset];
@ -786,13 +792,6 @@ volatile bool execute = true;
- (void) getTimedEmulatorStatistics:(NSTimer *)timer
{
uint32_t loadAvgARM9;
uint32_t loadAvgARM7;
pthread_rwlock_rdlock(&threadParam.rwlockCoreExecute);
NDS_GetCPULoadAverage(loadAvgARM9, loadAvgARM7);
pthread_rwlock_unlock(&threadParam.rwlockCoreExecute);
// The timer should fire every 0.5 seconds, so only take the frame
// count every other instance the timer fires.
_isTimerAtSecond = !_isTimerAtSecond;
@ -805,8 +804,6 @@ volatile bool execute = true;
{
[(CocoaDSDisplay *)cdsOutput takeFrameCount];
}
[(CocoaDSDisplay *)cdsOutput setCPULoadAvgARM9:loadAvgARM9 ARM7:loadAvgARM7];
}
}
}
@ -868,43 +865,12 @@ volatile bool execute = true;
- (NSString *) cpuEmulationEngineString
{
NSString *theString = @"Uninitialized";
switch ([self cpuEmulationEngine])
{
case CPUEmulationEngineID_Interpreter:
theString = @"Interpreter";
break;
case CPUEmulationEngineID_DynamicRecompiler:
theString = @"Dynamic Recompiler";
break;
default:
break;
}
return theString;
return [NSString stringWithCString:execControl->GetCPUEmulationEngineName() encoding:NSUTF8StringEncoding];
}
- (NSString *) slot1DeviceTypeString
{
NSString *theString = @"Uninitialized";
pthread_mutex_lock(&threadParam.mutexThreadExecute);
if(slot1_device == NULL)
{
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
return theString;
}
const Slot1Info *info = slot1_device->info();
theString = [NSString stringWithCString:info->name() encoding:NSUTF8StringEncoding];
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
return theString;
return [NSString stringWithCString:execControl->GetSlot1DeviceName() encoding:NSUTF8StringEncoding];
}
- (NSString *) slot2DeviceTypeString
@ -913,7 +879,7 @@ volatile bool execute = true;
pthread_mutex_lock(&threadParam.mutexThreadExecute);
if(slot2_device == NULL)
if (slot2_device == NULL)
{
pthread_mutex_unlock(&threadParam.mutexThreadExecute);
return theString;
@ -978,7 +944,8 @@ static void* RunCoreThread(void *arg)
CocoaDSCore *cdsCore = (CocoaDSCore *)param->cdsCore;
ClientExecutionControl *execControl = [cdsCore execControl];
NSMutableArray *cdsOutputList = [cdsCore cdsOutputList];
uint64_t frameNum = 0;
const NDSFrameInfo &ndsFrameInfo = execControl->GetNDSFrameInfo();
double startTime = 0;
double frameTime = 0; // The amount of time that is expected for the frame to run.
@ -1025,7 +992,7 @@ static void* RunCoreThread(void *arg)
// Execute the frame and increment the frame counter.
pthread_rwlock_wrlock(&param->rwlockCoreExecute);
NDS_exec<false>();
frameNum = (uint64_t)currFrameCounter;
execControl->FetchOutputPostNDSExec();
pthread_rwlock_unlock(&param->rwlockCoreExecute);
// Check if an internal execution error occurred that halted the emulation.
@ -1054,6 +1021,11 @@ static void* RunCoreThread(void *arg)
{
for (CocoaDSOutput *cdsOutput in cdsOutputList)
{
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]])
{
[(CocoaDSDisplay *)cdsOutput setNDSFrameInfo:ndsFrameInfo];
}
if ( ![cdsOutput isKindOfClass:[CocoaDSDisplay class]] || (framesToSkip == 0) )
{
[cdsOutput doCoreEmuFrame];
@ -1115,11 +1087,11 @@ static void* RunCoreThread(void *arg)
}
else if (behavior == ExecutionBehavior_FrameJump)
{
if (frameNum == (frameJumpTarget - 1))
if (ndsFrameInfo.frameIndex == (frameJumpTarget - 1))
{
execControl->ResetFramesToSkip();
}
else if (frameNum >= frameJumpTarget)
else if (ndsFrameInfo.frameIndex >= frameJumpTarget)
{
[cdsCore restoreCoreState];
}

View File

@ -22,13 +22,12 @@
#import "cocoa_util.h"
#include "ClientDisplayView.h"
#include "ClientExecutionControl.h"
#undef BOOL
@class NSImage;
@class NSBitmapImageRep;
struct NDSFrameInfo;
@interface CocoaDSOutput : CocoaDSThread
{
NSMutableDictionary *property;
@ -105,11 +104,10 @@ struct NDSFrameInfo;
uint32_t _currentReceivedFrameIndex;
uint32_t _receivedFrameCount;
uint32_t _cpuLoadAvgARM9;
uint32_t _cpuLoadAvgARM7;
NDSFrameInfo _ndsFrameInfo;
OSSpinLock spinlockReceivedFrameIndex;
OSSpinLock spinlockCPULoadAverage;
OSSpinLock spinlockNDSFrameInfo;
OSSpinLock spinlockViewProperties;
}
@ -124,7 +122,7 @@ struct NDSFrameInfo;
- (void) handleCopyToPasteboard;
- (void) takeFrameCount;
- (void) setCPULoadAvgARM9:(uint32_t)loadAvgARM9 ARM7:(uint32_t)loadAvgARM7;
- (void) setNDSFrameInfo:(const NDSFrameInfo &)ndsFrameInfo;
- (NSImage *) image;
- (NSBitmapImageRep *) bitmapImageRep;

View File

@ -513,17 +513,15 @@
}
spinlockReceivedFrameIndex = OS_SPINLOCK_INIT;
spinlockCPULoadAverage = OS_SPINLOCK_INIT;
spinlockNDSFrameInfo = OS_SPINLOCK_INIT;
spinlockViewProperties = OS_SPINLOCK_INIT;
_cdv = NULL;
_ndsFrameInfo.clear();
_receivedFrameIndex = 0;
_currentReceivedFrameIndex = 0;
_receivedFrameCount = 0;
_cpuLoadAvgARM9 = 0;
_cpuLoadAvgARM7 = 0;
return self;
}
@ -645,12 +643,11 @@
OSSpinLockUnlock(&spinlockReceivedFrameIndex);
}
- (void) setCPULoadAvgARM9:(uint32_t)loadAvgARM9 ARM7:(uint32_t)loadAvgARM7
- (void) setNDSFrameInfo:(const NDSFrameInfo &)ndsFrameInfo
{
OSSpinLockLock(&spinlockCPULoadAverage);
_cpuLoadAvgARM9 = loadAvgARM9;
_cpuLoadAvgARM7 = loadAvgARM7;
OSSpinLockUnlock(&spinlockCPULoadAverage);
OSSpinLockLock(&spinlockNDSFrameInfo);
_ndsFrameInfo.copyFrom(ndsFrameInfo);
OSSpinLockUnlock(&spinlockNDSFrameInfo);
}
- (NSImage *) image
@ -1038,23 +1035,16 @@
{
[super handleEmuFrameProcessed];
NDSFrameInfo frameInfo;
frameInfo.render3DFPS = GPU->GetFPSRender3D();
frameInfo.frameIndex = currFrameCounter;
frameInfo.lagFrameCount = TotalLagFrames;
OSSpinLockLock(&spinlockReceivedFrameIndex);
frameInfo.videoFPS = _receivedFrameCount;
ClientFrameInfo clientFrameInfo;
clientFrameInfo.videoFPS = _receivedFrameCount;
OSSpinLockUnlock(&spinlockReceivedFrameIndex);
OSSpinLockLock(&spinlockCPULoadAverage);
frameInfo.cpuLoadAvgARM9 = _cpuLoadAvgARM9;
frameInfo.cpuLoadAvgARM7 = _cpuLoadAvgARM7;
OSSpinLockUnlock(&spinlockCPULoadAverage);
OSSpinLockLock(&spinlockNDSFrameInfo);
_cdv->SetHUDInfo(clientFrameInfo, _ndsFrameInfo);
OSSpinLockUnlock(&spinlockNDSFrameInfo);
rtcGetTimeAsString(frameInfo.rtcString);
_cdv->HandleEmulatorFrameEndEvent(frameInfo);
_cdv->HandleEmulatorFrameEndEvent();
}
- (void) handleReceiveGPUFrame

View File

@ -1683,7 +1683,7 @@
CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content];
[cdsCore execControl]->ApplySettingsOnReset();
[cdsCore applySlot1Device];
[cdsCore updateSlot1DeviceStatus];
[self writeDefaultsSlot1Settings:nil];
CocoaDSRom *newRom = [[CocoaDSRom alloc] init];

View File

@ -152,17 +152,22 @@ void slot1_Reset()
bool slot1_Change(NDS_SLOT1_TYPE changeToType)
{
if((changeToType == slot1_device_type) || (changeToType == slot1_GetSelectedType()))
return FALSE; //nothing to do
if (changeToType > NDS_SLOT1_COUNT || changeToType < 0) return FALSE;
if(slot1_device != NULL)
if ( (changeToType == slot1_device_type) || (changeToType == slot1_GetSelectedType()) )
return false; //nothing to do
if ( (changeToType >= NDS_SLOT1_COUNT) || (changeToType < 0) )
return false;
if (slot1_device != NULL)
slot1_device->disconnect();
slot1_device_type = changeToType;
slot1_device = slot1_List[slot1_device_type];
printf("Slot 1: %s\n", slot1_device->info()->name());
printf("sending eject signal to SLOT-1\n");
NDS_TriggerCardEjectIRQ();
slot1_device->connect();
return true;
}