private void GetStreamProviderAndVirtualPath(ViewModels.GameSystemVM system, IFile file, IFolder rootFolder, out IStreamProvider provider, out string mainFileVirtualPath)
        {
            IStreamProvider romProvider;

            if (rootFolder == null)
            {
                mainFileVirtualPath = $"{VFS.RomPath}{Path.DirectorySeparatorChar}{file.Name}";
                romProvider         = new SingleFileStreamProvider(mainFileVirtualPath, file);
            }
            else
            {
                mainFileVirtualPath = file.Path.Substring(rootFolder.Path.Length + 1);
                mainFileVirtualPath = $"{VFS.RomPath}{Path.DirectorySeparatorChar}{mainFileVirtualPath}";
                romProvider         = new FolderStreamProvider(VFS.RomPath, rootFolder);
            }

            var systemProvider   = new FolderStreamProvider(VFS.SystemPath, new WinRTFolder(system.Core.SystemFolder));
            var saveProvider     = new FolderStreamProvider(VFS.SavePath, new WinRTFolder(system.Core.SaveGameFolder));
            var combinedProvider = new CombinedStreamProvider(new HashSet <IStreamProvider> {
                romProvider, systemProvider, saveProvider
            });

            provider = combinedProvider;
        }
        public async Task <bool> StartGameAsync(Shared.ViewModels.GameSystemVM system, IFile file, IFolder rootFolder = null)
        {
            ViewModels.GameSystemVM nativeSystem = (ViewModels.GameSystemVM)system;

            if (CoreRunner == null)
            {
                RootFrame.Navigate(typeof(GamePlayerPage));
            }
            else
            {
                await CoreRunner.UnloadGameAsync();
            }

            StreamProvider?.Dispose();
            StreamProvider = null;
            string virtualMainFilePath = null;

            if (nativeSystem.Core.NativeArchiveSupport || !ArchiveExtensions.Contains(Path.GetExtension(file.Name)))
            {
                IStreamProvider streamProvider;
                GetStreamProviderAndVirtualPath(nativeSystem, file, rootFolder, out streamProvider, out virtualMainFilePath);
                StreamProvider = streamProvider;
            }
            else
            {
                var archiveProvider = new ArchiveStreamProvider(VFS.RomPath, file);
                await archiveProvider.InitializeAsync();

                StreamProvider = archiveProvider;
                var entries = await StreamProvider.ListEntriesAsync();

                virtualMainFilePath = entries.FirstOrDefault(d => nativeSystem.SupportedExtensions.Contains(Path.GetExtension(d)));
            }

            //Navigation should cause the player page to load, which in turn should initialize the core runner
            while (CoreRunner == null)
            {
                await Task.Delay(100);
            }

            if (virtualMainFilePath == null)
            {
                return(false);
            }

            nativeSystem.Core.OpenFileStream  = OnCoreOpenFileStream;
            nativeSystem.Core.CloseFileStream = OnCoreCloseFileStream;
            var loadSuccessful = false;

            try
            {
                loadSuccessful = await CoreRunner.LoadGameAsync(nativeSystem.Core, virtualMainFilePath);
            }
            catch
            {
                await StopGameAsync();

                return(false);
            }

            if (loadSuccessful)
            {
                GameStarted(this);
            }
            else
            {
                await StopGameAsync();

                return(false);
            }

            return(loadSuccessful);
        }