diff --git a/Classes/Retronator/Xni/Framework/Game.m b/Classes/Retronator/Xni/Framework/Game.m index ab3f26b..0892e20 100644 --- a/Classes/Retronator/Xni/Framework/Game.m +++ b/Classes/Retronator/Xni/Framework/Game.m @@ -12,12 +12,14 @@ #import "Retronator.Xni.Framework.h" #import "Retronator.Xni.Framework.Graphics.h" #import "Retronator.Xni.Framework.Content.h" +#import "Retronator.Xni.Framework.Media.h" #import "TouchPanel+Internal.h" #import "GameWindow+Internal.h" #import "GameViewController.h" #import "GameView.h" #import "Guide+Internal.h" #import "SoundEffect+Internal.h" +#import "MediaPlayer+Internal.h" @interface Game () @@ -233,6 +235,7 @@ static NSArray *drawOrderSort; { NSLog(@"Application was deactivated."); isActive = NO; + [MediaPlayer toBackground]; [deactivated raiseWithSender:self]; } @@ -240,6 +243,7 @@ static NSArray *drawOrderSort; { NSLog(@"Application was activated."); isActive = YES; + [MediaPlayer returnFromBackground]; [activated raiseWithSender:self]; } diff --git a/Classes/Retronator/Xni/Framework/Media/MediaPlayer.h b/Classes/Retronator/Xni/Framework/Media/MediaPlayer.h index a4bf6f0..3d7fa80 100644 --- a/Classes/Retronator/Xni/Framework/Media/MediaPlayer.h +++ b/Classes/Retronator/Xni/Framework/Media/MediaPlayer.h @@ -21,6 +21,8 @@ MediaQueue *queue; MediaState state; float volume; + + Song *songToPlayOnActive; NSMutableArray *remainingSongIndices; diff --git a/Classes/Retronator/Xni/Framework/Media/MediaPlayer.m b/Classes/Retronator/Xni/Framework/Media/MediaPlayer.m index 91530c9..20c3f44 100644 --- a/Classes/Retronator/Xni/Framework/Media/MediaPlayer.m +++ b/Classes/Retronator/Xni/Framework/Media/MediaPlayer.m @@ -7,6 +7,7 @@ // #import "MediaPlayer.h" +#import "MediaPlayer+Internal.h" #import @@ -20,6 +21,11 @@ - (void) setMediaState:(MediaState)value; - (void) fillSongIndices; +- (void) setSongToPlayOnActive:(Song*)song; + +- (void) toBackground; +- (void) returnFromBackground; + @end @@ -115,6 +121,8 @@ static MediaPlayer *instance; + (void) playSong:(Song*)song { [instance playSong:song];} + (void) resume { [instance resume];} + (void) stop { [instance stop];} ++ (void) toBackground { [instance toBackground];} ++ (void) returnFromBackground { [instance returnFromBackground];} - (void) moveNext { if (![self checkAvailability]) { @@ -158,6 +166,8 @@ static MediaPlayer *instance; - (void) playSong:(Song*)song { if (![self checkAvailability]) { + // Save the song if we might get availability later. + [self setSongToPlayOnActive:song]; return; } @@ -244,11 +254,51 @@ static MediaPlayer *instance; } } +- (void)setSongToPlayOnActive:(Song *)song { + [songToPlayOnActive release]; + songToPlayOnActive = [song retain]; +} + +- (void)toBackground { + // If music was playing, activate the ambient category while the app is in background. + if (soloModeActivated) { + [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error:nil]; + } +} + +- (void)returnFromBackground { + // If music was playing, try to return to playing if we still have control. + // Otherwise the user has started playing his own music and we should remain in ambient. + if (soloModeActivated) { + + if (self.gameHasControl) { + // Everything is OK, set category back to solo. + [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategorySoloAmbient error:nil]; + } else { + // Stop music if we lost control. + [self setSongToPlayOnActive:queue.activeSong]; + + queue.activeSong.audioPlayer.currentTime = 0; + [queue.activeSong.audioPlayer stop]; + [self setMediaState:MediaStateStopped]; + + soloModeActivated = NO; + } + } else { + if (self.gameHasControl && songToPlayOnActive) { + + [self playSong:songToPlayOnActive]; + [self setSongToPlayOnActive:nil]; + } + } +} + - (void) dealloc { [remainingSongIndices release]; [activeSongChanged release]; [mediaStateChanged release]; + [songToPlayOnActive release]; [queue release]; [super dealloc]; } diff --git a/Classes/Retronator/Xni/Framework/MediaPlayer+Internal.h b/Classes/Retronator/Xni/Framework/MediaPlayer+Internal.h new file mode 100644 index 0000000..c0e073b --- /dev/null +++ b/Classes/Retronator/Xni/Framework/MediaPlayer+Internal.h @@ -0,0 +1,8 @@ + + +@interface MediaPlayer (Internal) + ++ (void) toBackground; ++ (void) returnFromBackground; + +@end \ No newline at end of file diff --git a/XNI.xcodeproj/project.pbxproj b/XNI.xcodeproj/project.pbxproj index 5f79788..d43a06a 100644 --- a/XNI.xcodeproj/project.pbxproj +++ b/XNI.xcodeproj/project.pbxproj @@ -664,6 +664,7 @@ B57E36BF124BE2DD00DDAA42 /* VertexPositionColorTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = B57E36BD124BE2DD00DDAA42 /* VertexPositionColorTexture.m */; }; B57E36CD124BE36E00DDAA42 /* VertexPositionColorTextureArray.m in Sources */ = {isa = PBXBuildFile; fileRef = B57E36CB124BE36E00DDAA42 /* VertexPositionColorTextureArray.m */; }; B594878612AEF44900EE601F /* XniPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = B594878412AEF44900EE601F /* XniPoint.m */; }; + B5956CCA1663BD2700FC01F5 /* MediaPlayer+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B5956CC91663BD2700FC01F5 /* MediaPlayer+Internal.h */; }; B59AD7F11236E07300F99511 /* ContentImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = B59AD7EF1236E07300F99511 /* ContentImporter.m */; }; B59AD8121236E25700F99511 /* TextureImporter.m in Sources */ = {isa = PBXBuildFile; fileRef = B59AD8101236E25700F99511 /* TextureImporter.m */; }; B59AD8201236E59A00F99511 /* ContentItem.m in Sources */ = {isa = PBXBuildFile; fileRef = B59AD81E1236E59A00F99511 /* ContentItem.m */; }; @@ -936,6 +937,7 @@ B594878112AEF3DA00EE601F /* PointStruct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PointStruct.h; sourceTree = ""; }; B594878312AEF44900EE601F /* XniPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XniPoint.h; sourceTree = ""; }; B594878412AEF44900EE601F /* XniPoint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XniPoint.m; sourceTree = ""; }; + B5956CC91663BD2700FC01F5 /* MediaPlayer+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "MediaPlayer+Internal.h"; path = "Classes/Retronator/Xni/Framework/MediaPlayer+Internal.h"; sourceTree = SOURCE_ROOT; }; B59AD7EE1236E07300F99511 /* ContentImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentImporter.h; sourceTree = ""; }; B59AD7EF1236E07300F99511 /* ContentImporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContentImporter.m; sourceTree = ""; }; B59AD80B1236E21900F99511 /* Retronator.Xni.Framework.Content.Pipeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Retronator.Xni.Framework.Content.Pipeline.h; sourceTree = ""; }; @@ -1260,6 +1262,7 @@ B507F85D12E5766C00A7302B /* Song+Internal.h */, B507F85012E5756400A7302B /* Song.m */, B507F83E12E5751700A7302B /* MediaPlayer.h */, + B5956CC91663BD2700FC01F5 /* MediaPlayer+Internal.h */, B507F83F12E5751700A7302B /* MediaPlayer.m */, B507F8BA12E58E7000A7302B /* MediaQueue.h */, B507F8C412E58EB100A7302B /* MediaQueue+Internal.h */, @@ -2249,6 +2252,7 @@ B54E75561356241B007AD718 /* ReadOnlyCollection.h in Headers */, B54E75571356241B007AD718 /* IAsyncResult.h in Headers */, 25AE5D5315F5440B00B73D10 /* RenderTarget2D.h in Headers */, + B5956CCA1663BD2700FC01F5 /* MediaPlayer+Internal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/XNI.xcodeproj/project.xcworkspace/xcuserdata/Retro.xcuserdatad/UserInterfaceState.xcuserstate b/XNI.xcodeproj/project.xcworkspace/xcuserdata/Retro.xcuserdatad/UserInterfaceState.xcuserstate index c0853e9..ae59cd8 100644 Binary files a/XNI.xcodeproj/project.xcworkspace/xcuserdata/Retro.xcuserdatad/UserInterfaceState.xcuserstate and b/XNI.xcodeproj/project.xcworkspace/xcuserdata/Retro.xcuserdatad/UserInterfaceState.xcuserstate differ