From 9f6f8c1cfd26587b9a06cf5702449386ed68f54e Mon Sep 17 00:00:00 2001 From: rogerman Date: Fri, 31 Jan 2014 08:31:20 +0000 Subject: [PATCH] Cocoa Port: - Optimize the emulator idle state to achieve 0% CPU usage. This greatly reduces the app's energy usage when the emulator is idle. Cocoa Port (OpenEmu Plug-in): - Remove some dependencies needed to compile the OpenEmu plug-in. --- .../project.pbxproj | 8 -- .../project.pbxproj | 10 -- desmume/src/cocoa/cocoa_core.h | 6 +- desmume/src/cocoa/cocoa_core.mm | 108 ++++++++---------- desmume/src/cocoa/cocoa_output.mm | 15 +++ desmume/src/cocoa/cocoa_util.h | 8 +- desmume/src/cocoa/cocoa_util.mm | 37 ++++++ desmume/src/cocoa/coreaudiosound.cpp | 14 +++ desmume/src/cocoa/coreaudiosound.h | 2 + desmume/src/cocoa/openemu/NDSGameCore.mm | 9 +- desmume/src/cocoa/sndOSX.cpp | 21 ++++ desmume/src/cocoa/sndOSX.h | 2 + .../src/cocoa/userinterface/appDelegate.mm | 9 -- 13 files changed, 152 insertions(+), 97 deletions(-) diff --git a/desmume/src/cocoa/DeSmuME (XCode 4).xcodeproj/project.pbxproj b/desmume/src/cocoa/DeSmuME (XCode 4).xcodeproj/project.pbxproj index 9f7d60bfc..080076dc1 100644 --- a/desmume/src/cocoa/DeSmuME (XCode 4).xcodeproj/project.pbxproj +++ b/desmume/src/cocoa/DeSmuME (XCode 4).xcodeproj/project.pbxproj @@ -12,7 +12,6 @@ AB00E87E14205EBC00DE561F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB00E87C14205EBC00DE561F /* MainMenu.xib */; }; AB01005E170D07B000D70FBE /* InputProfileController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB01005D170D07B000D70FBE /* InputProfileController.mm */; }; AB01005F170D07B000D70FBE /* InputProfileController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB01005D170D07B000D70FBE /* InputProfileController.mm */; }; - AB010060170D07B000D70FBE /* InputProfileController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB01005D170D07B000D70FBE /* InputProfileController.mm */; }; AB02475C13886BF300E9F9AB /* KeyNames.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB02475B13886BF300E9F9AB /* KeyNames.plist */; }; AB0F290214BE6E68009ABC6F /* Icon_Execute_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = AB0F28FE14BE6E68009ABC6F /* Icon_Execute_420x420.png */; }; AB0F290314BE6E68009ABC6F /* Icon_Pause_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = AB0F28FF14BE6E68009ABC6F /* Icon_Pause_420x420.png */; }; @@ -197,8 +196,6 @@ AB4FCEBD1692AB82000F498F /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB4FCEBC1692AB82000F498F /* Accelerate.framework */; }; AB4FCEBE1692AB82000F498F /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB4FCEBC1692AB82000F498F /* Accelerate.framework */; }; AB4FCEBF1692AB82000F498F /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB4FCEBC1692AB82000F498F /* Accelerate.framework */; }; - AB5785F817175F16002C5FC7 /* cocoa_core.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104121346652500AF11D1 /* cocoa_core.mm */; }; - AB5785F9171760D2002C5FC7 /* cocoa_output.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3E34C8134AF4500056477A /* cocoa_output.mm */; }; AB5785FD17176AFC002C5FC7 /* OpenEmuBase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB5785FC17176AFC002C5FC7 /* OpenEmuBase.framework */; }; AB58F32D1364F44B0074C376 /* cocoa_file.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB58F32C1364F44B0074C376 /* cocoa_file.mm */; }; AB64987C13ECC73800EE7DD2 /* FileTypeInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB64987B13ECC73800EE7DD2 /* FileTypeInfo.plist */; }; @@ -444,7 +441,6 @@ ABB3C6721501C04F00E0C22E /* cocoa_file.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB58F32C1364F44B0074C376 /* cocoa_file.mm */; }; ABB3C6751501C04F00E0C22E /* cocoa_rom.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104131346652500AF11D1 /* cocoa_rom.mm */; }; ABB3C6761501C04F00E0C22E /* cocoa_util.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB80E04C142BC4A800A52038 /* cocoa_util.mm */; }; - ABB3C6771501C04F00E0C22E /* cocoa_videofilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */; }; ABB3C6781501C04F00E0C22E /* slot1_none.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF001345AC9B00AF11D1 /* slot1_none.cpp */; }; ABB3C6791501C04F00E0C22E /* slot1_r4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF011345AC9B00AF11D1 /* slot1_r4.cpp */; }; ABB3C67A1501C04F00E0C22E /* slot1_retail_nand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB6FBEF5139B6258007BB045 /* slot1_retail_nand.cpp */; }; @@ -2662,7 +2658,6 @@ ABB3C6721501C04F00E0C22E /* cocoa_file.mm in Sources */, ABB3C6751501C04F00E0C22E /* cocoa_rom.mm in Sources */, ABB3C6761501C04F00E0C22E /* cocoa_util.mm in Sources */, - ABB3C6771501C04F00E0C22E /* cocoa_videofilter.mm in Sources */, ABB3C6781501C04F00E0C22E /* slot1_none.cpp in Sources */, ABB3C6791501C04F00E0C22E /* slot1_r4.cpp in Sources */, ABB3C67A1501C04F00E0C22E /* slot1_retail_nand.cpp in Sources */, @@ -2790,13 +2785,10 @@ AB68A0DD16B139BC00DE0546 /* OGLRender_3_2.cpp in Sources */, AB3A656316CC5438001F5D4A /* cocoa_GPU.mm in Sources */, AB82445D1704AE9A00B8EE20 /* utilities.c in Sources */, - AB010060170D07B000D70FBE /* InputProfileController.mm in Sources */, ABD10AE91715FCDD00B5729D /* audiosamplegenerator.cpp in Sources */, ABD10AEC1715FCDD00B5729D /* mic_ext.cpp in Sources */, ABD10AED17160C9300B5729D /* ringbuffer.cpp in Sources */, ABD10AEE17160CDD00B5729D /* cocoa_input.mm in Sources */, - AB5785F817175F16002C5FC7 /* cocoa_core.mm in Sources */, - AB5785F9171760D2002C5FC7 /* cocoa_output.mm in Sources */, ABD798CA178C7B9000089F19 /* encrypt.cpp in Sources */, ABFE7C8417C5CFE70028DC56 /* advanscene.cpp in Sources */, ABFE7C8D17C5D03C0028DC56 /* slot1_retail_auto.cpp in Sources */, diff --git a/desmume/src/cocoa/DeSmuME (Xcode 5).xcodeproj/project.pbxproj b/desmume/src/cocoa/DeSmuME (Xcode 5).xcodeproj/project.pbxproj index 5fc90e20f..cf9da5235 100644 --- a/desmume/src/cocoa/DeSmuME (Xcode 5).xcodeproj/project.pbxproj +++ b/desmume/src/cocoa/DeSmuME (Xcode 5).xcodeproj/project.pbxproj @@ -14,7 +14,6 @@ AB00E87E14205EBC00DE561F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB00E87C14205EBC00DE561F /* MainMenu.xib */; }; AB01005E170D07B000D70FBE /* InputProfileController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB01005D170D07B000D70FBE /* InputProfileController.mm */; }; AB01005F170D07B000D70FBE /* InputProfileController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB01005D170D07B000D70FBE /* InputProfileController.mm */; }; - AB010060170D07B000D70FBE /* InputProfileController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB01005D170D07B000D70FBE /* InputProfileController.mm */; }; AB02475C13886BF300E9F9AB /* KeyNames.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB02475B13886BF300E9F9AB /* KeyNames.plist */; }; AB031B5518472F3100541888 /* cocoa_cheat.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */; }; AB0F290214BE6E68009ABC6F /* Icon_Execute_420x420.png in Resources */ = {isa = PBXBuildFile; fileRef = AB0F28FE14BE6E68009ABC6F /* Icon_Execute_420x420.png */; }; @@ -212,8 +211,6 @@ AB564913186E6F67002740F4 /* Image_PassME.png in Resources */ = {isa = PBXBuildFile; fileRef = AB56490A186E6F67002740F4 /* Image_PassME.png */; }; AB564914186E6F67002740F4 /* Image_Piano.png in Resources */ = {isa = PBXBuildFile; fileRef = AB56490B186E6F67002740F4 /* Image_Piano.png */; }; AB564915186E6F67002740F4 /* Image_Piano.png in Resources */ = {isa = PBXBuildFile; fileRef = AB56490B186E6F67002740F4 /* Image_Piano.png */; }; - AB5785F817175F16002C5FC7 /* cocoa_core.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104121346652500AF11D1 /* cocoa_core.mm */; }; - AB5785F9171760D2002C5FC7 /* cocoa_output.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3E34C8134AF4500056477A /* cocoa_output.mm */; }; AB5785FD17176AFC002C5FC7 /* OpenEmuBase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB5785FC17176AFC002C5FC7 /* OpenEmuBase.framework */; }; AB58F32D1364F44B0074C376 /* cocoa_file.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB58F32C1364F44B0074C376 /* cocoa_file.mm */; }; AB64987C13ECC73800EE7DD2 /* FileTypeInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB64987B13ECC73800EE7DD2 /* FileTypeInfo.plist */; }; @@ -484,8 +481,6 @@ ABB3C6701501C04F00E0C22E /* videofilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB817A35143EE2DB00A7DFE9 /* videofilter.cpp */; }; ABB3C6721501C04F00E0C22E /* cocoa_file.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB58F32C1364F44B0074C376 /* cocoa_file.mm */; }; ABB3C6751501C04F00E0C22E /* cocoa_rom.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD104131346652500AF11D1 /* cocoa_rom.mm */; }; - ABB3C6761501C04F00E0C22E /* cocoa_util.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB80E04C142BC4A800A52038 /* cocoa_util.mm */; }; - ABB3C6771501C04F00E0C22E /* cocoa_videofilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE5DFE4143FB1DA00835AD8 /* cocoa_videofilter.mm */; }; ABB3C6781501C04F00E0C22E /* slot1_none.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF001345AC9B00AF11D1 /* slot1_none.cpp */; }; ABB3C6791501C04F00E0C22E /* slot1_r4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF011345AC9B00AF11D1 /* slot1_r4.cpp */; }; ABB3C67A1501C04F00E0C22E /* slot1_retail_nand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB6FBEF5139B6258007BB045 /* slot1_retail_nand.cpp */; }; @@ -2664,8 +2659,6 @@ ABB3C6721501C04F00E0C22E /* cocoa_file.mm in Sources */, ABB3C6751501C04F00E0C22E /* cocoa_rom.mm in Sources */, AB29B16418313AF5009B7982 /* slot2.cpp in Sources */, - ABB3C6761501C04F00E0C22E /* cocoa_util.mm in Sources */, - ABB3C6771501C04F00E0C22E /* cocoa_videofilter.mm in Sources */, ABB3C6781501C04F00E0C22E /* slot1_none.cpp in Sources */, AB29B16818313C14009B7982 /* slot2_auto.cpp in Sources */, AB9038B417C5ED2200F410BD /* slot1_retail_mcrom.cpp in Sources */, @@ -2804,13 +2797,10 @@ AB9038B717C5ED2200F410BD /* slot1comp_mc.cpp in Sources */, AB3A656316CC5438001F5D4A /* cocoa_GPU.mm in Sources */, AB82445D1704AE9A00B8EE20 /* utilities.c in Sources */, - AB010060170D07B000D70FBE /* InputProfileController.mm in Sources */, ABD10AE91715FCDD00B5729D /* audiosamplegenerator.cpp in Sources */, ABD10AEC1715FCDD00B5729D /* mic_ext.cpp in Sources */, ABD10AED17160C9300B5729D /* ringbuffer.cpp in Sources */, ABD10AEE17160CDD00B5729D /* cocoa_input.mm in Sources */, - AB5785F817175F16002C5FC7 /* cocoa_core.mm in Sources */, - AB5785F9171760D2002C5FC7 /* cocoa_output.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/desmume/src/cocoa/cocoa_core.h b/desmume/src/cocoa/cocoa_core.h index 9d4a85546..3b302074f 100644 --- a/desmume/src/cocoa/cocoa_core.h +++ b/desmume/src/cocoa/cocoa_core.h @@ -45,7 +45,7 @@ typedef struct pthread_cond_t condThreadExecute; } CoreThreadParam; -@interface CocoaDSCore : CocoaDSThread +@interface CocoaDSCore : NSObject { CocoaDSController *cdsController; CocoaDSFirmware *cdsFirmware; @@ -123,10 +123,6 @@ typedef struct @property (readonly) pthread_mutex_t *mutexCoreExecute; -+ (BOOL) startupCore; -+ (void) shutdownCore; -+ (BOOL) isCoreStarted; - - (BOOL) ejectCardFlag; - (void) setEjectCardFlag; - (void) slot1Eject; diff --git a/desmume/src/cocoa/cocoa_core.mm b/desmume/src/cocoa/cocoa_core.mm index 9c77fba63..d35a11816 100644 --- a/desmume/src/cocoa/cocoa_core.mm +++ b/desmume/src/cocoa/cocoa_core.mm @@ -1,6 +1,6 @@ /* Copyright (C) 2011 Roger Manuel - Copyright (C) 2011-2013 DeSmuME team + Copyright (C) 2011-2014 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 @@ -76,8 +76,6 @@ volatile bool execute = true; @dynamic mutexCoreExecute; -static BOOL isCoreStarted = NO; - - (id)init { self = [super init]; @@ -86,6 +84,14 @@ static BOOL isCoreStarted = NO; return self; } + int initResult = NDS_Init(); + if (initResult == -1) + { + [self release]; + self = nil; + return self; + } + cdsController = nil; cdsFirmware = nil; cdsGPU = [[[[CocoaDSGPU alloc] init] autorelease] retain]; @@ -150,18 +156,6 @@ static BOOL isCoreStarted = NO; { [self setCoreState:CORESTATE_PAUSE]; - // Exit the thread. - if (self.thread != nil) - { - self.threadExit = YES; - - // Wait until the thread has shut down. - while (self.thread != nil) - { - [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; - } - } - pthread_mutex_lock(&threadParam.mutexThreadExecute); threadParam.exitThread = true; pthread_cond_signal(&threadParam.condThreadExecute); @@ -182,44 +176,11 @@ static BOOL isCoreStarted = NO; pthread_mutex_destroy(&threadParam.mutexOutputList); pthread_mutex_destroy(&threadParam.mutexCoreExecute); + NDS_DeInit(); + [super dealloc]; } -+ (BOOL) startupCore -{ - NSInteger result = -1; - - if (isCoreStarted) - { - return isCoreStarted; - } - - result = NDS_Init(); - if (result == -1) - { - isCoreStarted = NO; - return isCoreStarted; - } - - isCoreStarted = YES; - - return isCoreStarted; -} - -+ (void) shutdownCore -{ - if (isCoreStarted) - { - NDS_DeInit(); - isCoreStarted = NO; - } -} - -+ (BOOL) isCoreStarted -{ - return isCoreStarted; -} - - (void) setMasterExecute:(BOOL)theState { OSSpinLockLock(&spinlockMasterExecute); @@ -515,17 +476,51 @@ static BOOL isCoreStarted = NO; switch (coreState) { case CORESTATE_PAUSE: - case CORESTATE_FRAMEADVANCE: - [self setFrameStatus:[NSString stringWithFormat:@"%lld", (unsigned long)[self frameNumber]]]; + { + for(CocoaDSOutput *cdsOutput in cdsOutputList) + { + [cdsOutput setIdle:YES]; + } + + [self setFrameStatus:[NSString stringWithFormat:@"%lu", (unsigned long)[self frameNumber]]]; break; + } + + case CORESTATE_FRAMEADVANCE: + { + for(CocoaDSOutput *cdsOutput in cdsOutputList) + { + [cdsOutput setIdle:NO]; + } + + [self setFrameStatus:[NSString stringWithFormat:@"%lu", (unsigned long)[self frameNumber]]]; + break; + } case CORESTATE_EXECUTE: + { + for(CocoaDSOutput *cdsOutput in cdsOutputList) + { + [cdsOutput setIdle:NO]; + } + [self setFrameStatus:@"Executing..."]; break; + } case CORESTATE_FRAMEJUMP: - [self setFrameStatus:[NSString stringWithFormat:@"Jumping to frame %lld.", (unsigned long)threadParam.frameJumpTarget]]; + { + for(CocoaDSOutput *cdsOutput in cdsOutputList) + { + if (![cdsOutput isKindOfClass:[CocoaDSDisplay class]]) + { + [cdsOutput setIdle:YES]; + } + } + + [self setFrameStatus:[NSString stringWithFormat:@"Jumping to frame %lu.", (unsigned long)threadParam.frameJumpTarget]]; break; + } default: break; @@ -801,13 +796,6 @@ static BOOL isCoreStarted = NO; pthread_mutex_unlock(&threadParam.mutexOutputList); } -- (void) runThread:(id)object -{ - [CocoaDSCore startupCore]; - [super runThread:object]; - [CocoaDSCore shutdownCore]; -} - - (NSString *) cpuEmulationEngineString { NSString *theString = @"Uninitialized"; diff --git a/desmume/src/cocoa/cocoa_output.mm b/desmume/src/cocoa/cocoa_output.mm index 141e55b5c..a3797753b 100644 --- a/desmume/src/cocoa/cocoa_output.mm +++ b/desmume/src/cocoa/cocoa_output.mm @@ -134,6 +134,7 @@ spinlockSpuSyncMode = OS_SPINLOCK_INIT; spinlockSpuSyncMethod = OS_SPINLOCK_INIT; + _idleState = YES; bufferSize = 0; // Set up properties. @@ -154,6 +155,20 @@ [super dealloc]; } +- (void) setIdle:(BOOL)theState +{ + if (theState) + { + SNDOSXPauseAudio(); + } + else + { + SNDOSXUnpauseAudio(); + } + + [super setIdle:theState]; +} + - (void) setVolume:(float)vol { if (vol < 0.0f) diff --git a/desmume/src/cocoa/cocoa_util.h b/desmume/src/cocoa/cocoa_util.h index 32d22bcbb..14868a84d 100644 --- a/desmume/src/cocoa/cocoa_util.h +++ b/desmume/src/cocoa/cocoa_util.h @@ -17,6 +17,7 @@ */ #import +#include #include "utilities.h" #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 @@ -62,13 +63,18 @@ { NSThread *thread; BOOL threadExit; + NSCondition *conditionIdle; + BOOL _idleState; NSTimeInterval autoreleaseInterval; NSPort *sendPort; - NSPort *receivePort; + NSPort *receivePort; + + OSSpinLock spinlockIdle; } @property (assign) NSThread *thread; @property (assign) BOOL threadExit; +@property (assign) BOOL idle; @property (assign) NSTimeInterval autoreleaseInterval; @property (assign) NSPort *sendPort; @property (assign) NSPort *receivePort; diff --git a/desmume/src/cocoa/cocoa_util.mm b/desmume/src/cocoa/cocoa_util.mm index 8ffd3ebc1..df011d490 100644 --- a/desmume/src/cocoa/cocoa_util.mm +++ b/desmume/src/cocoa/cocoa_util.mm @@ -223,6 +223,7 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; @synthesize thread; @synthesize threadExit; +@dynamic idle; @synthesize autoreleaseInterval; @synthesize sendPort; @synthesize receivePort; @@ -237,8 +238,12 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; // Set up thread info. thread = nil; threadExit = NO; + conditionIdle = [[NSCondition alloc] init]; + _idleState = NO; autoreleaseInterval = interval; + spinlockIdle = OS_SPINLOCK_INIT; + // Set up thread ports. sendPort = [[NSPort port] retain]; [sendPort setDelegate:self]; @@ -251,10 +256,33 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; - (void)dealloc { [self forceThreadExit]; + [conditionIdle release]; [super dealloc]; } +- (void) setIdle:(BOOL)theState +{ + OSSpinLockLock(&spinlockIdle); + + _idleState = theState; + if (!theState) + { + [conditionIdle signal]; + } + + OSSpinLockUnlock(&spinlockIdle); +} + +- (BOOL) idle +{ + OSSpinLockLock(&spinlockIdle); + const BOOL theState = _idleState; + OSSpinLockUnlock(&spinlockIdle); + + return theState; +} + - (void) runThread:(id)object { NSAutoreleasePool *threadPool = [[NSAutoreleasePool alloc] init]; @@ -265,6 +293,14 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; do { + + [conditionIdle lock]; + while ([self idle]) + { + [conditionIdle wait]; + } + [conditionIdle unlock]; + NSAutoreleasePool *runLoopPool = [[NSAutoreleasePool alloc] init]; NSDate *runDate = [[NSDate alloc] initWithTimeIntervalSinceNow:[self autoreleaseInterval]]; [runLoop runUntilDate:runDate]; @@ -294,6 +330,7 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; } [self setThreadExit:YES]; + [self setIdle:NO]; // Wait until the thread has shut down. while ([self thread] != nil) diff --git a/desmume/src/cocoa/coreaudiosound.cpp b/desmume/src/cocoa/coreaudiosound.cpp index de27c402d..338150183 100644 --- a/desmume/src/cocoa/coreaudiosound.cpp +++ b/desmume/src/cocoa/coreaudiosound.cpp @@ -185,6 +185,20 @@ void CoreAudioOutput::start() OSSpinLockUnlock(this->_spinlockAU); } +void CoreAudioOutput::pause() +{ + OSSpinLockLock(this->_spinlockAU); + AudioOutputUnitStop(this->_au); + OSSpinLockUnlock(this->_spinlockAU); +} + +void CoreAudioOutput::unpause() +{ + OSSpinLockLock(this->_spinlockAU); + AudioOutputUnitStart(this->_au); + OSSpinLockUnlock(this->_spinlockAU); +} + void CoreAudioOutput::stop() { OSSpinLockLock(this->_spinlockAU); diff --git a/desmume/src/cocoa/coreaudiosound.h b/desmume/src/cocoa/coreaudiosound.h index 76ac58fb3..8ce524085 100644 --- a/desmume/src/cocoa/coreaudiosound.h +++ b/desmume/src/cocoa/coreaudiosound.h @@ -44,6 +44,8 @@ public: size_t getAvailableSamples() const; void mute(); void unmute(); + void pause(); + void unpause(); float getVolume() const; void setVolume(float vol); }; diff --git a/desmume/src/cocoa/openemu/NDSGameCore.mm b/desmume/src/cocoa/openemu/NDSGameCore.mm index 4368d1d75..74aff4caf 100644 --- a/desmume/src/cocoa/openemu/NDSGameCore.mm +++ b/desmume/src/cocoa/openemu/NDSGameCore.mm @@ -22,8 +22,6 @@ #import "cocoa_firmware.h" #import "cocoa_GPU.h" #import "cocoa_input.h" -#import "cocoa_core.h" -#import "cocoa_output.h" #import "OESoundInterface.h" #import "OENDSSystemResponderClient.h" @@ -31,6 +29,9 @@ #include "../../NDSSystem.h" #undef BOOL + +volatile bool execute = true; + @implementation NDSGameCore @synthesize cdsController; @@ -85,7 +86,7 @@ CommonSettings.advanced_timing = true; CommonSettings.jit_max_block_size = 12; CommonSettings.use_jit = true; - [CocoaDSCore startupCore]; + NDS_Init(); // Set up the cheat system cdsCheats = [[[[CocoaDSCheatManager alloc] init] retain] autorelease]; @@ -122,7 +123,7 @@ - (void)dealloc { SPU_ChangeSoundCore(SNDCORE_DUMMY, 0); - [CocoaDSCore shutdownCore]; + NDS_DeInit(); [self setCdsCheats:nil]; [self setCdsController:nil]; diff --git a/desmume/src/cocoa/sndOSX.cpp b/desmume/src/cocoa/sndOSX.cpp index bb478713f..bee83d4bd 100644 --- a/desmume/src/cocoa/sndOSX.cpp +++ b/desmume/src/cocoa/sndOSX.cpp @@ -62,6 +62,7 @@ int SNDOSXInit(int buffer_size) } coreAudioPlaybackManager->start(); + coreAudioPlaybackManager->pause(); return 0; } @@ -126,6 +127,26 @@ void SNDOSXUnMuteAudio() coreAudioPlaybackManager->unmute(); } +void SNDOSXPauseAudio() +{ + if (coreAudioPlaybackManager == NULL) + { + return; + } + + coreAudioPlaybackManager->pause(); +} + +void SNDOSXUnpauseAudio() +{ + if (coreAudioPlaybackManager == NULL) + { + return; + } + + coreAudioPlaybackManager->unpause(); +} + void SNDOSXSetVolume(int volume) { if (coreAudioPlaybackManager == NULL) diff --git a/desmume/src/cocoa/sndOSX.h b/desmume/src/cocoa/sndOSX.h index e2d707d88..ad25db024 100644 --- a/desmume/src/cocoa/sndOSX.h +++ b/desmume/src/cocoa/sndOSX.h @@ -36,6 +36,8 @@ void SNDOSXUpdateAudio(s16 *buffer, u32 num_samples); u32 SNDOSXGetAudioSpace(); void SNDOSXMuteAudio(); void SNDOSXUnMuteAudio(); +void SNDOSXPauseAudio(); +void SNDOSXUnpauseAudio(); void SNDOSXSetVolume(int volume); void SNDOSXClearBuffer(); void SNDOSXFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer); diff --git a/desmume/src/cocoa/userinterface/appDelegate.mm b/desmume/src/cocoa/userinterface/appDelegate.mm index d13abc91a..27ad853e2 100644 --- a/desmume/src/cocoa/userinterface/appDelegate.mm +++ b/desmume/src/cocoa/userinterface/appDelegate.mm @@ -189,15 +189,6 @@ [newCore addOutput:newSpeaker]; [emuControl setCdsSpeaker:newSpeaker]; - // Start the core thread. - [NSThread detachNewThreadSelector:@selector(runThread:) toTarget:newCore withObject:nil]; - - // Wait until the emulation core has finished starting up. - while (!([CocoaDSCore isCoreStarted] && [newCore thread] != nil)) - { - [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; - } - // Update the SLOT-2 device list after the emulation core is initialized. [slot2WindowDelegate update]; [slot2WindowDelegate setHidManager:[inputManager hidManager]];