mirror of
https://github.com/digital-jellyfish/Virtu.git
synced 2024-05-31 15:41:33 +00:00
Upgraded to Windows Phone 7 Beta.
Upgraded to FxCop 10.0. Dropped Silverlight Toolkit dependency (for now). Modified AudioService to avoid deadlocks by using timeouts. Refactored DebugService and implementations. Modified SilverlightVideoService to handle browser zoom. Split Wpf MainWindow into MainPage child control. --HG-- extra : convert_revision : svn%3Affd33b8c-2492-42e0-bdc5-587b920b7d6d/trunk%4048619
This commit is contained in:
parent
9fca4b220f
commit
2167383a00
52
Library/DispatcherExtensions.cs
Normal file
52
Library/DispatcherExtensions.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Jellyfish.Library
|
||||
{
|
||||
public static class DispatcherExtensions
|
||||
{
|
||||
public static void CheckBeginInvoke(this Dispatcher dispatcher, Action action)
|
||||
{
|
||||
if (dispatcher == null)
|
||||
{
|
||||
throw new ArgumentNullException("dispatcher");
|
||||
}
|
||||
if (action == null)
|
||||
{
|
||||
throw new ArgumentNullException("action");
|
||||
}
|
||||
|
||||
if (dispatcher.CheckAccess())
|
||||
{
|
||||
action();
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatcher.BeginInvoke(action);
|
||||
}
|
||||
}
|
||||
|
||||
#if WINDOWS
|
||||
public static void CheckInvoke(this Dispatcher dispatcher, Action action)
|
||||
{
|
||||
if (dispatcher == null)
|
||||
{
|
||||
throw new ArgumentNullException("dispatcher");
|
||||
}
|
||||
if (action == null)
|
||||
{
|
||||
throw new ArgumentNullException("action");
|
||||
}
|
||||
|
||||
if (dispatcher.CheckAccess())
|
||||
{
|
||||
action();
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatcher.Invoke(action);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FxCopProject Version="1.36" Name="My FxCop Project">
|
||||
<FxCopProject Version="10.0" Name="Jellyfish.Library">
|
||||
<ProjectOptions>
|
||||
<SharedProject>True</SharedProject>
|
||||
<Stylesheet Apply="False">c:\program files\microsoft fxcop 1.36\Xml\FxCopReport.xsl</Stylesheet>
|
||||
<Stylesheet Apply="False">$(FxCopDir)\Xml\FxCopReport.xsl</Stylesheet>
|
||||
<SaveMessages>
|
||||
<Project Status="Active, Excluded" NewOnly="False" />
|
||||
<Report Status="Active" NewOnly="False" />
|
||||
|
@ -19,11 +19,10 @@
|
|||
<SearchGlobalAssemblyCache>True</SearchGlobalAssemblyCache>
|
||||
<DeadlockDetectionTimeout>120</DeadlockDetectionTimeout>
|
||||
<IgnoreGeneratedCode>True</IgnoreGeneratedCode>
|
||||
<TargetFrameworkVersion>3.5</TargetFrameworkVersion>
|
||||
</ProjectOptions>
|
||||
<Targets>
|
||||
<Target Name="$(ProjectDir)/Wpf/bin/Jellyfish.Library.dll" Analyze="True" AnalyzeAllChildren="True" />
|
||||
<Target Name="$(ProjectDir)/Xna/bin/Jellyfish.Library.dll" Analyze="True" AnalyzeAllChildren="True" />
|
||||
<Target Name="$(ProjectDir)/Xna/bin/x86/Jellyfish.Library.dll" Analyze="True" AnalyzeAllChildren="True" />
|
||||
</Targets>
|
||||
<Rules>
|
||||
<RuleFiles>
|
||||
|
@ -35,10 +34,11 @@
|
|||
<RuleFile Name="$(FxCopDir)\Rules\PerformanceRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
<RuleFile Name="$(FxCopDir)\Rules\PortabilityRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
<RuleFile Name="$(FxCopDir)\Rules\SecurityRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
<RuleFile Name="$(FxCopDir)\Rules\SecurityTransparencyRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
<RuleFile Name="$(FxCopDir)\Rules\UsageRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
</RuleFiles>
|
||||
<Groups />
|
||||
<Settings />
|
||||
</Rules>
|
||||
<FxCopReport Version="1.36" />
|
||||
<FxCopReport Version="10.0" />
|
||||
</FxCopProject>
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
#if WINDOWS_PHONE
|
||||
using System.Windows.Navigation;
|
||||
using Microsoft.Phone.Controls;
|
||||
using Microsoft.Phone.Shell;
|
||||
#endif
|
||||
|
||||
namespace Jellyfish.Library
|
||||
{
|
||||
|
@ -19,24 +24,25 @@ public ApplicationBase(string name)
|
|||
//AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
|
||||
}
|
||||
|
||||
private void OnApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
|
||||
#if WINDOWS_PHONE
|
||||
protected void InitializePhoneApplication()
|
||||
{
|
||||
MessageBox.Show(GetExceptionMessage(e.ExceptionObject), GetExceptionCaption("Application Exception"), MessageBoxButton.OK);
|
||||
e.Handled = true;
|
||||
if (!_phoneApplicationInitialized)
|
||||
{
|
||||
RootFrame = new PhoneApplicationFrame();
|
||||
RootFrame.Navigated += OnRootFrameNavigated;
|
||||
RootFrame.NavigationFailed += OnRootFrameNavigationFailed;
|
||||
_phoneApplicationInitialized = true;
|
||||
}
|
||||
|
||||
//private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
//{
|
||||
// MessageBox.Show(GetExceptionMessage(e.ExceptionObject as Exception), GetExceptionCaption("AppDomain Exception", e.IsTerminating), MessageBoxButton.OK);
|
||||
//}
|
||||
}
|
||||
#endif
|
||||
|
||||
private string GetExceptionCaption(string title, bool isTerminating = false)
|
||||
{
|
||||
var caption = new StringBuilder();
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
caption.Append(Name);
|
||||
caption.Append(" ");
|
||||
caption.Append(Name).Append(' ');
|
||||
}
|
||||
caption.Append(title);
|
||||
if (isTerminating)
|
||||
|
@ -47,19 +53,48 @@ private string GetExceptionCaption(string title, bool isTerminating = false)
|
|||
return caption.ToString();
|
||||
}
|
||||
|
||||
private static string GetExceptionMessage(Exception exception)
|
||||
private void OnApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
|
||||
{
|
||||
var message = new StringBuilder();
|
||||
if (exception != null)
|
||||
MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("Application Exception"), MessageBoxButton.OK);
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
message.Append(exception.Message.ToString());
|
||||
message.Append(Environment.NewLine);
|
||||
message.Append(exception.StackTrace.ToString());
|
||||
Debugger.Break();
|
||||
}
|
||||
}
|
||||
|
||||
return message.ToString();
|
||||
//private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
//{
|
||||
// MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating), MessageBoxButton.OK);
|
||||
// if (Debugger.IsAttached)
|
||||
// {
|
||||
// Debugger.Break();
|
||||
// }
|
||||
//}
|
||||
|
||||
#if WINDOWS_PHONE
|
||||
private void OnRootFrameNavigated(object sender, NavigationEventArgs e)
|
||||
{
|
||||
if (RootVisual != RootFrame)
|
||||
{
|
||||
RootVisual = RootFrame;
|
||||
}
|
||||
RootFrame.Navigated -= OnRootFrameNavigated;
|
||||
}
|
||||
|
||||
private void OnRootFrameNavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||
{
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Debugger.Break();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public string Name { get; private set; }
|
||||
#if WINDOWS_PHONE
|
||||
public PhoneApplicationFrame RootFrame { get; private set; }
|
||||
|
||||
private bool _phoneApplicationInitialized;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
<Compile Include="..\AssemblyCommentAttribute.cs">
|
||||
<Link>AssemblyCommentAttribute.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DispatcherExtensions.cs">
|
||||
<Link>DispatcherExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FrameRateCounter.xaml.cs">
|
||||
<Link>FrameRateCounter.xaml.cs</Link>
|
||||
<DependentUpon>FrameRateCounter.xaml</DependentUpon>
|
||||
|
@ -89,6 +92,12 @@
|
|||
<Compile Include="..\StringBuilderExtensions.cs">
|
||||
<Link>StringBuilderExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ThreadExtensions.cs">
|
||||
<Link>ThreadExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\WaitHandleExtensions.cs">
|
||||
<Link>WaitHandleExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\WaveFormat.cs">
|
||||
<Link>WaveFormat.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Phone" />
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
@ -59,6 +60,9 @@
|
|||
<Compile Include="..\..\AssemblyCommentAttribute.cs">
|
||||
<Link>AssemblyCommentAttribute.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\DispatcherExtensions.cs">
|
||||
<Link>DispatcherExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\GlobalSuppressions.cs">
|
||||
<Link>GlobalSuppressions.cs</Link>
|
||||
</Compile>
|
||||
|
@ -77,6 +81,12 @@
|
|||
<Compile Include="..\..\StringBuilderExtensions.cs">
|
||||
<Link>StringBuilderExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\ThreadExtensions.cs">
|
||||
<Link>ThreadExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\WaitHandleExtensions.cs">
|
||||
<Link>WaitHandleExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\WaveFormat.cs">
|
||||
<Link>WaveFormat.cs</Link>
|
||||
</Compile>
|
||||
|
|
23
Library/ThreadExtensions.cs
Normal file
23
Library/ThreadExtensions.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Jellyfish.Library
|
||||
{
|
||||
public static class ThreadExtensions
|
||||
{
|
||||
public static void IsAliveJoin(this Thread thread)
|
||||
{
|
||||
if (thread == null)
|
||||
{
|
||||
throw new ArgumentNullException("thread");
|
||||
}
|
||||
|
||||
#if !XBOX
|
||||
if (thread.IsAlive)
|
||||
#endif
|
||||
{
|
||||
thread.Join();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
Library/WaitHandleExtensions.cs
Normal file
20
Library/WaitHandleExtensions.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Jellyfish.Library
|
||||
{
|
||||
public static class WaitHandleExtensions
|
||||
{
|
||||
#if XBOX
|
||||
public static bool WaitOne(this WaitHandle waitHandle, int millisecondsTimeout)
|
||||
{
|
||||
if (waitHandle == null)
|
||||
{
|
||||
throw new ArgumentNullException("waitHandle");
|
||||
}
|
||||
|
||||
return waitHandle.WaitOne(millisecondsTimeout, false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -24,26 +24,12 @@ public ApplicationBase(string name)
|
|||
AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
|
||||
}
|
||||
|
||||
private void OnApplicationDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
MessageBox.Show(GetExceptionMessage(e.Exception), GetExceptionCaption("Application Dispatcher Exception", isTerminating: true));
|
||||
e.Handled = true;
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
MessageBox.Show(GetExceptionMessage(e.ExceptionObject as Exception), GetExceptionCaption("AppDomain Exception", e.IsTerminating));
|
||||
}
|
||||
|
||||
private string GetExceptionCaption(string title, bool isTerminating = false)
|
||||
{
|
||||
var caption = new StringBuilder();
|
||||
caption.AppendFormat("[{0}] ", Process.GetCurrentProcess().Id);
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
caption.Append(Name);
|
||||
caption.Append(" ");
|
||||
caption.Append(Name).Append(' ');
|
||||
}
|
||||
caption.Append(title);
|
||||
if (isTerminating)
|
||||
|
@ -54,17 +40,24 @@ private string GetExceptionCaption(string title, bool isTerminating = false)
|
|||
return caption.ToString();
|
||||
}
|
||||
|
||||
private static string GetExceptionMessage(Exception exception)
|
||||
private void OnApplicationDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
var message = new StringBuilder();
|
||||
if (exception != null)
|
||||
MessageBox.Show(e.Exception.ToString(), GetExceptionCaption("Application Dispatcher Exception", isTerminating: true));
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
message.Append(exception.Message.ToString());
|
||||
message.Append(Environment.NewLine);
|
||||
message.Append(exception.StackTrace.ToString());
|
||||
Debugger.Break();
|
||||
}
|
||||
e.Handled = true;
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
return message.ToString();
|
||||
private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating));
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Debugger.Break();
|
||||
}
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
<Compile Include="..\DirectSoundInterop.cs">
|
||||
<Link>DirectSoundInterop.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\DispatcherExtensions.cs">
|
||||
<Link>DispatcherExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\FrameRateCounter.xaml.cs">
|
||||
<Link>FrameRateCounter.xaml.cs</Link>
|
||||
<DependentUpon>FrameRateCounter.xaml</DependentUpon>
|
||||
|
@ -95,6 +98,12 @@
|
|||
<Compile Include="..\StringBuilderExtensions.cs">
|
||||
<Link>StringBuilderExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ThreadExtensions.cs">
|
||||
<Link>ThreadExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\WaitHandleExtensions.cs">
|
||||
<Link>WaitHandleExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\WaveFormat.cs">
|
||||
<Link>WaveFormat.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
@ -12,12 +13,6 @@ public FrameRateCounter(GameBase game) :
|
|||
{
|
||||
FontColor = Color.White;
|
||||
FontName = "Default";
|
||||
|
||||
//game.IsFixedTimeStep = true; // fixed (default)
|
||||
//game.TargetElapsedTime = TimeSpan.FromSeconds(1 / 60f);
|
||||
|
||||
//game.IsFixedTimeStep = false; // flatout
|
||||
//game.GraphicsDeviceManager.SynchronizeWithVerticalRetrace = false;
|
||||
}
|
||||
|
||||
protected override void LoadContent()
|
||||
|
@ -29,6 +24,7 @@ protected override void LoadContent()
|
|||
Position = new Vector2(titleSafeArea.X, titleSafeArea.Y);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||||
public override void Draw(GameTime gameTime)
|
||||
{
|
||||
_frameCount++;
|
||||
|
@ -44,6 +40,7 @@ public override void Draw(GameTime gameTime)
|
|||
_spriteBatch.End();
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||||
public override void Update(GameTime gameTime)
|
||||
{
|
||||
if (gameTime == null)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.GamerServices;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
|
@ -16,16 +17,21 @@ public GameBase(string name)
|
|||
{
|
||||
Name = name;
|
||||
|
||||
Content.RootDirectory = "Content";
|
||||
GraphicsDeviceManager = new GraphicsDeviceManager(this);
|
||||
#if WINDOWS_PHONE
|
||||
GraphicsDeviceManager.IsFullScreen = true;
|
||||
TargetElapsedTime = TimeSpan.FromTicks(333333); // 30 fps
|
||||
#endif
|
||||
GraphicsDeviceService = (IGraphicsDeviceService)Services.GetService(typeof(IGraphicsDeviceService));
|
||||
|
||||
Content.RootDirectory = "Content";
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
Window.Title = Name;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||||
protected override void Update(GameTime gameTime)
|
||||
{
|
||||
var gamePadState = GamePad.GetState(PlayerIndex.One);
|
||||
|
|
|
@ -110,6 +110,12 @@
|
|||
<Compile Include="..\StringBuilderExtensions.cs">
|
||||
<Link>StringBuilderExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ThreadExtensions.cs">
|
||||
<Link>ThreadExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\WaitHandleExtensions.cs">
|
||||
<Link>WaitHandleExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\XmlSerializerHelpers.cs">
|
||||
<Link>XmlSerializerHelpers.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -122,6 +122,12 @@
|
|||
<Compile Include="..\StringBuilderExtensions.cs">
|
||||
<Link>StringBuilderExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ThreadExtensions.cs">
|
||||
<Link>ThreadExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\WaitHandleExtensions.cs">
|
||||
<Link>WaitHandleExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\XmlSerializerHelpers.cs">
|
||||
<Link>XmlSerializerHelpers.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -134,6 +134,12 @@
|
|||
<Compile Include="..\StringBuilderExtensions.cs">
|
||||
<Link>StringBuilderExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\ThreadExtensions.cs">
|
||||
<Link>ThreadExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\WaitHandleExtensions.cs">
|
||||
<Link>WaitHandleExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\XmlSerializerHelpers.cs">
|
||||
<Link>XmlSerializerHelpers.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
|
||||
namespace Jellyfish.Virtu
|
||||
{
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Jellyfish.Virtu.Services;
|
||||
using Jellyfish.Virtu.Settings;
|
||||
|
||||
namespace Jellyfish.Virtu
|
||||
{
|
||||
|
|
|
@ -15,9 +15,7 @@ public Drive525()
|
|||
DriveArmStepDelta[3] = new int[] { 0, 1, 0, 1, -1, 0, -1, 0, 0, 1, 0, 1, -1, 0, -1, 0 }; // phase 3
|
||||
}
|
||||
|
||||
#if !XBOX
|
||||
[SecurityCritical]
|
||||
#endif
|
||||
public void InsertDisk(string fileName, bool isWriteProtected)
|
||||
{
|
||||
using (var stream = File.OpenRead(fileName))
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Jellyfish.Library;
|
||||
using Jellyfish.Virtu.Services;
|
||||
using Jellyfish.Virtu.Settings;
|
||||
|
||||
namespace Jellyfish.Virtu
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FxCopProject Version="1.36" Name="My FxCop Project">
|
||||
<FxCopProject Version="10.0" Name="Jellyfish.Virtu">
|
||||
<ProjectOptions>
|
||||
<SharedProject>True</SharedProject>
|
||||
<Stylesheet Apply="False">c:\program files\microsoft fxcop 1.36\Xml\FxCopReport.xsl</Stylesheet>
|
||||
<Stylesheet Apply="False">$(FxCopDir)\Xml\FxCopReport.xsl</Stylesheet>
|
||||
<SaveMessages>
|
||||
<Project Status="Active, Excluded" NewOnly="False" />
|
||||
<Report Status="Active" NewOnly="False" />
|
||||
|
@ -19,11 +19,10 @@
|
|||
<SearchGlobalAssemblyCache>True</SearchGlobalAssemblyCache>
|
||||
<DeadlockDetectionTimeout>120</DeadlockDetectionTimeout>
|
||||
<IgnoreGeneratedCode>True</IgnoreGeneratedCode>
|
||||
<TargetFrameworkVersion>3.5</TargetFrameworkVersion>
|
||||
</ProjectOptions>
|
||||
<Targets>
|
||||
<Target Name="$(ProjectDir)/Wpf/bin/Jellyfish.Virtu.exe" Analyze="True" AnalyzeAllChildren="True" />
|
||||
<Target Name="$(ProjectDir)/Xna/bin/Jellyfish.Virtu.exe" Analyze="True" AnalyzeAllChildren="True" />
|
||||
<Target Name="$(ProjectDir)/Xna/bin/x86/Jellyfish.Virtu.exe" Analyze="True" AnalyzeAllChildren="True" />
|
||||
</Targets>
|
||||
<Rules>
|
||||
<RuleFiles>
|
||||
|
@ -35,46 +34,11 @@
|
|||
<RuleFile Name="$(FxCopDir)\Rules\PerformanceRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
<RuleFile Name="$(FxCopDir)\Rules\PortabilityRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
<RuleFile Name="$(FxCopDir)\Rules\SecurityRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
<RuleFile Name="$(FxCopDir)\Rules\SecurityTransparencyRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
<RuleFile Name="$(FxCopDir)\Rules\UsageRules.dll" Enabled="True" AllRulesEnabled="True" />
|
||||
</RuleFiles>
|
||||
<Groups />
|
||||
<Settings />
|
||||
</Rules>
|
||||
<FxCopReport Version="1.36">
|
||||
<Targets>
|
||||
<Target Name="$(ProjectDir)/Wpf/bin/Jellyfish.Virtu.exe">
|
||||
<Modules>
|
||||
<Module Name="jellyfish.virtu.exe">
|
||||
<Namespaces>
|
||||
<Namespace Name="Jellyfish.Virtu">
|
||||
<Types>
|
||||
<Type Name="MainWindow">
|
||||
<Members>
|
||||
<Member Name="#System.Windows.Markup.IComponentConnector.Connect(System.Int32,System.Object)">
|
||||
<Messages>
|
||||
<Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2009-12-11 09:07:49Z">
|
||||
<Issue Name="Parameter">
|
||||
<Item>'target'</Item>
|
||||
<Item>'Button'</Item>
|
||||
<Item>'MainWindow.IComponentConnector.Connect(int, object)'</Item>
|
||||
<Item>castclass</Item>
|
||||
</Issue>
|
||||
</Message>
|
||||
</Messages>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
||||
</Types>
|
||||
</Namespace>
|
||||
</Namespaces>
|
||||
</Module>
|
||||
</Modules>
|
||||
</Target>
|
||||
</Targets>
|
||||
<Rules>
|
||||
<Rule TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800">
|
||||
<Resolution Name="Parameter">{0}, a parameter, is cast to type {1} multiple times in method {2}. Cache the result of the 'as' operator or direct cast in order to eliminate the redundant {3} instruction.</Resolution>
|
||||
</Rule>
|
||||
</Rules>
|
||||
</FxCopReport>
|
||||
<FxCopReport Version="10.0" />
|
||||
</FxCopProject>
|
||||
|
|
|
@ -47,8 +47,6 @@ public void Start()
|
|||
_storageService.Load(MachineSettings.FileName, stream => Settings.Deserialize(stream));
|
||||
|
||||
State = MachineState.Starting;
|
||||
Services.ForEach(service => service.Start());
|
||||
|
||||
Thread.Start();
|
||||
}
|
||||
|
||||
|
@ -68,15 +66,15 @@ public void Unpause()
|
|||
public void Stop()
|
||||
{
|
||||
State = MachineState.Stopping;
|
||||
Services.ForEach(service => service.Stop());
|
||||
|
||||
_pauseEvent.Set();
|
||||
_unpauseEvent.Set();
|
||||
Thread.Join();
|
||||
Thread.IsAliveJoin();
|
||||
State = MachineState.Stopped;
|
||||
|
||||
if (_storageService != null)
|
||||
{
|
||||
_storageService.Save(MachineSettings.FileName, stream => Settings.Serialize(stream));
|
||||
}
|
||||
}
|
||||
|
||||
private void Run() // machine thread
|
||||
{
|
||||
|
|
|
@ -36,29 +36,33 @@ public MachineSettings()
|
|||
Button0 = 0, Button1 = 0, Button2 = 0
|
||||
}
|
||||
};
|
||||
#if WINDOWS_PHONE
|
||||
Audio = new AudioSettings { Volume = 0.85 };
|
||||
#else
|
||||
Audio = new AudioSettings { Volume = 0.5 };
|
||||
#endif
|
||||
Video = new VideoSettings
|
||||
{
|
||||
IsFullScreen = false, IsMonochrome = false, ScannerOptions = ScannerOptions.None,
|
||||
Color = new ColorSettings
|
||||
{
|
||||
Black = 0x000000,
|
||||
DarkBlue = 0x000099,
|
||||
DarkGreen = 0x117722,
|
||||
MediumBlue = 0x0000FF,
|
||||
Brown = 0x885500,
|
||||
LightGrey = 0x99AAAA,
|
||||
Green = 0x00EE11,
|
||||
Aquamarine = 0x55FFAA,
|
||||
DeepRed = 0xFF1111,
|
||||
Purple = 0xDD00DD,
|
||||
DarkGrey = 0x445555,
|
||||
LightBlue = 0x33AAFF,
|
||||
Orange = 0xFF4411,
|
||||
Pink = 0xFF9988,
|
||||
Yellow = 0xFFFF11,
|
||||
White = 0xFFFFFF,
|
||||
Monochrome = 0x00AA00
|
||||
Black = 0xFF000000, // BGRA
|
||||
DarkBlue = 0xFF000099,
|
||||
DarkGreen = 0xFF117722,
|
||||
MediumBlue = 0xFF0000FF,
|
||||
Brown = 0xFF885500,
|
||||
LightGrey = 0xFF99AAAA,
|
||||
Green = 0xFF00EE11,
|
||||
Aquamarine = 0xFF55FFAA,
|
||||
DeepRed = 0xFFFF1111,
|
||||
Purple = 0xFFDD00DD,
|
||||
DarkGrey = 0xFF445555,
|
||||
LightBlue = 0xFF33AAFF,
|
||||
Orange = 0xFFFF4411,
|
||||
Pink = 0xFFFF9988,
|
||||
Yellow = 0xFFFFFF11,
|
||||
White = 0xFFFFFFFF,
|
||||
Monochrome = 0xFF00AA00
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading;
|
||||
using Jellyfish.Library;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
{
|
||||
|
@ -21,7 +22,7 @@ public void Output(int data) // machine thread
|
|||
_readEvent.Set();
|
||||
if (Machine.Settings.Cpu.IsThrottled)
|
||||
{
|
||||
_writeEvent.WaitOne();
|
||||
_writeEvent.WaitOne(SampleLatency * 2); // allow timeout; avoids deadlock
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,17 +34,11 @@ public void Reset()
|
|||
|
||||
public abstract void SetVolume(double volume); // machine thread
|
||||
|
||||
public override void Stop() // main thread
|
||||
{
|
||||
_readEvent.Set(); // signal events; avoids deadlock
|
||||
_writeEvent.Set();
|
||||
}
|
||||
|
||||
protected void Update(int bufferSize, Action<byte[], int> updateBuffer) // audio thread
|
||||
{
|
||||
if (Machine.State == MachineState.Running)
|
||||
{
|
||||
_readEvent.WaitOne();
|
||||
_readEvent.WaitOne(SampleLatency * 2); // allow timeout; avoids deadlock
|
||||
}
|
||||
if (updateBuffer != null)
|
||||
{
|
||||
|
|
|
@ -10,9 +10,14 @@ public DebugService(Machine machine) :
|
|||
{
|
||||
}
|
||||
|
||||
public virtual void WriteLine(string message)
|
||||
public void WriteLine(string message)
|
||||
{
|
||||
Debug.WriteLine(string.Concat(DateTime.Now, " ", message));
|
||||
OnWriteLine(string.Concat(DateTime.Now, ' ', message));
|
||||
}
|
||||
|
||||
protected virtual void OnWriteLine(string message)
|
||||
{
|
||||
Debug.WriteLine(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
namespace Jellyfish.Virtu.Services
|
||||
{
|
||||
public abstract class KeyboardService : MachineService
|
||||
{
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
{
|
||||
|
@ -21,15 +20,6 @@ public void Dispose()
|
|||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Stop")]
|
||||
public virtual void Stop()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using Jellyfish.Library;
|
||||
using Jellyfish.Virtu.Properties;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
|
@ -31,11 +30,6 @@ public void AddService(Type serviceType, MachineService serviceProvider)
|
|||
_serviceProviders.Add(serviceType, serviceProvider);
|
||||
}
|
||||
|
||||
public void ForEach(Action<MachineService> action)
|
||||
{
|
||||
_serviceProviders.Values.ForEach(action);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
|
||||
public T GetService<T>()
|
||||
{
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Windows" />
|
||||
<Reference Include="System.Windows.Browser" />
|
||||
<Reference Include="System.Windows.Controls.Toolkit, Version=4.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||
<Reference Include="System.Windows.Controls" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<Private>True</Private>
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
<UserControl x:Class="Jellyfish.Virtu.MainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:tk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
|
||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
||||
xmlns:jv="clr-namespace:Jellyfish.Virtu;assembly=Jellyfish.Virtu">
|
||||
<tk:DockPanel Background="Black">
|
||||
<StackPanel Orientation="Horizontal" tk:DockPanel.Dock="Top">
|
||||
<Button x:Name="_disk1Button" Content="Disk 1" IsTabStop="False" Margin="4 4 0 4"/>
|
||||
<Button x:Name="_disk2Button" Content="Disk 2" IsTabStop="False" Margin="4 4 0 4"/>
|
||||
<jl:FrameRateCounter Margin="4 4 0 4" VerticalAlignment="Center"/>
|
||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library">
|
||||
<Grid Background="Black">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Name="_disk1Button" Content="Disk 1" IsTabStop="False" Margin="4,4,0,4" />
|
||||
<Button x:Name="_disk2Button" Content="Disk 2" IsTabStop="False" Margin="4,4,0,4" />
|
||||
</StackPanel>
|
||||
<Grid>
|
||||
<Image x:Name="_image" MinWidth="280" MinHeight="192"/>
|
||||
<jl:FrameRateCounter Margin="0,0,4,0" HorizontalAlignment="Right" VerticalAlignment="Center" />
|
||||
<Grid Grid.Row="1">
|
||||
<Image x:Name="_image" MinWidth="560" MinHeight="384" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
<MediaElement x:Name="_media" />
|
||||
<ScrollViewer BorderThickness="0" IsTabStop="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock x:Name="_debug" FontFamily="Consolas" FontSize="12" Foreground="White"/>
|
||||
<ScrollViewer x:Name="_debugScrollViewer" BorderThickness="0" IsTabStop="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock x:Name="_debugText" FontFamily="Consolas" FontSize="12" Foreground="White" />
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</tk:DockPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
@ -13,6 +13,8 @@ public MainPage()
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (!DesignerProperties.IsInDesignTool)
|
||||
{
|
||||
_debugService = new SilverlightDebugService(_machine, this);
|
||||
_storageService = new IsolatedStorageService(_machine);
|
||||
_keyboardService = new SilverlightKeyboardService(_machine, this);
|
||||
|
@ -34,6 +36,7 @@ public MainPage()
|
|||
_disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
|
||||
_disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
@ -46,6 +49,13 @@ public void Dispose()
|
|||
_videoService.Dispose();
|
||||
}
|
||||
|
||||
public void WriteLine(string message)
|
||||
{
|
||||
_debugText.Text += message;
|
||||
_debugScrollViewer.UpdateLayout();
|
||||
_debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
|
||||
}
|
||||
|
||||
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
||||
{
|
||||
_keyboardService.Update();
|
||||
|
|
|
@ -54,8 +54,7 @@
|
|||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Phone.Controls" />
|
||||
<Reference Include="Microsoft.Phone.Controls.Navigation" />
|
||||
<Reference Include="Microsoft.Phone" />
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
|
|
@ -1,566 +1,13 @@
|
|||
<jl:ApplicationBase x:Class="Jellyfish.Virtu.MainApp"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:mpc="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
|
||||
xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
|
||||
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
|
||||
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
|
||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library">
|
||||
|
||||
<!--RootFrame points to and loads the first page of your application-->
|
||||
<Application.RootVisual>
|
||||
<phoneNavigation:PhoneApplicationFrame x:Name="RootFrame" Source="/MainPage.xaml"/>
|
||||
</Application.RootVisual>
|
||||
|
||||
<!-- Resources for following the Windows Phone design guidelines -->
|
||||
<Application.Resources>
|
||||
<!--************ THEME RESOURCES ************-->
|
||||
<!-- Color Resources -->
|
||||
<Color x:Key="PhoneBackgroundColor">#FF1F1F1F</Color>
|
||||
<Color x:Key="PhoneContrastForegroundColor">Black</Color>
|
||||
<Color x:Key="PhoneForegroundColor">White</Color>
|
||||
<Color x:Key="PhoneInactiveColor">#FF666666</Color>
|
||||
<Color x:Key="PhoneDisabledColor">#FF808080</Color>
|
||||
<Color x:Key="PhoneSubtleColor">#FF999999</Color>
|
||||
<Color x:Key="PhoneContrastBackgroundColor">#FFFFFFFF</Color>
|
||||
<Color x:Key="PhoneTextBoxColor">#FFBFBFBF</Color>
|
||||
<Color x:Key="PhoneBorderColor">#FFCCCCCC</Color>
|
||||
<Color x:Key="PhoneTextSelectionColor">Black</Color>
|
||||
<Color x:Key="PhoneAccentColor">#FF1BA1E2</Color>
|
||||
|
||||
<!-- Brush Resources -->
|
||||
<SolidColorBrush x:Key="PhoneAccentBrush" Color="{StaticResource PhoneAccentColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneBackgroundBrush" Color="{StaticResource PhoneBackgroundColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneContrastForegroundBrush" Color="{StaticResource PhoneContrastForegroundColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneForegroundBrush" Color="{StaticResource PhoneForegroundColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneInactiveBrush" Color="{StaticResource PhoneInactiveColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneDisabledBrush" Color="{StaticResource PhoneDisabledColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneSubtleBrush" Color="{StaticResource PhoneSubtleColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneContrastBackgroundBrush" Color="{StaticResource PhoneContrastBackgroundColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneTextBoxBrush" Color="{StaticResource PhoneTextBoxColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneBorderBrush" Color="{StaticResource PhoneBorderColor}"/>
|
||||
<SolidColorBrush x:Key="PhoneTextSelectionBrush" Color="{StaticResource PhoneTextSelectionColor}"/>
|
||||
<SolidColorBrush x:Key="TransparentBrush" Color="Transparent"/>
|
||||
|
||||
<!-- Touch Target Area -->
|
||||
<Thickness x:Key="PhoneTouchTargetOverhang">12</Thickness>
|
||||
|
||||
<!-- Default Border Size-->
|
||||
<Thickness x:Key="PhoneDefaultBorderThickness">3</Thickness>
|
||||
|
||||
<!-- Font Names -->
|
||||
<FontFamily x:Key="PhoneFontFamilyNormal">Segoe WP</FontFamily>
|
||||
<FontFamily x:Key="PhoneFontFamilyLight">Segoe WP Light</FontFamily>
|
||||
<FontFamily x:Key="PhoneFontFamilySemiLight">Segoe WP Semilight</FontFamily>
|
||||
<FontFamily x:Key="PhoneFontFamilySemiBold">Segoe WP Semibold</FontFamily>
|
||||
|
||||
<!-- Font sizes -->
|
||||
<!--14pt-->
|
||||
<system:Double x:Key="PhoneFontSizeSmall">18.667</system:Double>
|
||||
<!--15pt-->
|
||||
<system:Double x:Key="PhoneFontSizeNormal">20</system:Double>
|
||||
<!--17pt-->
|
||||
<system:Double x:Key="PhoneFontSizeMedium">22.667</system:Double>
|
||||
<!--19pt-->
|
||||
<system:Double x:Key="PhoneFontSizeMediumLarge">25.333</system:Double>
|
||||
<!--24pt-->
|
||||
<system:Double x:Key="PhoneFontSizeLarge">32</system:Double>
|
||||
<!--32pt-->
|
||||
<system:Double x:Key="PhoneFontSizeExtraLarge">42.667</system:Double>
|
||||
<!--54pt-->
|
||||
<system:Double x:Key="PhoneFontSizeExtraExtraLarge">72</system:Double>
|
||||
|
||||
<!-- TextBox styles -->
|
||||
<Style x:Key="PhoneTextBoxStyle" TargetType="TextBox">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeSmall}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneTextBoxBrush}"/>
|
||||
</Style>
|
||||
|
||||
<!-- TextBlock styles -->
|
||||
<Style x:Key="PhoneTextNormalStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextPageTitle1Style" TargetType="TextBlock" BasedOn="{StaticResource PhoneTextNormalStyle}">
|
||||
<Setter Property="Margin" Value="20,20,0,0" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextSubtleStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneSubtleBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextTitle1Style" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiLight}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeExtraExtraLarge}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextPageTitle2Style" TargetType="TextBlock" BasedOn="{StaticResource PhoneTextTitle1Style}">
|
||||
<Setter Property="Margin" Value="20,43,0,0" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextTitle2Style" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiLight}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeLarge}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextTitle3Style" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiLight}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextExtraLargeStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiLight}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeExtraLarge}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextGroupHeaderStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiLight}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeLarge}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneSubtleBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextLargeStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiLight}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeLarge}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextSmallStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeSmall}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneSubtleBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextContrastStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneContrastForegroundBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextAccentStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneAccentBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneTextBodyTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
<Setter Property="LineHeight" Value="32"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
<Setter Property="Margin" Value="20,20,20,0" />
|
||||
</Style>
|
||||
<!--************ THEME RESOURCES ************-->
|
||||
|
||||
<!--***** LISTBOX/LISTBOXITEM TEMPLATES *****-->
|
||||
<Style x:Key="PhoneListBox" TargetType="ListBox">
|
||||
<Setter Property="Padding" Value="1"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Top"/>
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
|
||||
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListBox">
|
||||
<Grid>
|
||||
<ScrollViewer Foreground="{TemplateBinding Foreground}" x:Name="ScrollViewer" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Margin="7,1,1,1">
|
||||
<ItemsPresenter/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="ItemContainerStyle">
|
||||
<Setter.Value>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Stretch"/>
|
||||
<Setter Property="Background" Value="{StaticResource TransparentBrush}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ListBoxItem">
|
||||
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal"/>
|
||||
<VisualState x:Name="MouseOver" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Background" Duration="0">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<SolidColorBrush Color="Transparent"/>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<DoubleAnimation Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" Duration="0" To=".55" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="SelectionStates">
|
||||
<VisualState x:Name="Unselected"/>
|
||||
<VisualState x:Name="Selected"/>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
<Grid Margin="{StaticResource PhoneTouchTargetOverhang}">
|
||||
<ContentPresenter x:Name="contentPresenter" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PhoneListBoxItemLayout" TargetType="mpc:ListViewItem">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="ImageStretch" Value="UniformToFill" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Height" Value="82"/>
|
||||
<!-- The intended height of the control is 95 but the ItemsControl pads each element with 12 -->
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="mpc:ListViewItem">
|
||||
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Margin="{TemplateBinding Padding}" Height="{TemplateBinding Height}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" x:Name="ItemText" Text="{TemplateBinding Text}" Style="{StaticResource PhoneTextExtraLargeStyle}" VerticalAlignment="Center" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" Margin="-3,-4,0,0"/>
|
||||
<ContentPresenter Grid.Column="1" x:Name="SecondaryContent" Content="{TemplateBinding SecondaryContent}" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="TextWithIconTemplate">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="mpc:ListViewItem">
|
||||
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Margin="{TemplateBinding Padding}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="43"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.Column="0" Source="{TemplateBinding ImageSource}" Stretch="{TemplateBinding ImageStretch}" Width="43" Height="43"/>
|
||||
<TextBlock Grid.Column="1" Margin="9,-4,0,0" x:Name="ItemText" Text="{TemplateBinding Text}" Style="{StaticResource PhoneTextExtraLargeStyle}" VerticalAlignment="Center" />
|
||||
<ContentPresenter Grid.Column="2" x:Name="SecondaryContent" Content="{TemplateBinding SecondaryContent}" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="TextAndDetailsTemplate">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="mpc:ListViewItem">
|
||||
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Margin="{TemplateBinding Padding}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0" VerticalAlignment="Center" >
|
||||
<TextBlock x:Name="ItemText" Text="{TemplateBinding Text}" Style="{StaticResource PhoneTextExtraLargeStyle}" HorizontalAlignment="Left" Margin="-3,-13,0,0" />
|
||||
<TextBlock x:Name="DetailsText" Text="{TemplateBinding Details}" Style="{StaticResource PhoneTextSubtleStyle}" HorizontalAlignment="Left" Margin="-1,-6,0,0" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="1" x:Name="SecondaryContent" Content="{TemplateBinding SecondaryContent}" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="TextAndDetailsWithIconTemplate">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="mpc:ListViewItem">
|
||||
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Margin="{TemplateBinding Padding}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="43"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image Grid.Column="0" Source="{TemplateBinding ImageSource}" Stretch="{TemplateBinding ImageStretch}" Width="43" Height="43" VerticalAlignment="Top"/>
|
||||
<StackPanel Grid.Column="1" Margin="12,0,0,0" VerticalAlignment="Center">
|
||||
<TextBlock x:Name="ItemText" Text="{TemplateBinding Text}" Style="{StaticResource PhoneTextExtraLargeStyle}" HorizontalAlignment="Left" Margin="-3,-13,0,0"/>
|
||||
<TextBlock x:Name="DetailsText" Text="{TemplateBinding Details}" Style="{StaticResource PhoneTextSubtleStyle}" HorizontalAlignment="Left" Margin="-1,-6,0,0" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="2" x:Name="SecondaryContent" Content="{TemplateBinding SecondaryContent}" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="CustomTemplate">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="mpc:ListViewItem">
|
||||
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Margin="{TemplateBinding Padding}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Margin="12,0,0,0" x:Name="ItemText" Text="{TemplateBinding Text}" Style="{StaticResource PhoneTextExtraLargeStyle}" VerticalAlignment="Center" />
|
||||
<ContentPresenter Grid.Column="1" x:Name="SecondaryContent" Content="{TemplateBinding SecondaryContent}" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<!--***** LISTBOX/LISTBOXITEM TEMPLATES *****-->
|
||||
|
||||
<!--************ BUTTON TEMPLATE ************-->
|
||||
<Style x:Key="PhoneButtonBase" TargetType="ButtonBase">
|
||||
<Setter Property="Background" Value="{StaticResource TransparentBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
|
||||
<Setter Property="MinHeight" Value="72" />
|
||||
<Setter Property="BorderThickness" Value="{StaticResource PhoneDefaultBorderThickness}"/>
|
||||
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
|
||||
<Setter Property="Padding" Value="10,0,10,5"/>
|
||||
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ButtonBase">
|
||||
<Grid Background="Transparent">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal"/>
|
||||
<VisualState x:Name="MouseOver"/>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="foregroundContainer" Storyboard.TargetProperty="Control.Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Border.Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundColor}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Border.BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundColor}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="foregroundContainer" Storyboard.TargetProperty="Control.Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Control.BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Control.Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="FocusStates">
|
||||
<VisualState x:Name="Focused"/>
|
||||
<VisualState x:Name="Unfocused"/>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}">
|
||||
<ContentControl x:Name="foregroundContainer" FontFamily="{TemplateBinding FontFamily}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" FontSize="{TemplateBinding FontSize}" Padding="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<!--************ BUTTON TEMPLATE ************-->
|
||||
|
||||
<!--********* PHONE SLIDER TEMPLATE *********-->
|
||||
<Style x:Key="PhoneSlider" TargetType="Slider">
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Maximum" Value="10"/>
|
||||
<Setter Property="Minimum" Value="0"/>
|
||||
<Setter Property="MinHeight" Value="84"/>
|
||||
<Setter Property="MinWidth" Value="60"/>
|
||||
<Setter Property="Value" Value="0"/>
|
||||
<Setter Property="BorderBrush" Value="{x:Null}"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneAccentBrush}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Slider">
|
||||
<Grid x:Name="Root" Background="{TemplateBinding Background}">
|
||||
<Grid.Resources>
|
||||
<ControlTemplate x:Key="PhoneSimpleRepeatButton" TargetType="RepeatButton">
|
||||
<Rectangle />
|
||||
</ControlTemplate>
|
||||
<ControlTemplate x:Key="PhoneSimpleThumb" TargetType="Thumb">
|
||||
<Rectangle />
|
||||
</ControlTemplate>
|
||||
</Grid.Resources>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal"/>
|
||||
<VisualState x:Name="MouseOver"/>
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Duration="0" Storyboard.TargetName="HorizontalTrack" Storyboard.TargetProperty="Opacity" To="0.55" />
|
||||
<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="HorizontalThumbDisabledOverlay" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<Visibility>Visible</Visibility>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<DoubleAnimation Duration="0" Storyboard.TargetName="VerticalTrack" Storyboard.TargetProperty="Opacity" To="0.55" />
|
||||
<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="VerticalThumbDisabledOverlay" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<Visibility>Visible</Visibility>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
<Grid x:Name="HorizontalTemplate">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="0"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Rectangle x:Name="HorizontalTrack" Fill="{StaticResource PhoneForegroundBrush}" Opacity="0.2" StrokeThickness="0" Grid.ColumnSpan="3" Margin="0,24,0,0" VerticalAlignment="Top" Height="12"/>
|
||||
<Rectangle Fill="{TemplateBinding Foreground}" StrokeThickness="0" Grid.Column="0" Margin="0,24,0,0" VerticalAlignment="Top" Height="12"/>
|
||||
<RepeatButton x:Name="HorizontalTrackLargeChangeDecreaseRepeatButton" IsTabStop="False" Template="{StaticResource PhoneSimpleRepeatButton}" Background="Transparent"/>
|
||||
<RepeatButton x:Name="HorizontalTrackLargeChangeIncreaseRepeatButton" IsTabStop="False" Template="{StaticResource PhoneSimpleRepeatButton}" Grid.Column="2" Background="Transparent"/>
|
||||
<Thumb x:Name="HorizontalThumb" Width="1" Margin="-1,0,0,0" Grid.Column="1" BorderThickness="0" Template="{StaticResource PhoneSimpleThumb}" Background="Transparent" RenderTransformOrigin="0.5,0.5">
|
||||
<Thumb.RenderTransform>
|
||||
<ScaleTransform ScaleX="32" ScaleY="1"/>
|
||||
</Thumb.RenderTransform>
|
||||
</Thumb>
|
||||
<Rectangle x:Name="HorizontalThumbDisabledOverlay" IsHitTestVisible="False" Opacity="0.55" Visibility="Collapsed" Fill="{StaticResource PhoneDisabledBrush}" Grid.Column="1" Height="12" Margin="0,24,0,0" VerticalAlignment="Top"/>
|
||||
</Grid>
|
||||
<Grid x:Name="VerticalTemplate">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="0"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Rectangle x:Name="VerticalTrack" Fill="{StaticResource PhoneForegroundBrush}" Opacity="0.2" StrokeThickness="0" HorizontalAlignment="Left" Margin="24,0,0,0" Width="12" Grid.RowSpan="3"/>
|
||||
<Rectangle Fill="{TemplateBinding Foreground}" StrokeThickness="0" Grid.Row="2" HorizontalAlignment="Left" Margin="24,0,0,0" Width="12"/>
|
||||
<RepeatButton x:Name="VerticalTrackLargeChangeDecreaseRepeatButton" IsTabStop="False" Template="{StaticResource PhoneSimpleRepeatButton}" Background="Transparent" Grid.Row="2"/>
|
||||
<RepeatButton x:Name="VerticalTrackLargeChangeIncreaseRepeatButton" IsTabStop="False" Template="{StaticResource PhoneSimpleRepeatButton}" Grid.Row="2" Background="Transparent"/>
|
||||
<Thumb x:Name="VerticalThumb" Width="{TemplateBinding Width}" Height="1" Margin="0,-1,0,0" IsTabStop="True" Grid.Row="1" BorderThickness="0" Template="{StaticResource PhoneSimpleThumb}" Background="Transparent" RenderTransformOrigin="0.5,0.5">
|
||||
<Thumb.RenderTransform>
|
||||
<ScaleTransform ScaleX="1" ScaleY="32"/>
|
||||
</Thumb.RenderTransform>
|
||||
</Thumb>
|
||||
<Rectangle x:Name="VerticalThumbDisabledOverlay" HorizontalAlignment="Left" Margin="24,0,0,0" Width="12" IsHitTestVisible="False" Opacity="0.55" Visibility="Collapsed" Fill="{StaticResource PhoneDisabledBrush}" Grid.Row="1"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<!--********* PHONE SLIDER TEMPLATE *********-->
|
||||
|
||||
<!--****** PHONE TOGGLESWITCH TEMPLATE ******-->
|
||||
<Style x:Key="PhoneToggleSwitch" TargetType="ToggleButton">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource PhoneBorderBrush}"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource PhoneBorderBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="2"/>
|
||||
<Setter Property="MinWidth" Value="136"/>
|
||||
<Setter Property="MaxWidth" Value="136"/>
|
||||
<Setter Property="MinHeight" Value="96"/>
|
||||
<Setter Property="MaxHeight" Value="96"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Grid Background="Transparent">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal"/>
|
||||
<VisualState x:Name="MouseOver" />
|
||||
<VisualState x:Name="Pressed"/>
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="border" Storyboard.TargetProperty="Visibility" >
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<Visibility>Collapsed</Visibility>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="borderDisabled" Storyboard.TargetProperty="Visibility" >
|
||||
<DiscreteObjectKeyFrame KeyTime="0">
|
||||
<DiscreteObjectKeyFrame.Value>
|
||||
<Visibility>Visible</Visibility>
|
||||
</DiscreteObjectKeyFrame.Value>
|
||||
</DiscreteObjectKeyFrame>
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="CheckStates">
|
||||
<VisualState x:Name="Checked" >
|
||||
<Storyboard>
|
||||
<DoubleAnimation Duration="00:00:00.3" Storyboard.TargetName="switchButton" Storyboard.TargetProperty="(Canvas.Left)" To="80" />
|
||||
<DoubleAnimation Duration="00:00:00.3" Storyboard.TargetName="rectangleSwitchOn" Storyboard.TargetProperty="Width" To="78" />
|
||||
<DoubleAnimation Duration="00:00:00.3" Storyboard.TargetName="switchButtonDisabled" Storyboard.TargetProperty="(Canvas.Left)" To="80" />
|
||||
<DoubleAnimation Duration="00:00:00.3" Storyboard.TargetName="rectangleSwitchOnDisabled" Storyboard.TargetProperty="Width" To="78" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Unchecked">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Duration="00:00:00.3" Storyboard.TargetName="switchButton" Storyboard.TargetProperty="(Canvas.Left)" To="0" />
|
||||
<DoubleAnimation Duration="00:00:00.3" Storyboard.TargetName="rectangleSwitchOn" Storyboard.TargetProperty="Width" To="0" />
|
||||
<DoubleAnimation Duration="00:00:00.3" Storyboard.TargetName="switchButtonDisabled" Storyboard.TargetProperty="(Canvas.Left)" To="0" />
|
||||
<DoubleAnimation Duration="00:00:00.3" Storyboard.TargetName="rectangleSwitchOnDisabled" Storyboard.TargetProperty="Width" To="0" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="FocusStates">
|
||||
<VisualState x:Name="Focused"/>
|
||||
<VisualState x:Name="Unfocused"/>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
|
||||
<Border x:Name="border" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Width="112" Height="32" HorizontalAlignment="Right" Margin="0,32,0,32" >
|
||||
<Canvas x:Name="switchContainer" Margin="2">
|
||||
<Rectangle x:Name="rectangleSwitchOn" Width="0" Height="24" Fill="{TemplateBinding Foreground}" />
|
||||
<Grid x:Name="switchButton" Width="24" Height="24" Canvas.Left="0" Background="{StaticResource PhoneForegroundBrush}" >
|
||||
<Rectangle Fill="{StaticResource PhoneBackgroundBrush}" Width="2" HorizontalAlignment="Left" StrokeThickness="0" Margin="5,4,0,4" />
|
||||
<Rectangle Fill="{StaticResource PhoneBackgroundBrush}" Width="2" HorizontalAlignment="Center" StrokeThickness="0" Margin="0,4,0,4" />
|
||||
<Rectangle Fill="{StaticResource PhoneBackgroundBrush}" Width="2" HorizontalAlignment="Right" StrokeThickness="0" Margin="0,4,5,4" />
|
||||
</Grid>
|
||||
</Canvas>
|
||||
</Border>
|
||||
|
||||
<Border x:Name="borderDisabled" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" BorderBrush="{StaticResource PhoneInactiveBrush}" Width="112" Height="32" HorizontalAlignment="Right" Margin="0,32,0,32" Visibility="Collapsed" >
|
||||
<Canvas x:Name="switchContainerDisabled" Margin="2">
|
||||
<Rectangle x:Name="rectangleSwitchOnDisabled" Width="0" Height="24" Fill="{StaticResource PhoneInactiveBrush}" />
|
||||
<Grid x:Name="switchButtonDisabled" Width="24" Height="24" Canvas.Left="0" Background="{StaticResource PhoneInactiveBrush}" />
|
||||
</Canvas>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<!--****** PHONE TOGGLESWITCH TEMPLATE ******-->
|
||||
</Application.Resources>
|
||||
|
||||
<Application.ApplicationLifetimeObjects>
|
||||
<shell:PhoneApplicationService />
|
||||
</Application.ApplicationLifetimeObjects>
|
||||
</jl:ApplicationBase>
|
|
@ -8,6 +8,7 @@ public MainApp() :
|
|||
base("Virtu")
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializePhoneApplication();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,32 @@
|
|||
<phoneNavigation:PhoneApplicationPage
|
||||
<phone:PhoneApplicationPage
|
||||
x:Class="Jellyfish.Virtu.MainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
|
||||
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
|
||||
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
||||
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
|
||||
FontFamily="{StaticResource PhoneFontFamilyNormal}"
|
||||
FontSize="{StaticResource PhoneFontSizeNormal}"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="480"
|
||||
FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}"
|
||||
Foreground="{StaticResource PhoneForegroundBrush}"
|
||||
SupportedOrientations="PortraitOrLandscape" Title="Virtu">
|
||||
|
||||
<!--<tk:DockPanel Background="Black">-->
|
||||
<Grid Background="{StaticResource PhoneBackgroundBrush}">
|
||||
<!--<StackPanel Orientation="Horizontal" tk:DockPanel.Dock="Top">-->
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!--<Button x:Name="_disk1Button" Content="Disk 1" IsTabStop="False" Margin="4 4 0 4" MaxHeight="60"/>
|
||||
<Button x:Name="_disk2Button" Content="Disk 2" IsTabStop="False" Margin="4 4 0 4" MaxHeight="60"/>-->
|
||||
<jl:FrameRateCounter Margin="4 4 0 4" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<Grid>
|
||||
<Image x:Name="_image" MinWidth="280" MinHeight="192"/>
|
||||
Orientation="Landscape" SupportedOrientations="Landscape" Title="Virtu">
|
||||
<Grid Background="Black">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<!--<StackPanel Orientation="Horizontal">
|
||||
<Button x:Name="_disk1Button" Content="Disk 1" IsTabStop="False" Margin="4,4,0,4" />
|
||||
<Button x:Name="_disk2Button" Content="Disk 2" IsTabStop="False" Margin="4,4,0,4" />
|
||||
</StackPanel>-->
|
||||
<jl:FrameRateCounter Margin="0,0,4,0" HorizontalAlignment="Right" VerticalAlignment="Center" />
|
||||
<Grid Grid.Row="1">
|
||||
<Image x:Name="_image" MinWidth="560" MinHeight="384" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
<MediaElement x:Name="_media" />
|
||||
<ScrollViewer BorderThickness="0" IsTabStop="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock x:Name="_debug" FontFamily="Consolas" FontSize="12" Foreground="White"/>
|
||||
<ScrollViewer x:Name="_debugScrollViewer" BorderThickness="0" IsTabStop="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock x:Name="_debugText" FontFamily="Consolas" FontSize="12" Foreground="White" />
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<!--</tk:DockPanel>-->
|
||||
|
||||
</phoneNavigation:PhoneApplicationPage>
|
||||
</phone:PhoneApplicationPage>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using Jellyfish.Virtu.Services;
|
||||
using Microsoft.Phone.Controls;
|
||||
|
@ -13,12 +13,16 @@ public MainPage()
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (!DesignerProperties.IsInDesignTool)
|
||||
{
|
||||
_debugService = new SilverlightDebugService(_machine, this);
|
||||
_storageService = new IsolatedStorageService(_machine);
|
||||
_keyboardService = new SilverlightKeyboardService(_machine, this);
|
||||
_gamePortService = new GamePortService(_machine); // not connected
|
||||
_audioService = new SilverlightAudioService(_machine, this, _media);
|
||||
_videoService = new SilverlightVideoService(_machine, this, _image);
|
||||
|
||||
_machine.Services.AddService(typeof(DebugService), _debugService);
|
||||
_machine.Services.AddService(typeof(StorageService), _storageService);
|
||||
_machine.Services.AddService(typeof(KeyboardService), _keyboardService);
|
||||
_machine.Services.AddService(typeof(GamePortService), _gamePortService);
|
||||
|
@ -32,10 +36,12 @@ public MainPage()
|
|||
//_disk1Button.Click += (sender, e) => OnDiskButtonClick(0); // TODO
|
||||
//_disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_machine.Dispose();
|
||||
_debugService.Dispose();
|
||||
_storageService.Dispose();
|
||||
_keyboardService.Dispose();
|
||||
_gamePortService.Dispose();
|
||||
|
@ -43,6 +49,13 @@ public void Dispose()
|
|||
_videoService.Dispose();
|
||||
}
|
||||
|
||||
public void WriteLine(string message)
|
||||
{
|
||||
_debugText.Text += message;
|
||||
_debugScrollViewer.UpdateLayout();
|
||||
_debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
|
||||
}
|
||||
|
||||
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
||||
{
|
||||
_keyboardService.Update();
|
||||
|
@ -68,6 +81,7 @@ private void OnCompositionTargetRendering(object sender, EventArgs e)
|
|||
|
||||
private Machine _machine = new Machine();
|
||||
|
||||
private DebugService _debugService;
|
||||
private StorageService _storageService;
|
||||
private KeyboardService _keyboardService;
|
||||
private GamePortService _gamePortService;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0">
|
||||
<App xmlns="" ProductID="{89a50370-1ed9-4cf1-ad08-043b6e6f3c90}" Title="Virtu" RuntimeType="SilverLight" Version="1.0.0.0" Genre="NormalApp" Author="" Description="" Publisher="">
|
||||
<App xmlns="" ProductID="{89a50370-1ed9-4cf1-ad08-043b6e6f3c90}" Title="Virtu" RuntimeType="Silverlight" Version="1.0.0.0" Genre="Apps.Normal" Author="Sean Fausett & Nick Westgate" Description="Apple IIe Emulator" Publisher="Digital Jellyfish Design Ltd">
|
||||
<IconPath IsRelative="true" IsResource="false">AppIcon.png</IconPath>
|
||||
<Capabilities>
|
||||
<Capability Name="ID_CAP_NETWORKING" />
|
||||
|
@ -14,7 +14,7 @@
|
|||
<Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
|
||||
</Capabilities>
|
||||
<Tasks>
|
||||
<DefaultTask Name="_default" PlaceHolderString="Default task" />
|
||||
<DefaultTask Name="_default" NavigationPage="MainPage.xaml" />
|
||||
</Tasks>
|
||||
<Tokens>
|
||||
<PrimaryToken TokenID="Jellyfish.Virtu.Silverlight.Phone.Token" TaskName="_default">
|
||||
|
|
|
@ -18,14 +18,13 @@ public SilverlightAudioService(Machine machine, UserControl page, MediaElement m
|
|||
throw new ArgumentNullException("media");
|
||||
}
|
||||
|
||||
_page = page;
|
||||
_media = media;
|
||||
_mediaSource = new WaveMediaStreamSource(SampleRate, SampleChannels, SampleBits, SampleSize, SampleLatency, OnMediaSourceUpdate);
|
||||
_media.SetSource(_mediaSource);
|
||||
|
||||
_page.Loaded += (sender, e) => _media.Play();
|
||||
page.Loaded += (sender, e) => _media.Play();
|
||||
#if !WINDOWS_PHONE
|
||||
_page.Unloaded += (sender, e) => _media.Stop();
|
||||
page.Unloaded += (sender, e) => _media.Stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -54,7 +53,6 @@ private void OnMediaSourceUpdate(byte[] buffer, int bufferSize) // audio thread
|
|||
Update(bufferSize, (source, count) => Buffer.BlockCopy(source, 0, buffer, 0, count));
|
||||
}
|
||||
|
||||
private UserControl _page;
|
||||
private MediaElement _media;
|
||||
private WaveMediaStreamSource _mediaSource;
|
||||
//private int _count;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Jellyfish.Library;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
{
|
||||
|
@ -15,18 +16,9 @@ public SilverlightDebugService(Machine machine, MainPage page) :
|
|||
_page = page;
|
||||
}
|
||||
|
||||
public override void WriteLine(string message)
|
||||
protected override void OnWriteLine(string message)
|
||||
{
|
||||
message = string.Concat(DateTime.Now, " ", message, Environment.NewLine);
|
||||
|
||||
if (_page.CheckAccess())
|
||||
{
|
||||
_page._debug.Text += message;
|
||||
}
|
||||
else
|
||||
{
|
||||
_page.Dispatcher.BeginInvoke(() => _page._debug.Text += message);
|
||||
}
|
||||
_page.Dispatcher.CheckBeginInvoke(() => _page.WriteLine(message + Environment.NewLine));
|
||||
}
|
||||
|
||||
private MainPage _page;
|
||||
|
|
|
@ -17,11 +17,9 @@ public SilverlightKeyboardService(Machine machine, UserControl page) :
|
|||
throw new ArgumentNullException("page");
|
||||
}
|
||||
|
||||
_page = page;
|
||||
|
||||
_page.KeyDown += OnPageKeyDown;
|
||||
_page.KeyUp += OnPageKeyUp;
|
||||
_page.LostFocus += OnPageLostFocus;
|
||||
page.KeyDown += OnPageKeyDown;
|
||||
page.KeyUp += OnPageKeyUp;
|
||||
page.LostFocus += OnPageLostFocus;
|
||||
}
|
||||
|
||||
public override bool IsKeyDown(int key)
|
||||
|
@ -396,7 +394,6 @@ where field.IsLiteral
|
|||
|
||||
private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
|
||||
|
||||
private UserControl _page;
|
||||
private bool[] _states = new bool[KeyCount];
|
||||
private bool _capsLock;
|
||||
private bool _updateAnyKeyDown;
|
||||
|
|
|
@ -27,21 +27,18 @@ public SilverlightVideoService(Machine machine, UserControl page, Image image) :
|
|||
_image = image;
|
||||
_image.Source = _bitmap;
|
||||
|
||||
var content = Application.Current.Host.Content;
|
||||
#if WINDOWS_PHONE
|
||||
((Page)_page).OrientationChanged += (sender, e) => SetImageSize(swapOrientation: (e.Orientation & PageOrientation.Landscape) != 0);
|
||||
#else
|
||||
#if !WINDOWS_PHONE
|
||||
_page.LayoutUpdated += (sender, e) => SetWindowSizeToContent();
|
||||
content.FullScreenChanged += (sender, e) => SetImageSize();
|
||||
#else
|
||||
((PhoneApplicationPage)_page).OrientationChanged += (sender, e) => SetImageSize(swapOrientation: (e.Orientation & PageOrientation.Landscape) != 0);
|
||||
#endif
|
||||
content.Resized += (sender, e) => SetImageSize();
|
||||
_page.SizeChanged += (sender, e) => SetImageSize();
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
|
||||
public override void SetPixel(int x, int y, uint color)
|
||||
{
|
||||
_pixels[y * BitmapWidth + x] = (int)color;
|
||||
_pixels[(y + 1) * BitmapWidth + x] = (_imageScale < 1) ? (int)color : 0x0;
|
||||
_pixelsDirty = true;
|
||||
}
|
||||
|
||||
|
@ -67,15 +64,10 @@ public override void Update() // main thread
|
|||
|
||||
private void SetImageSize(bool swapOrientation = false)
|
||||
{
|
||||
var content = Application.Current.Host.Content;
|
||||
_imageScale = swapOrientation ? Math.Min(content.ActualHeight / BitmapWidth, content.ActualWidth / BitmapHeight) :
|
||||
Math.Min(content.ActualWidth / BitmapWidth, content.ActualHeight / BitmapHeight);
|
||||
if (_imageScale > 1)
|
||||
{
|
||||
_imageScale = Math.Floor(_imageScale); // integer scale up
|
||||
}
|
||||
_image.Width = _imageScale * BitmapWidth;
|
||||
_image.Height = _imageScale * BitmapHeight;
|
||||
int uniformScale = Math.Max(1, swapOrientation ? Math.Min((int)_page.RenderSize.Height / BitmapWidth, (int)_page.RenderSize.Width / BitmapHeight) :
|
||||
Math.Min((int)_page.RenderSize.Width / BitmapWidth, (int)_page.RenderSize.Height / BitmapHeight));
|
||||
_image.Width = uniformScale * BitmapWidth;
|
||||
_image.Height = uniformScale * BitmapHeight;
|
||||
Machine.Video.DirtyScreen();
|
||||
}
|
||||
|
||||
|
@ -98,7 +90,6 @@ private void SetWindowSizeToContent()
|
|||
|
||||
private UserControl _page;
|
||||
private Image _image;
|
||||
private double _imageScale;
|
||||
private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight);
|
||||
private int[] _pixels = new int[BitmapWidth * BitmapHeight];
|
||||
private bool _pixelsDirty;
|
||||
|
|
|
@ -61,6 +61,10 @@
|
|||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Page Include="MainPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
|
@ -69,6 +73,9 @@
|
|||
<DependentUpon>MainApp.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainPage.xaml.cs">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
|
|
23
Virtu/Wpf/MainPage.xaml
Normal file
23
Virtu/Wpf/MainPage.xaml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<UserControl x:Class="Jellyfish.Virtu.MainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
||||
Focusable="True">
|
||||
<Grid Background="Black">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Name="_disk1Button" Content="Disk 1" Focusable="False" IsTabStop="False" Margin="4,4,0,4" />
|
||||
<Button x:Name="_disk2Button" Content="Disk 2" Focusable="False" IsTabStop="False" Margin="4,4,0,4" />
|
||||
</StackPanel>
|
||||
<jl:FrameRateCounter Margin="0,0,4,0" HorizontalAlignment="Right" VerticalAlignment="Center" />
|
||||
<Grid Grid.Row="1">
|
||||
<Image x:Name="_image" MinWidth="560" MinHeight="384" RenderOptions.BitmapScalingMode="NearestNeighbor" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
<ScrollViewer x:Name="_debugScrollViewer" BorderThickness="0" Focusable="False" IsTabStop="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock x:Name="_debugText" FontFamily="Consolas" FontSize="12" Foreground="White" />
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
102
Virtu/Wpf/MainPage.xaml.cs
Normal file
102
Virtu/Wpf/MainPage.xaml.cs
Normal file
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using Jellyfish.Virtu.Services;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Jellyfish.Virtu
|
||||
{
|
||||
public sealed partial class MainPage : UserControl, IDisposable
|
||||
{
|
||||
public MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (!DesignerProperties.GetIsInDesignMode(this))
|
||||
{
|
||||
_debugService = new WpfDebugService(_machine, this);
|
||||
_storageService = new WpfStorageService(_machine);
|
||||
_keyboardService = new WpfKeyboardService(_machine, this);
|
||||
_gamePortService = new GamePortService(_machine); // not connected
|
||||
_audioService = new WpfAudioService(_machine, this);
|
||||
_videoService = new WpfVideoService(_machine, this, _image);
|
||||
|
||||
_machine.Services.AddService(typeof(DebugService), _debugService);
|
||||
_machine.Services.AddService(typeof(StorageService), _storageService);
|
||||
_machine.Services.AddService(typeof(KeyboardService), _keyboardService);
|
||||
_machine.Services.AddService(typeof(GamePortService), _gamePortService);
|
||||
_machine.Services.AddService(typeof(AudioService), _audioService);
|
||||
_machine.Services.AddService(typeof(VideoService), _videoService);
|
||||
|
||||
Loaded += (sender, e) => _machine.Start();
|
||||
CompositionTarget.Rendering += OnCompositionTargetRendering;
|
||||
Application.Current.Exit += (sender, e) => _machine.Stop();
|
||||
|
||||
_disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
|
||||
_disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_machine.Dispose();
|
||||
_debugService.Dispose();
|
||||
_storageService.Dispose();
|
||||
_keyboardService.Dispose();
|
||||
_gamePortService.Dispose();
|
||||
_audioService.Dispose();
|
||||
_videoService.Dispose();
|
||||
}
|
||||
|
||||
public void WriteLine(string message)
|
||||
{
|
||||
_debugText.Text += message;
|
||||
_debugScrollViewer.UpdateLayout();
|
||||
_debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
|
||||
}
|
||||
|
||||
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
||||
{
|
||||
_keyboardService.Update();
|
||||
_gamePortService.Update();
|
||||
_videoService.Update();
|
||||
}
|
||||
|
||||
private void OnDiskButtonClick(int drive)
|
||||
{
|
||||
var dialog = new OpenFileDialog() { Filter = "Disk Files (*.dsk;*.nib)|*.dsk;*.nib|All Files (*.*)|*.*" };
|
||||
|
||||
bool? result = dialog.ShowDialog();
|
||||
if (result.HasValue && result.Value)
|
||||
{
|
||||
using (var stream = File.OpenRead(dialog.FileName))
|
||||
{
|
||||
_machine.Pause();
|
||||
_machine.DiskII.Drives[drive].InsertDisk(dialog.FileName, stream, false);
|
||||
var settings = _machine.Settings.DiskII;
|
||||
if (drive == 0)
|
||||
{
|
||||
settings.Disk1.Name = dialog.FileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.Disk2.Name = dialog.FileName;
|
||||
}
|
||||
_machine.Unpause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Machine _machine = new Machine();
|
||||
|
||||
private DebugService _debugService;
|
||||
private StorageService _storageService;
|
||||
private KeyboardService _keyboardService;
|
||||
private GamePortService _gamePortService;
|
||||
private AudioService _audioService;
|
||||
private VideoService _videoService;
|
||||
}
|
||||
}
|
|
@ -1,19 +1,7 @@
|
|||
<Window x:Class="Jellyfish.Virtu.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
||||
Title="Virtu" ResizeMode="CanMinimize" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen">
|
||||
<DockPanel Background="Black">
|
||||
<StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
|
||||
<Button x:Name="_disk1Button" Content="Disk 1" Focusable="False" IsTabStop="False" Margin="4 4 0 4"/>
|
||||
<Button x:Name="_disk2Button" Content="Disk 2" Focusable="False" IsTabStop="False" Margin="4 4 0 4"/>
|
||||
<jl:FrameRateCounter Margin="4 4 0 4" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<Grid>
|
||||
<Image x:Name="_image" MinWidth="560" MinHeight="384" RenderOptions.BitmapScalingMode="NearestNeighbor"/>
|
||||
<ScrollViewer BorderThickness="0" Focusable="False" IsTabStop="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock x:Name="_debug" FontFamily="Consolas" FontSize="12" Foreground="White"/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
xmlns:jv="clr-namespace:Jellyfish.Virtu"
|
||||
Title="Virtu" WindowStartupLocation="CenterScreen" FocusManager.FocusedElement="{Binding ElementName=_mainPage}">
|
||||
<jv:MainPage x:Name="_mainPage" />
|
||||
</Window>
|
||||
|
|
|
@ -1,91 +1,12 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Jellyfish.Virtu.Services;
|
||||
using Jellyfish.Virtu.Settings;
|
||||
using Microsoft.Win32;
|
||||
using System.Windows;
|
||||
|
||||
namespace Jellyfish.Virtu
|
||||
{
|
||||
public sealed partial class MainWindow : Window, IDisposable
|
||||
public sealed partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_debugService = new WpfDebugService(_machine, this);
|
||||
_storageService = new WpfStorageService(_machine);
|
||||
_keyboardService = new WpfKeyboardService(_machine, this);
|
||||
_gamePortService = new GamePortService(_machine); // not connected
|
||||
_audioService = new WpfAudioService(_machine, this);
|
||||
_videoService = new WpfVideoService(_machine, this, _image);
|
||||
|
||||
_machine.Services.AddService(typeof(DebugService), _debugService);
|
||||
_machine.Services.AddService(typeof(StorageService), _storageService);
|
||||
_machine.Services.AddService(typeof(KeyboardService), _keyboardService);
|
||||
_machine.Services.AddService(typeof(GamePortService), _gamePortService);
|
||||
_machine.Services.AddService(typeof(AudioService), _audioService);
|
||||
_machine.Services.AddService(typeof(VideoService), _videoService);
|
||||
|
||||
Loaded += (sender, e) => _machine.Start();
|
||||
CompositionTarget.Rendering += OnCompositionTargetRendering;
|
||||
Application.Current.Exit += (sender, e) => _machine.Stop();
|
||||
|
||||
_disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
|
||||
_disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_machine.Dispose();
|
||||
_debugService.Dispose();
|
||||
_storageService.Dispose();
|
||||
_keyboardService.Dispose();
|
||||
_gamePortService.Dispose();
|
||||
_audioService.Dispose();
|
||||
_videoService.Dispose();
|
||||
}
|
||||
|
||||
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
||||
{
|
||||
_keyboardService.Update();
|
||||
_gamePortService.Update();
|
||||
_videoService.Update();
|
||||
}
|
||||
|
||||
private void OnDiskButtonClick(int drive)
|
||||
{
|
||||
var dialog = new OpenFileDialog() { Filter = "Disk Files (*.dsk;*.nib)|*.dsk;*.nib|All Files (*.*)|*.*" };
|
||||
|
||||
bool? result = dialog.ShowDialog();
|
||||
if (result.HasValue && result.Value)
|
||||
{
|
||||
using (var stream = File.OpenRead(dialog.FileName))
|
||||
{
|
||||
_machine.Pause();
|
||||
_machine.DiskII.Drives[drive].InsertDisk(dialog.FileName, stream, false);
|
||||
var settings = _machine.Settings.DiskII;
|
||||
if (drive == 0)
|
||||
{
|
||||
settings.Disk1.Name = dialog.FileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.Disk2.Name = dialog.FileName;
|
||||
}
|
||||
_machine.Unpause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Machine _machine = new Machine();
|
||||
|
||||
private DebugService _debugService;
|
||||
private StorageService _storageService;
|
||||
private KeyboardService _keyboardService;
|
||||
private GamePortService _gamePortService;
|
||||
private AudioService _audioService;
|
||||
private VideoService _videoService;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Jellyfish.Library;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
|
@ -9,19 +10,22 @@ namespace Jellyfish.Virtu.Services
|
|||
public sealed class WpfAudioService : AudioService
|
||||
{
|
||||
[SecurityCritical]
|
||||
public WpfAudioService(Machine machine, Window window) :
|
||||
public WpfAudioService(Machine machine, UserControl page) :
|
||||
base(machine)
|
||||
{
|
||||
if (window == null)
|
||||
if (page == null)
|
||||
{
|
||||
throw new ArgumentNullException("window");
|
||||
throw new ArgumentNullException("page");
|
||||
}
|
||||
|
||||
_window = window;
|
||||
_directSound = new DirectSound(SampleRate, SampleChannels, SampleBits, SampleSize, OnDirectSoundUpdate);
|
||||
|
||||
_window.SourceInitialized += (sender, e) => _directSound.Start(_window.GetHandle());
|
||||
_window.Closed += (sender, e) => _directSound.Stop();
|
||||
page.Loaded += (sender, e) =>
|
||||
{
|
||||
var window = Window.GetWindow(page);
|
||||
_directSound.Start(window.GetHandle());
|
||||
window.Closed += (_sender, _e) => _directSound.Stop();
|
||||
};
|
||||
}
|
||||
|
||||
public override void SetVolume(double volume) // machine thread
|
||||
|
@ -49,7 +53,6 @@ private void OnDirectSoundUpdate(IntPtr buffer, int bufferSize) // audio thread
|
|||
Update(bufferSize, (source, count) => Marshal.Copy(source, 0, buffer, count));
|
||||
}
|
||||
|
||||
private Window _window;
|
||||
private DirectSound _directSound;
|
||||
//private int _count;
|
||||
}
|
||||
|
|
|
@ -1,34 +1,26 @@
|
|||
using System;
|
||||
using Jellyfish.Library;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
{
|
||||
public sealed class WpfDebugService : DebugService
|
||||
{
|
||||
public WpfDebugService(Machine machine, MainWindow window) :
|
||||
public WpfDebugService(Machine machine, MainPage page) :
|
||||
base(machine)
|
||||
{
|
||||
if (window == null)
|
||||
if (page == null)
|
||||
{
|
||||
throw new ArgumentNullException("window");
|
||||
throw new ArgumentNullException("page");
|
||||
}
|
||||
|
||||
_window = window;
|
||||
_page = page;
|
||||
}
|
||||
|
||||
public override void WriteLine(string message)
|
||||
protected override void OnWriteLine(string message)
|
||||
{
|
||||
message = string.Concat(DateTime.Now, " ", message, Environment.NewLine);
|
||||
|
||||
if (_window.CheckAccess())
|
||||
{
|
||||
_window._debug.Text += message;
|
||||
}
|
||||
else
|
||||
{
|
||||
_window.Dispatcher.BeginInvoke(new Action(() => _window._debug.Text += message));
|
||||
}
|
||||
_page.Dispatcher.CheckInvoke(() => _page.WriteLine(message + Environment.NewLine));
|
||||
}
|
||||
|
||||
private MainWindow _window;
|
||||
private MainPage _page;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
{
|
||||
public sealed class WpfKeyboardService : KeyboardService
|
||||
{
|
||||
public WpfKeyboardService(Machine machine, Window window) :
|
||||
public WpfKeyboardService(Machine machine, UserControl page) :
|
||||
base(machine)
|
||||
{
|
||||
if (window == null)
|
||||
if (page == null)
|
||||
{
|
||||
throw new ArgumentNullException("window");
|
||||
throw new ArgumentNullException("page");
|
||||
}
|
||||
|
||||
_window = window;
|
||||
|
||||
_window.KeyDown += OnWindowKeyDown;
|
||||
_window.KeyUp += OnWindowKeyUp;
|
||||
_window.GotKeyboardFocus += (sender, e) => _updateAnyKeyDown = true;
|
||||
page.KeyDown += OnPageKeyDown;
|
||||
page.KeyUp += OnPageKeyUp;
|
||||
page.GotKeyboardFocus += (sender, e) => _updateAnyKeyDown = true;
|
||||
}
|
||||
|
||||
public override bool IsKeyDown(int key)
|
||||
|
@ -60,9 +58,9 @@ private bool IsKeyDown(Key key)
|
|||
return _states[(int)key];
|
||||
}
|
||||
|
||||
private void OnWindowKeyDown(object sender, KeyEventArgs e)
|
||||
private void OnPageKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
//DebugService.WriteLine(string.Concat("OnWindowKeyDn: Key=", e.Key));
|
||||
//DebugService.WriteLine(string.Concat("OnPageKeyDn: Key=", e.Key));
|
||||
|
||||
_states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = true;
|
||||
_updateAnyKeyDown = false;
|
||||
|
@ -78,9 +76,9 @@ private void OnWindowKeyDown(object sender, KeyEventArgs e)
|
|||
Update();
|
||||
}
|
||||
|
||||
private void OnWindowKeyUp(object sender, KeyEventArgs e)
|
||||
private void OnPageKeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
//DebugService.WriteLine(string.Concat("OnWindowKeyUp: Key=", e.Key));
|
||||
//DebugService.WriteLine(string.Concat("OnPageKeyUp: Key=", e.Key));
|
||||
|
||||
_states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = false;
|
||||
_updateAnyKeyDown = true;
|
||||
|
@ -292,7 +290,6 @@ private static int GetAsciiKey(Key key, KeyboardDevice keyboard)
|
|||
|
||||
private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
|
||||
|
||||
private Window _window;
|
||||
private bool[] _states = new bool[KeyCount];
|
||||
private bool _updateAnyKeyDown;
|
||||
}
|
||||
|
|
|
@ -1,36 +1,32 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Jellyfish.Virtu.Services
|
||||
{
|
||||
public sealed class WpfVideoService : VideoService
|
||||
{
|
||||
[SecurityCritical]
|
||||
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
|
||||
public WpfVideoService(Machine machine, Window window, Image image) :
|
||||
public WpfVideoService(Machine machine, UserControl page, Image image) :
|
||||
base(machine)
|
||||
{
|
||||
if (window == null)
|
||||
if (page == null)
|
||||
{
|
||||
throw new ArgumentNullException("window");
|
||||
throw new ArgumentNullException("page");
|
||||
}
|
||||
if (image == null)
|
||||
{
|
||||
throw new ArgumentNullException("image");
|
||||
}
|
||||
|
||||
_window = window;
|
||||
_page = page;
|
||||
_image = image;
|
||||
_image.Source = _bitmap;
|
||||
|
||||
_window.SizeChanged += (sender, e) => SetImageSize();
|
||||
SystemEvents.DisplaySettingsChanged += (sender, e) => SetImageSize();
|
||||
_page.Loaded += (sender, e) => SetWindowSizeToContent();
|
||||
_page.SizeChanged += (sender, e) => SetImageSize();
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
|
||||
|
@ -44,17 +40,18 @@ public override void Update() // main thread
|
|||
{
|
||||
if (_isFullScreen != IsFullScreen)
|
||||
{
|
||||
var window = Window.GetWindow(_page);
|
||||
if (IsFullScreen)
|
||||
{
|
||||
_window.SizeToContent = SizeToContent.Manual;
|
||||
_window.WindowStyle = WindowStyle.None;
|
||||
_window.WindowState = WindowState.Maximized;
|
||||
window.ResizeMode = ResizeMode.NoResize;
|
||||
window.WindowStyle = WindowStyle.None;
|
||||
window.WindowState = WindowState.Maximized;
|
||||
}
|
||||
else
|
||||
{
|
||||
_window.WindowState = WindowState.Normal;
|
||||
_window.WindowStyle = WindowStyle.SingleBorderWindow;
|
||||
_window.SizeToContent = SizeToContent.WidthAndHeight;
|
||||
window.WindowState = WindowState.Normal;
|
||||
window.WindowStyle = WindowStyle.SingleBorderWindow;
|
||||
window.ResizeMode = ResizeMode.CanResize;
|
||||
}
|
||||
_isFullScreen = IsFullScreen;
|
||||
}
|
||||
|
@ -68,13 +65,24 @@ public override void Update() // main thread
|
|||
|
||||
private void SetImageSize()
|
||||
{
|
||||
int uniformScale = IsFullScreen ? Math.Min((int)SystemParameters.PrimaryScreenWidth / BitmapWidth, (int)SystemParameters.PrimaryScreenHeight / BitmapHeight) :
|
||||
Math.Min((int)SystemParameters.FullPrimaryScreenWidth / BitmapWidth, (int)SystemParameters.FullPrimaryScreenHeight / BitmapHeight);
|
||||
int uniformScale = Math.Max(1, Math.Min((int)_page.RenderSize.Width / BitmapWidth, (int)_page.RenderSize.Height / BitmapHeight));
|
||||
_image.Width = uniformScale * BitmapWidth;
|
||||
_image.Height = uniformScale * BitmapHeight;
|
||||
Machine.Video.DirtyScreen();
|
||||
}
|
||||
|
||||
private void SetWindowSizeToContent()
|
||||
{
|
||||
if (!_sizedToContent)
|
||||
{
|
||||
_sizedToContent = true;
|
||||
var window = Application.Current.MainWindow;
|
||||
var size = window.DesiredSize;
|
||||
window.Width = size.Width;
|
||||
window.Height = size.Height;
|
||||
}
|
||||
}
|
||||
|
||||
private const int BitmapWidth = 560;
|
||||
private const int BitmapHeight = 384;
|
||||
private const int BitmapDpi = 96;
|
||||
|
@ -82,11 +90,12 @@ private void SetImageSize()
|
|||
private static readonly int BitmapStride = (BitmapWidth * BitmapPixelFormat.BitsPerPixel + 7) / 8;
|
||||
private static readonly Int32Rect BitmapRect = new Int32Rect(0, 0, BitmapWidth, BitmapHeight);
|
||||
|
||||
private Window _window;
|
||||
private UserControl _page;
|
||||
private Image _image;
|
||||
private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight, BitmapDpi, BitmapDpi, BitmapPixelFormat, null);
|
||||
private uint[] _pixels = new uint[BitmapWidth * BitmapHeight];
|
||||
private bool _pixelsDirty;
|
||||
private bool _isFullScreen;
|
||||
private bool _sizedToContent;
|
||||
}
|
||||
}
|
||||
|
|
BIN
Virtu/Xna/Background.png
Normal file
BIN
Virtu/Xna/Background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -18,10 +18,12 @@
|
|||
<XnaOutputType>Game</XnaOutputType>
|
||||
<XapFilename>$(AssemblyName).xap</XapFilename>
|
||||
<SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate>
|
||||
<XnaWindowsPhoneManifestTemplate>Properties\WindowsPhoneManifest.xml</XnaWindowsPhoneManifestTemplate>
|
||||
<XnaWindowsPhoneManifestTemplate>Properties\WMAppManifest.xml</XnaWindowsPhoneManifestTemplate>
|
||||
<ApplicationIcon>AppIcon.ico</ApplicationIcon>
|
||||
<Thumbnail>AppThumbnail.png</Thumbnail>
|
||||
<GameStartupType>Jellyfish.Virtu.MainGame</GameStartupType>
|
||||
<TileImage>Background.png</TileImage>
|
||||
<TileTitle>Virtu</TileTitle>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Windows Phone' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -189,14 +191,19 @@
|
|||
<Compile Include="MainGame.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Properties\AppManifest.xml">
|
||||
<XnaPlatformSpecific>true</XnaPlatformSpecific>
|
||||
</None>
|
||||
<None Include="Properties\WMAppManifest.xml">
|
||||
<XnaPlatformSpecific>true</XnaPlatformSpecific>
|
||||
</None>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Properties\AppManifest.xml" />
|
||||
<Content Include="Properties\WindowsPhoneManifest.xml" />
|
||||
<Content Include="AppIcon.ico" />
|
||||
<Content Include="AppThumbnail.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<Content Include="AppThumbnail.png" />
|
||||
<Content Include="Background.png">
|
||||
<XnaPlatformSpecific>true</XnaPlatformSpecific>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -63,9 +63,6 @@
|
|||
<Reference Include="Microsoft.Xna.Framework.GamerServices">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Input.Touch">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Xact">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
|
@ -202,9 +199,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="AppIcon.ico" />
|
||||
<Content Include="AppThumbnail.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="AppThumbnail.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\Properties\Strings.resx">
|
||||
|
|
|
@ -63,9 +63,6 @@
|
|||
<Reference Include="Microsoft.Xna.Framework.GamerServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=x86">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Input.Touch, Version=4.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=x86">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d, processorArchitecture=x86">
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
|
@ -203,9 +200,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="AppIcon.ico" />
|
||||
<Content Include="AppThumbnail.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="AppThumbnail.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\Properties\Strings.resx">
|
||||
|
|
|
@ -10,13 +10,9 @@ public sealed class MainGame : GameBase
|
|||
public MainGame() :
|
||||
base("Virtu")
|
||||
{
|
||||
#if WINDOWS_PHONE
|
||||
GraphicsDeviceManager.IsFullScreen = true;
|
||||
GraphicsDeviceManager.PreferredBackBufferWidth = 480; // TODO remove; works around known ctp issue
|
||||
GraphicsDeviceManager.PreferredBackBufferHeight = 800;
|
||||
#endif
|
||||
#if WINDOWS
|
||||
IsMouseVisible = true;
|
||||
|
||||
#endif
|
||||
var frameRateCounter = new FrameRateCounter(this); // no initializers; avoids CA2000
|
||||
Components.Add(frameRateCounter);
|
||||
frameRateCounter.DrawOrder = 1;
|
||||
|
|
29
Virtu/Xna/Properties/WMAppManifest.xml
Normal file
29
Virtu/Xna/Properties/WMAppManifest.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0">
|
||||
<App xmlns="" ProductID="{89a50370-1ed9-4cf1-ad08-043b6e6f3c90}" Title="Virtu" RuntimeType="XNA" Version="1.0.0.0" Genre="Apps.Games" Author="Sean Fausett & Nick Westgate" Description="Apple IIe Emulator" Publisher="Digital Jellyfish Design Ltd">
|
||||
<IconPath IsRelative="true" IsResource="false">AppThumbnail.png</IconPath>
|
||||
<Capabilities>
|
||||
<Capability Name="ID_CAP_NETWORKING" />
|
||||
<Capability Name="ID_CAP_LOCATION" />
|
||||
<Capability Name="ID_CAP_SENSORS" />
|
||||
<Capability Name="ID_CAP_MICROPHONE" />
|
||||
<Capability Name="ID_CAP_MEDIALIB" />
|
||||
<Capability Name="ID_CAP_GAMERSERVICES" />
|
||||
<Capability Name="ID_CAP_PHONEDIALER" />
|
||||
<Capability Name="ID_CAP_PUSH_NOTIFICATION" />
|
||||
<Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
|
||||
</Capabilities>
|
||||
<Tasks>
|
||||
<DefaultTask Name="_default" />
|
||||
</Tasks>
|
||||
<Tokens>
|
||||
<PrimaryToken TokenID="Jellyfish.Virtu.Xna.Phone.Token" TaskName="_default">
|
||||
<TemplateType5>
|
||||
<BackgroundImageURI IsRelative="true" IsResource="false">AppThumbnail.png</BackgroundImageURI>
|
||||
<Count>0</Count>
|
||||
<Title>Virtu</Title>
|
||||
</TemplateType5>
|
||||
</PrimaryToken>
|
||||
</Tokens>
|
||||
</App>
|
||||
</Deployment>
|
|
@ -27,9 +27,9 @@ public override void Load(string path, Action<Stream> reader)
|
|||
|
||||
try
|
||||
{
|
||||
using (var storageContainer = _storageDevice.Value.OpenContainer(_game.Name))
|
||||
using (var storageContainer = OpenContainer())
|
||||
{
|
||||
using (var stream = new FileStream(Path.Combine(storageContainer.Path, path), FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var stream = storageContainer.OpenFile(path))
|
||||
{
|
||||
reader(stream);
|
||||
}
|
||||
|
@ -47,15 +47,20 @@ public override void Save(string path, Action<Stream> writer)
|
|||
throw new ArgumentNullException("writer");
|
||||
}
|
||||
|
||||
using (var storageContainer = _storageDevice.Value.OpenContainer(_game.Name))
|
||||
using (var storageContainer = OpenContainer())
|
||||
{
|
||||
using (var stream = new FileStream(Path.Combine(storageContainer.Path, path), FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
using (var stream = storageContainer.OpenFile(path))
|
||||
{
|
||||
writer(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private StorageContainer OpenContainer()
|
||||
{
|
||||
return _storageDevice.Value.EndOpenContainer(_storageDevice.Value.BeginOpenContainer(_game.Name, null, null));
|
||||
}
|
||||
|
||||
private GameBase _game;
|
||||
private Lazy<StorageDevice> _storageDevice = new Lazy<StorageDevice>(() => StorageDevice.EndShowSelector(StorageDevice.BeginShowSelector(null, null)));
|
||||
}
|
||||
|
|
|
@ -29,9 +29,7 @@ public XnaVideoService(Machine machine, GameBase game) :
|
|||
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
|
||||
public override void SetPixel(int x, int y, uint color)
|
||||
{
|
||||
uint rgbaColor = ((color << 16) & 0xFF0000) | (color & 0x00FF00) | ((color >> 16) & 0x0000FF); // convert from BGRA to RGBA
|
||||
_pixels[y * TextureWidth + x] = rgbaColor;
|
||||
_pixels[(y + 1) * TextureWidth + x] = (_textureScale < 1) ? rgbaColor : 0x0;
|
||||
_pixels[y * TextureWidth + x] = (color & 0xFF00FF00) | ((color << 16) & 0x00FF0000) | ((color >> 16) & 0x000000FF); // RGBA
|
||||
_pixelsDirty = true;
|
||||
}
|
||||
|
||||
|
@ -74,36 +72,32 @@ private void OnGraphicsDeviceManagerPreparingDeviceSettings(object sender, Prepa
|
|||
bool portraitOrientation = (presentationParameters.DisplayOrientation & DisplayOrientation.Portrait) != 0;
|
||||
if (portraitOrientation)
|
||||
{
|
||||
_textureScale = Math.Min((float)displayMode.TitleSafeArea.Width / TextureWidth, (float)displayMode.TitleSafeArea.Height / TextureHeight);
|
||||
_textureScale = Math.Max(1, Math.Min(displayMode.TitleSafeArea.Width / TextureWidth, displayMode.TitleSafeArea.Height / TextureHeight));
|
||||
presentationParameters.BackBufferWidth = displayMode.Width; // always use portrait display mode
|
||||
presentationParameters.BackBufferHeight = displayMode.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
_textureScale = Math.Min((float)displayMode.TitleSafeArea.Height / TextureWidth, (float)displayMode.TitleSafeArea.Width / TextureHeight);
|
||||
_textureScale = Math.Max(1, Math.Min(displayMode.TitleSafeArea.Height / TextureWidth, displayMode.TitleSafeArea.Width / TextureHeight));
|
||||
presentationParameters.BackBufferWidth = displayMode.Height; // always use landscape display mode
|
||||
presentationParameters.BackBufferHeight = displayMode.Width;
|
||||
}
|
||||
if (_textureScale > 1)
|
||||
{
|
||||
_textureScale = (float)Math.Floor(_textureScale); // integer scale up
|
||||
}
|
||||
#elif XBOX
|
||||
_textureScale = Math.Min(displayMode.TitleSafeArea.Width / TextureWidth, displayMode.TitleSafeArea.Height / TextureHeight);
|
||||
_textureScale = Math.Max(1, Math.Min(displayMode.TitleSafeArea.Width / TextureWidth, displayMode.TitleSafeArea.Height / TextureHeight));
|
||||
presentationParameters.BackBufferWidth = displayMode.Width; // always use display mode
|
||||
presentationParameters.BackBufferHeight = displayMode.Height;
|
||||
#else
|
||||
if (presentationParameters.IsFullScreen)
|
||||
{
|
||||
_textureScale = Math.Min((int)SystemParameters.PrimaryScreenWidth / TextureWidth, (int)SystemParameters.PrimaryScreenHeight / TextureHeight);
|
||||
_textureScale = Math.Max(1, Math.Min((int)SystemParameters.PrimaryScreenWidth / TextureWidth, (int)SystemParameters.PrimaryScreenHeight / TextureHeight));
|
||||
presentationParameters.BackBufferWidth = displayMode.Width; // avoids changing display mode
|
||||
presentationParameters.BackBufferHeight = displayMode.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
_textureScale = Math.Min((int)SystemParameters.FullPrimaryScreenWidth / TextureWidth, (int)SystemParameters.FullPrimaryScreenHeight / TextureHeight);
|
||||
presentationParameters.BackBufferWidth = (int)_textureScale * TextureWidth;
|
||||
presentationParameters.BackBufferHeight = (int)_textureScale * TextureHeight;
|
||||
_textureScale = Math.Max(1, Math.Min((int)SystemParameters.FullPrimaryScreenWidth / TextureWidth, (int)SystemParameters.FullPrimaryScreenHeight / TextureHeight));
|
||||
presentationParameters.BackBufferWidth = _textureScale * TextureWidth;
|
||||
presentationParameters.BackBufferHeight = _textureScale * TextureHeight;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -131,7 +125,7 @@ private void SetTexturePosition()
|
|||
private SpriteBatch _spriteBatch;
|
||||
private Texture2D _texture;
|
||||
private Vector2 _texturePosition;
|
||||
private float _textureScale;
|
||||
private int _textureScale;
|
||||
private uint[] _pixels;
|
||||
private bool _pixelsDirty;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user