Last active
August 11, 2024 12:19
-
-
Save markusbkk/2b72f616f6e0f6b77af818d2d82e2954 to your computer and use it in GitHub Desktop.
Revisions
-
markusbkk renamed this gist
Aug 11, 2024 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
markusbkk revised this gist
Aug 11, 2024 . 4 changed files with 407 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,136 @@ <ContentDialog x:Class="NScumm.MonoGame.Pages.MainMenu" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:NScumm.MonoGame.Pages" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local1="using:NScumm.MonoGame.ViewModels" mc:Ignorable="d" x:Uid="MainMenu" Title="Main Menu"> <ContentDialog.DataContext> <local1:MenuViewModel/> </ContentDialog.DataContext> <ContentDialog.Template> <ControlTemplate TargetType="ContentDialog"> <Border x:Name="Container"> <Grid x:Name="LayoutRoot" Padding="20,5,20,0"> <Grid.RowDefinitions> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Border x:Name="BackgroundElement" Background="{TemplateBinding Background}" FlowDirection="{TemplateBinding FlowDirection}" BorderThickness="{ThemeResource ContentDialogBorderWidth}" BorderBrush="{ThemeResource SystemControlForegroundAccentBrush}" MaxWidth="{TemplateBinding MaxWidth}" MaxHeight="{TemplateBinding MaxHeight}" MinWidth="{TemplateBinding MinWidth}" MinHeight="{TemplateBinding MinHeight}" > <Grid x:Name="DialogSpace" Padding="20,10,20,0" VerticalAlignment="Stretch"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <ScrollViewer x:Name="ContentScrollViewer" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled" ZoomMode="Disabled" Margin="{ThemeResource ContentDialogContentScrollViewerMargin}" IsTabStop="False"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <ContentControl x:Name="Title" Margin="{ThemeResource ContentDialogTitleMargin}" Content="{TemplateBinding Title}" ContentTemplate="{TemplateBinding TitleTemplate}" FontSize="20" FontFamily="Segoe UI" FontWeight="Normal" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Left" VerticalAlignment="Top" IsTabStop="False" MaxHeight="{ThemeResource ContentDialogTitleMaxHeight}" > <ContentControl.Template> <ControlTemplate TargetType="ContentControl"> <ContentPresenter Content="{TemplateBinding Content}" MaxLines="2" TextWrapping="Wrap" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="{TemplateBinding Padding}" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> </ControlTemplate> </ContentControl.Template> </ContentControl> <ContentPresenter x:Name="Content" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" FontSize="{ThemeResource ControlContentThemeFontSize}" FontFamily="{ThemeResource ContentControlThemeFontFamily}" Margin="{ThemeResource ContentDialogContentMargin}" Foreground="{TemplateBinding Foreground}" Grid.Row="1" TextWrapping="Wrap" /> </Grid> </ScrollViewer> <Grid x:Name="CommandSpace" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Border x:Name="Button1Host" Margin="{ThemeResource ContentDialogButton1HostMargin}" MinWidth="{ThemeResource ContentDialogButtonMinWidth}" MaxWidth="{ThemeResource ContentDialogButtonMaxWidth}" Height="{ThemeResource ContentDialogButtonHeight}" HorizontalAlignment="Stretch" /> <Border x:Name="Button2Host" Margin="{ThemeResource ContentDialogButton2HostMargin}" MinWidth="{ThemeResource ContentDialogButtonMinWidth}" MaxWidth="{ThemeResource ContentDialogButtonMaxWidth}" Height="{ThemeResource ContentDialogButtonHeight}" Grid.Column="1" HorizontalAlignment="Stretch" /> </Grid> </Grid> </Border> </Grid> </Border> </ControlTemplate> </ContentDialog.Template> <Grid> <StackPanel x:Name="MainStackPanel" Margin="0 20 0 0" Visibility="Visible"> <Button x:Uid="MainMenuSaveButton" HorizontalAlignment="Stretch" Margin="5" Click="OnSave">Save</Button> <Button x:Uid="MainMenuLoadButton" HorizontalAlignment="Stretch" Margin="5" Click="OnLoad">Load</Button> <Button x:Uid="MainMenuResumeButton" HorizontalAlignment="Stretch" Margin="5" Click="OnResume">Resume</Button> <Button x:Uid="MainMenuExitButton" HorizontalAlignment="Stretch" Margin="5 20 5 5" Click="OnExit">Exit</Button> <MenuFlyoutSeparator></MenuFlyoutSeparator> <CheckBox x:Name="ShowFPScheckBox" Margin="5" IsChecked="{Binding ShowFPS, Mode=TwoWay}">FPS Counter</CheckBox> </StackPanel> <Grid x:Name="LoadStackPanel" Margin="0 20 0 0" Visibility="Collapsed"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <ListView x:Name="LoadGameList" MinWidth="150" ItemClick="OnLoadGame" IsItemClickEnabled="True" /> <Button x:Uid="MainMenuBackButton" Grid.Row="1" Margin="5 10 5 5" HorizontalAlignment="Stretch" Click="OnBack">Back</Button> </Grid> <Grid x:Name="SaveStackPanel" Margin="0 20 0 0" Visibility="Collapsed"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <ListView x:Name="SaveGameList" ItemClick="OnSaveGame" MinWidth="150" IsItemClickEnabled="True" ScrollViewer.VerticalScrollBarVisibility="Auto" /> <Button x:Uid="MainMenuBackButton" Grid.Row="1" Margin="5 10 5 5" HorizontalAlignment="Stretch" Click="OnBack">Back</Button> </Grid> </Grid> </ContentDialog> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,245 @@ using NScumm.Core; using System.Collections.Generic; using System.IO; using System.Linq; using Windows.UI.Xaml.Controls; using Windows.ApplicationModel.Resources; using Windows.UI.Core; using System; using Windows.UI.Popups; using System.Threading.Tasks; using Windows.UI.Xaml.Media; using Windows.UI; using Windows.Storage; using Windows.UI.Xaml.Data; using Windows.UI.Xaml; using NScumm.MonoGame.ViewModels; using NScumm.MonoGame.Converters; namespace NScumm.MonoGame.Pages { public sealed partial class MainMenu : ContentDialog { public MenuViewModel ViewModel { get { return DataContext as MenuViewModel; } set { DataContext = value; } } private ResourceLoader _loader; internal ScummGame Game { get; set; } private IEngine Engine { get { var engine = Game.Services.GetService<IEngine>(); return engine; } } public MainMenu() { InitializeComponent(); _loader = ResourceLoader.GetForViewIndependentUse(); } private void OnResume(object sender, Windows.UI.Xaml.RoutedEventArgs e) { Hide(); } private void OnBack(object sender, Windows.UI.Xaml.RoutedEventArgs e) { Title = _loader.GetString("MainMenu_Title"); MainStackPanel.Visibility = Windows.UI.Xaml.Visibility.Visible; LoadStackPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed; SaveStackPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed; } private async void OnLoad(object sender, Windows.UI.Xaml.RoutedEventArgs e) { Title = _loader.GetString("MainMenu_LoadTitle"); LoadGameList.Items.Clear(); var savegames = await GetSavegames(); savegames.ForEach(LoadGameList.Items.Add); MainStackPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed; LoadStackPanel.Visibility = Windows.UI.Xaml.Visibility.Visible; } private async void OnSave(object sender, Windows.UI.Xaml.RoutedEventArgs e) { Title = _loader.GetString("MainMenu_SaveTitle"); SaveGameList.Items.Clear(); var savegames = await GetSavegames(); savegames.ForEach(SaveGameList.Items.Add); ListViewItem NewEntry = new ListViewItem(); NewEntry.Content = _loader.GetString("New Entry"); NewEntry.Background = new SolidColorBrush(Colors.DodgerBlue); NewEntry.Foreground = new SolidColorBrush(Colors.White); SaveGameList.Items.Add(NewEntry); MainStackPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed; SaveStackPanel.Visibility = Windows.UI.Xaml.Visibility.Visible; } private void OnExit(object sender, Windows.UI.Xaml.RoutedEventArgs e) { ExitGame_Click(); Hide(); } private async void ExitGame_Click() { try { var messageDialog = new MessageDialog("Do you want to exit?"); messageDialog.Commands.Add(new UICommand("Exit", new UICommandInvokedHandler(this.CommandInvokedHandler))); messageDialog.Commands.Add(new UICommand("Dismiss")); await messageDialog.ShowAsync(); } catch (Exception ex) { } } private void CommandInvokedHandler(IUICommand command) { Engine.IsPaused = false; Engine.HasToQuit = true; App.isGameStarted = false; } private void OnLoadGame(object sender, ItemClickEventArgs e) { //string ObjectType = e.ClickedItem.GetType().Name; var index = ((ListView)sender).Items.IndexOf(e.ClickedItem); LoadGame(index); Hide(); } private void OnSaveGame(object sender, ItemClickEventArgs e) { var index = ((ListView)sender).Items.IndexOf(e.ClickedItem); if(index == -1) { index = ((ListView)sender).Items.Count - 1; } SaveGame(index); Hide(); } private async Task<List<string>> GetSavegames() { var local = Windows.Storage.ApplicationData.Current.LocalFolder; var spec = await local.CreateFolderAsync(Game.Settings.Game.Id, Windows.Storage.CreationCollisionOption.OpenIfExists); if (spec != null) { var dir = spec.Path; var pattern = string.Format("{0}*.sav", Game.Settings.Game.Id); return ServiceLocator.FileStorage.EnumerateFiles(dir, pattern).Select(Path.GetFileNameWithoutExtension).ToList(); } return new List<string>(); } private async Task<string> GetSaveGamePath(int index) { var local = Windows.Storage.ApplicationData.Current.LocalFolder; var spec = await local.CreateFolderAsync(Game.Settings.Game.Id, Windows.Storage.CreationCollisionOption.OpenIfExists); if (spec != null) { var indexResolve = "00"; if(index > 9) { indexResolve = "0"; }else if (index > 99) { indexResolve = ""; } var dir = spec.Path; var filename = Path.Combine(dir, string.Format("{0} ({1}{2}).sav", Game.Settings.Game.Id, indexResolve ,(index + 1))); return filename; } return ""; } private async void LoadGame(int index) { try { var filename = await GetSaveGamePath(index); if (filename.Length > 0) { Engine.Load(filename); GamePage.ShowTileHandler.Invoke(new string[] { "Load State", "State loaded successfully", $"Name: { Path.GetFileNameWithoutExtension(filename) }"}, EventArgs.Empty); } }catch(Exception ex) { ShowDialog(ex); } } private async void SaveGame(int index) { try { var filename = await GetSaveGamePath(index); if (filename.Length > 0) { Engine.Save(filename); GamePage.ShowTileHandler.Invoke(new string[] { "Save State", "Save state done", $"Name: { Path.GetFileNameWithoutExtension(filename) }" }, EventArgs.Empty); } }catch(Exception ex) { ShowDialog(ex); } } private async void ShowDialog(Exception message, bool log = false) { try { if (log) { var logFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("log.txt", CreationCollisionOption.OpenIfExists); await FileIO.AppendTextAsync(logFile, message.Message); } } catch (Exception ex) { } var messageDialog = new MessageDialog(message.Message); messageDialog.Commands.Add(new UICommand( "Close")); await messageDialog.ShowAsync(); } private async void ShowDialog(string message, bool log = false) { try { if (log) { var logFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("log.txt", CreationCollisionOption.OpenIfExists); await FileIO.AppendTextAsync(logFile, message); } } catch (Exception ex) { } var messageDialog = new MessageDialog(message); messageDialog.Commands.Add(new UICommand( "Close")); await messageDialog.ShowAsync(); } private void ShowFPS_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) { } } } File renamed without changes.This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,26 @@ using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; namespace NScumm.MonoGame.ViewModels { public abstract class ViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { var eh = PropertyChanged; eh?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public virtual void RaiseAndSetIfChanged<T>(ref T field, T value, [CallerMemberName] string propertyName = null) { if (!EqualityComparer<T>.Default.Equals(field, value)) { field = value; OnPropertyChanged(propertyName); } } } } -
markusbkk created this gist
Aug 11, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,20 @@ namespace NScumm.MonoGame.ViewModels { public interface IMenuViewModel { void UpdateShowFPS(); } public class MenuViewModel : ViewModel, IMenuViewModel { private bool _showFPS; public bool ShowFPS { get { return _showFPS; } set { RaiseAndSetIfChanged(ref _showFPS, value); } } } }