diff --git a/Library/CustomDictionary.xml b/Library/CustomDictionary.xml index 2a83b12..ae15117 100644 --- a/Library/CustomDictionary.xml +++ b/Library/CustomDictionary.xml @@ -3,6 +3,8 @@ Alloc + x + y diff --git a/Library/Silverlight/Phone/Properties/AssemblyInfo.cs b/Library/Silverlight/Phone/Properties/AssemblyInfo.cs index 02e6eca..7744fa5 100644 --- a/Library/Silverlight/Phone/Properties/AssemblyInfo.cs +++ b/Library/Silverlight/Phone/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ [assembly: AssemblyDescription("Common Library")] [assembly: AssemblyProduct("Jellyfish.Library.Silverlight.Phone")] [assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 2009-2012 Digital Jellyfish Design Ltd")] [assembly: AssemblyComment("Developed by Sean Fausett")] [assembly: AssemblyVersion("0.2.0.0")] diff --git a/Library/Silverlight/Properties/AssemblyInfo.cs b/Library/Silverlight/Properties/AssemblyInfo.cs index 972e989..66a7844 100644 --- a/Library/Silverlight/Properties/AssemblyInfo.cs +++ b/Library/Silverlight/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ [assembly: AssemblyDescription("Common Library")] [assembly: AssemblyProduct("Jellyfish.Library.Silverlight")] [assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 2009-2012 Digital Jellyfish Design Ltd")] [assembly: AssemblyComment("Developed by Sean Fausett")] [assembly: AssemblyVersion("0.2.0.0")] diff --git a/Library/StreamExtensions.cs b/Library/StreamExtensions.cs index 15f2244..4e4c005 100644 --- a/Library/StreamExtensions.cs +++ b/Library/StreamExtensions.cs @@ -5,21 +5,22 @@ namespace Jellyfish.Library { public static class StreamExtensions { - public static byte[] ReadAllBytes(this Stream stream) + public static byte[] ReadBlock(this Stream stream, int count) { - if (stream == null) - { - throw new ArgumentNullException("stream"); - } - - int count = (int)stream.Length; - byte[] buffer = new byte[count]; - ReadBlock(stream, buffer, 0, count); - - return buffer; + return ReadBlock(stream, new byte[count], 0, count); } - public static int ReadBlock(this Stream stream, byte[] buffer, int offset, int count) + public static byte[] ReadBlock(this Stream stream, byte[] buffer) + { + if (buffer == null) + { + throw new ArgumentNullException("buffer"); + } + + return ReadBlock(stream, buffer, 0, buffer.Length); + } + + public static byte[] ReadBlock(this Stream stream, byte[] buffer, int offset, int count) { if (stream == null) { @@ -34,7 +35,38 @@ public static int ReadBlock(this Stream stream, byte[] buffer, int offset, int c } while ((read > 0) && (total < count)); - return total; + if (total < count) + { + throw new EndOfStreamException(); + } + + return buffer; + } + + public static void SkipBlock(this Stream stream, int count) + { + if (stream == null) + { + throw new ArgumentNullException("stream"); + } + + if (stream.CanSeek) + { + stream.Seek(count, SeekOrigin.Current); + } + else + { + const int BufferSize = 1024; + byte[] buffer = new byte[BufferSize]; + + int total = 0; + int read; + do + { + total += read = stream.Read(buffer, 0, Math.Min(count - total, BufferSize)); + } + while ((read > 0) && (total < count)); + } } } } diff --git a/Library/Wpf/Properties/AssemblyInfo.cs b/Library/Wpf/Properties/AssemblyInfo.cs index 0b8d668..4aa93d6 100644 --- a/Library/Wpf/Properties/AssemblyInfo.cs +++ b/Library/Wpf/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ [assembly: AssemblyDescription("Common Library")] [assembly: AssemblyProduct("Jellyfish.Library.Wpf")] [assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 2009-2012 Digital Jellyfish Design Ltd")] [assembly: AssemblyComment("Developed by Sean Fausett")] [assembly: AssemblyVersion("0.2.0.0")] diff --git a/Library/Xna/FrameRateCounter.cs b/Library/Xna/FrameRateCounter.cs index 43dbf9d..12e567b 100644 --- a/Library/Xna/FrameRateCounter.cs +++ b/Library/Xna/FrameRateCounter.cs @@ -20,7 +20,7 @@ protected override void LoadContent() _spriteBatch = new SpriteBatch(GraphicsDevice); _spriteFont = Game.Content.Load(FontName); - var titleSafeArea = Game.GraphicsDevice.DisplayMode.TitleSafeArea; + var titleSafeArea = Game.GraphicsDevice.Viewport.TitleSafeArea; Position = new Vector2(titleSafeArea.X, titleSafeArea.Y); } diff --git a/Library/Xna/GameBase.cs b/Library/Xna/GameBase.cs index 227d325..9cc9478 100644 --- a/Library/Xna/GameBase.cs +++ b/Library/Xna/GameBase.cs @@ -1,7 +1,9 @@ using System; using System.Threading; using Microsoft.Xna.Framework; +#if XBOX using Microsoft.Xna.Framework.GamerServices; +#endif using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; @@ -9,11 +11,6 @@ namespace Jellyfish.Library { public class GameBase : Game { - public GameBase() : - this(null) - { - } - public GameBase(string name) { Name = name; @@ -22,10 +19,12 @@ public GameBase(string name) GraphicsDeviceManager = new GraphicsDeviceManager(this); #if WINDOWS_PHONE GraphicsDeviceManager.IsFullScreen = true; + GraphicsDeviceManager.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight; TargetElapsedTime = TimeSpan.FromTicks(333333); // 30 fps #elif XBOX + GraphicsDeviceManager.IsFullScreen = true; Components.Add(new GamerServicesComponent(this)); -#else +#elif WINDOWS SynchronizationContext = new System.Windows.Forms.WindowsFormsSynchronizationContext(); #endif GraphicsDeviceService = (IGraphicsDeviceService)Services.GetService(typeof(IGraphicsDeviceService)); diff --git a/Library/Xna/Properties/AssemblyInfo.cs b/Library/Xna/Properties/AssemblyInfo.cs index 13881d3..64193ca 100644 --- a/Library/Xna/Properties/AssemblyInfo.cs +++ b/Library/Xna/Properties/AssemblyInfo.cs @@ -14,7 +14,7 @@ [assembly: AssemblyProduct("Jellyfish.Library.Xna")] #endif [assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 2009-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 2009-2012 Digital Jellyfish Design Ltd")] [assembly: AssemblyComment("Developed by Sean Fausett")] [assembly: AssemblyVersion("0.2.0.0")] diff --git a/Library/Xna/TouchJoystick.cs b/Library/Xna/TouchJoystick.cs index 044e44f..058572b 100644 --- a/Library/Xna/TouchJoystick.cs +++ b/Library/Xna/TouchJoystick.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input.Touch; @@ -6,6 +7,7 @@ namespace Jellyfish.Library { public sealed class TouchJoystick : TouchRegion { + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] public Vector2 GetJoystick() { TouchLocation touch; diff --git a/Library/Xna/TouchRegionCollection.cs b/Library/Xna/TouchRegionCollection.cs index 8d9c281..21c3f58 100644 --- a/Library/Xna/TouchRegionCollection.cs +++ b/Library/Xna/TouchRegionCollection.cs @@ -1,4 +1,5 @@ using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; using Microsoft.Xna.Framework.Input.Touch; namespace Jellyfish.Library @@ -9,6 +10,7 @@ public TouchRegionCollection() { } + [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")] public void Update(ref TouchCollection touches) { for (int i = 0; i < base.Count; i++) diff --git a/License.txt b/License.txt index e60bc67..074a544 100644 --- a/License.txt +++ b/License.txt @@ -1,12 +1,12 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -56,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - GNU GENERAL PUBLIC LICENSE + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN @@ -277,63 +277,4 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. + END OF TERMS AND CONDITIONS diff --git a/Virtu/Disk525.cs b/Virtu/Disk525.cs index 4bcdb26..6ef1f7a 100644 --- a/Virtu/Disk525.cs +++ b/Virtu/Disk525.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.IO; +using Jellyfish.Library; namespace Jellyfish.Virtu { @@ -13,25 +14,27 @@ protected Disk525(string name, byte[] data, bool isWriteProtected) IsWriteProtected = isWriteProtected; } - public static Disk525 CreateDisk(string name, byte[] data, bool isWriteProtected) + public static Disk525 CreateDisk(string name, Stream stream, bool isWriteProtected) { if (name == null) { throw new ArgumentNullException("name"); } - if (data == null) + if (stream == null) { - throw new ArgumentNullException("data"); + throw new ArgumentNullException("stream"); } - if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase) && (data.Length == TrackCount * TrackSize)) - { - return new DiskNib(name, data, isWriteProtected); - } - else if (name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase) && (data.Length == TrackCount * SectorCount * SectorSize)) + if (name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) { + byte[] data = stream.ReadBlock(TrackCount * SectorCount * SectorSize); return new DiskDsk(name, data, isWriteProtected); } + else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase)) + { + byte[] data = stream.ReadBlock(TrackCount * TrackSize); + return new DiskNib(name, data, isWriteProtected); + } return null; } @@ -48,7 +51,16 @@ public static Disk525 LoadState(BinaryReader reader, Version version) bool isWriteProtected = reader.ReadBoolean(); byte[] data = reader.ReadBytes(reader.ReadInt32()); - return CreateDisk(name, data, isWriteProtected); + if (name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) + { + return new DiskDsk(name, data, isWriteProtected); + } + else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase)) + { + return new DiskNib(name, data, isWriteProtected); + } + + return null; } public void SaveState(BinaryWriter writer) diff --git a/Virtu/DiskIIController.cs b/Virtu/DiskIIController.cs index dced1fa..5b5e7f9 100644 --- a/Virtu/DiskIIController.cs +++ b/Virtu/DiskIIController.cs @@ -15,8 +15,8 @@ public DiskIIController(Machine machine) : public override void Initialize() { - StorageService.LoadResource("Roms/DiskII.rom", 0x0100, stream => stream.ReadBlock(_romRegionC1C7, 0, 0x0100)); - StorageService.LoadResource("Disks/Default.dsk", 0x23000, stream => _drives[0].InsertDisk("Default.dsk", stream, false)); + StorageService.LoadResource("Roms/DiskII.rom", stream => stream.ReadBlock(_romRegionC1C7)); + StorageService.LoadResource("Disks/Default.dsk", stream => _drives[0].InsertDisk("Default.dsk", stream, false)); } public override void Reset() diff --git a/Virtu/DiskIIDrive.cs b/Virtu/DiskIIDrive.cs index a9ae9db..298e5fe 100644 --- a/Virtu/DiskIIDrive.cs +++ b/Virtu/DiskIIDrive.cs @@ -66,7 +66,7 @@ public void InsertDisk(string name, Stream stream, bool isWriteProtected) // TODO handle null param/empty string for eject, or add Eject() - _disk = Disk525.CreateDisk(name, stream.ReadAllBytes(), isWriteProtected); + _disk = Disk525.CreateDisk(name, stream, isWriteProtected); _trackLoaded = false; } diff --git a/Virtu/Machine.cs b/Virtu/Machine.cs index 2e371f5..9f67ecd 100644 --- a/Virtu/Machine.cs +++ b/Virtu/Machine.cs @@ -50,7 +50,12 @@ public void Dispose() public void Reset() { - Components.ForEach(component => component.Reset()); + foreach (var component in Components) + { + //_debugService.WriteLine("Resetting component '{0}'", component.GetType().Name); + component.Reset(); + //_debugService.WriteLine("Reset component '{0}'", component.GetType().Name); + } } public void Start() @@ -99,14 +104,18 @@ public DiskIIController FindDiskIIController() private void Initialize() { - Components.ForEach(component => component.Initialize()); + foreach (var component in Components) + { + //_debugService.WriteLine("Initializing component '{0}'", component.GetType().Name); + component.Initialize(); + //_debugService.WriteLine("Initialized component '{0}'", component.GetType().Name); + } } [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] private void LoadState() { - var storageService = Services.GetService(); - storageService.Load(Machine.LastStateFileName, stream => + _storageService.Load(Machine.LastStateFileName, stream => { try { @@ -116,7 +125,12 @@ private void LoadState() var stateVersion = new Version(reader.ReadString()); if ((stateSignature == StateSignature) && (stateVersion == new Version(Machine.Version))) // avoid state version mismatch (for now) { - Components.ForEach(component => component.LoadState(reader, stateVersion)); + foreach (var component in Components) + { + //_debugService.WriteLine("Loading component '{0}' state", component.GetType().Name); + component.LoadState(reader, stateVersion); + //_debugService.WriteLine("Loaded component '{0}' state", component.GetType().Name); + } } } } @@ -132,25 +146,37 @@ private void LoadState() private void Uninitialize() { - Components.ForEach(component => component.Uninitialize()); + foreach (var component in Components) + { + //_debugService.WriteLine("Uninitializing component '{0}'", component.GetType().Name); + component.Uninitialize(); + //_debugService.WriteLine("Uninitialized component '{0}'", component.GetType().Name); + } } private void SaveState() { - var storageService = Services.GetService(); - storageService.Save(Machine.LastStateFileName, stream => + _storageService.Save(Machine.LastStateFileName, stream => { using (var writer = new BinaryWriter(stream)) { writer.Write(StateSignature); writer.Write(Machine.Version); - Components.ForEach(component => component.SaveState(writer)); + foreach (var component in Components) + { + //_debugService.WriteLine("Saving component '{0}' state", component.GetType().Name); + component.SaveState(writer); + //_debugService.WriteLine("Saved component '{0}' state", component.GetType().Name); + } } }); } private void Run() // machine thread { + _debugService = Services.GetService(); + _storageService = Services.GetService(); + Initialize(); Reset(); LoadState(); @@ -207,6 +233,9 @@ private void Run() // machine thread private const string LastStateFileName = "LastState.bin"; private const string StateSignature = "Virtu"; + private DebugService _debugService; + private StorageService _storageService; + private AutoResetEvent _pauseEvent = new AutoResetEvent(false); private AutoResetEvent _unpauseEvent = new AutoResetEvent(false); } diff --git a/Virtu/Memory.cs b/Virtu/Memory.cs index 19d37e6..86e39ca 100644 --- a/Virtu/Memory.cs +++ b/Virtu/Memory.cs @@ -94,12 +94,12 @@ public override void Initialize() _video = Machine.Video; _noSlotClock = Machine.NoSlotClock; - StorageService.LoadResource("Roms/AppleIIe.rom", 0x4000, stream => + StorageService.LoadResource("Roms/AppleIIe.rom", stream => { - stream.Seek(0x0100, SeekOrigin.Current); - stream.ReadBlock(_romInternalRegionC1CF, 0, _romInternalRegionC1CF.Length); - stream.ReadBlock(_romRegionD0DF, 0, _romRegionD0DF.Length); - stream.ReadBlock(_romRegionE0FF, 0, _romRegionE0FF.Length); + stream.SkipBlock(0x0100); + stream.ReadBlock(_romInternalRegionC1CF); + stream.ReadBlock(_romRegionD0DF); + stream.ReadBlock(_romRegionE0FF); }); if ((ReadRomRegionE0FF(0xFBB3) == 0x06) && (ReadRomRegionE0FF(0xFBBF) == 0xC1)) diff --git a/Virtu/Properties/Strings.Designer.cs b/Virtu/Properties/Strings.Designer.cs index d162531..16a2c1e 100644 --- a/Virtu/Properties/Strings.Designer.cs +++ b/Virtu/Properties/Strings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.1 +// Runtime Version:4.0.30319.431 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -60,15 +60,6 @@ internal Strings() { } } - /// - /// Looks up a localized string similar to Resource '{0}' invalid.. - /// - internal static string ResourceInvalid { - get { - return ResourceManager.GetString("ResourceInvalid", resourceCulture); - } - } - /// /// Looks up a localized string similar to Resource '{0}' not found.. /// diff --git a/Virtu/Properties/Strings.resx b/Virtu/Properties/Strings.resx index 3ca952f..e703e94 100644 --- a/Virtu/Properties/Strings.resx +++ b/Virtu/Properties/Strings.resx @@ -112,17 +112,14 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Resource '{0}' not found. - - Resource '{0}' invalid. - Service type '{0}' already present. diff --git a/Virtu/Services/DebugService.cs b/Virtu/Services/DebugService.cs index ca5a3d8..b1d09d6 100644 --- a/Virtu/Services/DebugService.cs +++ b/Virtu/Services/DebugService.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Globalization; namespace Jellyfish.Virtu.Services { @@ -15,6 +16,11 @@ public void WriteLine(string message) OnWriteLine(string.Concat(DateTime.Now.TimeOfDay, ' ', message)); } + public void WriteLine(string format, params object[] args) + { + WriteLine(string.Format(CultureInfo.InvariantCulture, format, args)); + } + protected virtual void OnWriteLine(string message) { Debug.WriteLine(message); diff --git a/Virtu/Services/IsolatedStorageService.cs b/Virtu/Services/IsolatedStorageService.cs index f806261..2e41a1b 100644 --- a/Virtu/Services/IsolatedStorageService.cs +++ b/Virtu/Services/IsolatedStorageService.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.IO.IsolatedStorage; +using Jellyfish.Library; namespace Jellyfish.Virtu.Services { diff --git a/Virtu/Services/MachineService.cs b/Virtu/Services/MachineService.cs index 0168224..1cb4420 100644 --- a/Virtu/Services/MachineService.cs +++ b/Virtu/Services/MachineService.cs @@ -1,4 +1,5 @@ using System; +using Jellyfish.Library; namespace Jellyfish.Virtu.Services { @@ -7,6 +8,8 @@ public abstract class MachineService : IDisposable protected MachineService(Machine machine) { Machine = machine; + + _debugService = new Lazy(() => Machine.Services.GetService()); } ~MachineService() @@ -25,6 +28,8 @@ protected virtual void Dispose(bool disposing) } protected Machine Machine { get; private set; } - protected DebugService DebugService { get { return Machine.Services.GetService(); } } + protected DebugService DebugService { get { return _debugService.Value; } } + + private Lazy _debugService; } } diff --git a/Virtu/Services/StorageService.cs b/Virtu/Services/StorageService.cs index 95e4976..3945547 100644 --- a/Virtu/Services/StorageService.cs +++ b/Virtu/Services/StorageService.cs @@ -65,7 +65,7 @@ public static void LoadFile(FileInfo fileInfo, Action reader) } } - public static void LoadResource(string resourceName, int resourceSize, Action reader) + public static void LoadResource(string resourceName, Action reader) { if (reader == null) { @@ -74,7 +74,7 @@ public static void LoadResource(string resourceName, int resourceSize, Action writer) } } - private static Stream GetResourceStream(string resourceName, int resourceSize) + private static Stream GetResourceStream(string resourceName) { - var resourceStream = _resourceManager.Value.GetStream(resourceName, CultureInfo.CurrentUICulture); + resourceName = "Jellyfish.Virtu." + resourceName.Replace('/', '.'); + var resourceStream = typeof(StorageService).Assembly.GetManifestResourceStream(resourceName); if (resourceStream == null) { throw new FileNotFoundException(string.Format(CultureInfo.CurrentUICulture, Strings.ResourceNotFound, resourceName)); } - if ((resourceSize > 0) && (resourceStream.Length != resourceSize)) - { - throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, Strings.ResourceInvalid, resourceName)); - } return resourceStream; } - - private static Lazy _resourceManager = new Lazy(() => new ResourceManager("Jellyfish.Virtu.g", typeof(StorageService).Assembly) { IgnoreCase = true }); } } diff --git a/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.csproj b/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.csproj index 65d8f45..6a765a3 100644 --- a/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.csproj +++ b/Virtu/Silverlight/Jellyfish.Virtu.Silverlight.csproj @@ -230,15 +230,15 @@ - + Disks\Default.dsk - - + + Roms\AppleIIe.rom - - + + Roms\DiskII.rom - + diff --git a/Virtu/Silverlight/Phone/Jellyfish.Virtu.Silverlight.Phone.csproj b/Virtu/Silverlight/Phone/Jellyfish.Virtu.Silverlight.Phone.csproj index bfbc8ba..9ea1b59 100644 --- a/Virtu/Silverlight/Phone/Jellyfish.Virtu.Silverlight.Phone.csproj +++ b/Virtu/Silverlight/Phone/Jellyfish.Virtu.Silverlight.Phone.csproj @@ -228,15 +228,15 @@ - + Disks\Default.dsk - - + + Roms\AppleIIe.rom - - + + Roms\DiskII.rom - + diff --git a/Virtu/Silverlight/Phone/Properties/AssemblyInfo.cs b/Virtu/Silverlight/Phone/Properties/AssemblyInfo.cs index 1463887..f14c12d 100644 --- a/Virtu/Silverlight/Phone/Properties/AssemblyInfo.cs +++ b/Virtu/Silverlight/Phone/Properties/AssemblyInfo.cs @@ -9,7 +9,7 @@ [assembly: AssemblyDescription("Apple IIe Emulator")] [assembly: AssemblyProduct("Jellyfish.Virtu.Silverlight.Phone")] [assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 1995-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")] [assembly: AssemblyComment("Developed by Sean Fausett & Nick Westgate")] [assembly: AssemblyVersion(Machine.Version)] diff --git a/Virtu/Silverlight/Properties/AssemblyInfo.cs b/Virtu/Silverlight/Properties/AssemblyInfo.cs index a0bd1f1..471d9ed 100644 --- a/Virtu/Silverlight/Properties/AssemblyInfo.cs +++ b/Virtu/Silverlight/Properties/AssemblyInfo.cs @@ -9,7 +9,7 @@ [assembly: AssemblyDescription("Apple IIe Emulator")] [assembly: AssemblyProduct("Jellyfish.Virtu.Silverlight")] [assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 1995-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")] [assembly: AssemblyComment("Developed by Sean Fausett & Nick Westgate")] [assembly: AssemblyVersion(Machine.Version)] diff --git a/Virtu/Wpf/Jellyfish.Virtu.Wpf.csproj b/Virtu/Wpf/Jellyfish.Virtu.Wpf.csproj index ad9681f..4870f51 100644 --- a/Virtu/Wpf/Jellyfish.Virtu.Wpf.csproj +++ b/Virtu/Wpf/Jellyfish.Virtu.Wpf.csproj @@ -219,15 +219,15 @@ - + Disks\Default.dsk - - + + Roms\AppleIIe.rom - - + + Roms\DiskII.rom - + diff --git a/Virtu/Wpf/Properties/AssemblyInfo.cs b/Virtu/Wpf/Properties/AssemblyInfo.cs index d3d6287..63393b3 100644 --- a/Virtu/Wpf/Properties/AssemblyInfo.cs +++ b/Virtu/Wpf/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ [assembly: AssemblyDescription("Apple IIe Emulator")] [assembly: AssemblyProduct("Jellyfish.Virtu.Wpf")] [assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 1995-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")] [assembly: AssemblyComment("Developed by Sean Fausett & Nick Westgate")] [assembly: AssemblyVersion(Machine.Version)] diff --git a/Virtu/Xna/Jellyfish.Virtu.Xna.Phone.csproj b/Virtu/Xna/Jellyfish.Virtu.Xna.Phone.csproj index 32bec19..9c9421c 100644 --- a/Virtu/Xna/Jellyfish.Virtu.Xna.Phone.csproj +++ b/Virtu/Xna/Jellyfish.Virtu.Xna.Phone.csproj @@ -232,15 +232,15 @@ - + Disks\Default.dsk - - + + Roms\AppleIIe.rom - - + + Roms\DiskII.rom - + diff --git a/Virtu/Xna/Jellyfish.Virtu.Xna.Xbox.csproj b/Virtu/Xna/Jellyfish.Virtu.Xna.Xbox.csproj index c0e2971..b822db7 100644 --- a/Virtu/Xna/Jellyfish.Virtu.Xna.Xbox.csproj +++ b/Virtu/Xna/Jellyfish.Virtu.Xna.Xbox.csproj @@ -230,15 +230,15 @@ - + Disks\Default.dsk - - + + Roms\AppleIIe.rom - - + + Roms\DiskII.rom - + diff --git a/Virtu/Xna/Jellyfish.Virtu.Xna.csproj b/Virtu/Xna/Jellyfish.Virtu.Xna.csproj index 1fdfad0..6cb0660 100644 --- a/Virtu/Xna/Jellyfish.Virtu.Xna.csproj +++ b/Virtu/Xna/Jellyfish.Virtu.Xna.csproj @@ -234,15 +234,15 @@ - + Disks\Default.dsk - - + + Roms\AppleIIe.rom - - + + Roms\DiskII.rom - + diff --git a/Virtu/Xna/Properties/AssemblyInfo.cs b/Virtu/Xna/Properties/AssemblyInfo.cs index 0179ef6..756e741 100644 --- a/Virtu/Xna/Properties/AssemblyInfo.cs +++ b/Virtu/Xna/Properties/AssemblyInfo.cs @@ -15,7 +15,7 @@ [assembly: AssemblyProduct("Jellyfish.Virtu.Xna")] #endif [assembly: AssemblyCompany("Digital Jellyfish Design Ltd")] -[assembly: AssemblyCopyright("Copyright © 1995-2010 Digital Jellyfish Design Ltd")] +[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")] [assembly: AssemblyComment("Developed by Sean Fausett & Nick Westgate")] [assembly: AssemblyVersion(Machine.Version)] diff --git a/Virtu/Xna/Services/XnaKeyboardService.cs b/Virtu/Xna/Services/XnaKeyboardService.cs index 2a2d43a..d7f45fb 100644 --- a/Virtu/Xna/Services/XnaKeyboardService.cs +++ b/Virtu/Xna/Services/XnaKeyboardService.cs @@ -86,7 +86,7 @@ private bool IsKeyDown(Keys key) private void OnKeyDown(Keys key, bool gamePadControl) { - //DebugService.WriteLine(string.Concat("OnKeyDn: Key=", key)); + //DebugService.WriteLine("OnKeyDn: Key='{0}'", key); int asciiKey = GetAsciiKey(key, gamePadControl); if (asciiKey >= 0) @@ -97,7 +97,7 @@ private void OnKeyDown(Keys key, bool gamePadControl) private void OnKeyUp(Keys key, bool gamePadControl) { - //DebugService.WriteLine(string.Concat("OnKeyUp: Key=", key)); + //DebugService.WriteLine("OnKeyUp: Key='{0}'", key); bool control = IsKeyDown(Keys.LeftControl) || IsKeyDown(Keys.RightControl); diff --git a/Virtu/Xna/Services/XnaVideoService.cs b/Virtu/Xna/Services/XnaVideoService.cs index 6c4e6e4..bd14361 100644 --- a/Virtu/Xna/Services/XnaVideoService.cs +++ b/Virtu/Xna/Services/XnaVideoService.cs @@ -20,10 +20,10 @@ public XnaVideoService(Machine machine, GameBase game) : } _game = game; - +#if WINDOWS || XBOX _game.GraphicsDeviceManager.PreparingDeviceSettings += OnGraphicsDeviceManagerPreparingDeviceSettings; +#endif _game.GraphicsDeviceService.DeviceCreated += OnGraphicsDeviceServiceDeviceCreated; - _game.GraphicsDeviceService.DeviceReset += (sender, e) => SetTexturePosition(); } public override void SetFullScreen(bool isFullScreen) @@ -53,8 +53,12 @@ public override void Update() // main thread _texture.SetData(_pixels); } + var viewport = _graphicsDevice.Viewport; + int scale = Math.Max(1, Math.Min(viewport.Width / TextureWidth, viewport.Height / TextureHeight)); + var position = new Vector2((viewport.Width - scale * TextureWidth) / 2, (viewport.Height - scale * TextureHeight) / 2); + _spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.PointClamp, null, null); - _spriteBatch.Draw(_texture, _texturePosition, null, Color.White, 0, Vector2.Zero, _textureScale, SpriteEffects.None, 0); + _spriteBatch.Draw(_texture, position, null, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, 0); _spriteBatch.End(); } @@ -69,58 +73,32 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } +#if WINDOWS || XBOX private void OnGraphicsDeviceManagerPreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e) { - var displayMode = e.GraphicsDeviceInformation.Adapter.CurrentDisplayMode; var presentationParameters = e.GraphicsDeviceInformation.PresentationParameters; - -#if WINDOWS_PHONE - bool portraitOrientation = (presentationParameters.DisplayOrientation & DisplayOrientation.Portrait) != 0; - if (portraitOrientation) +#if WINDOWS + if (!presentationParameters.IsFullScreen) { - _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; + var maxScale = Math.Max(1, Math.Min((int)SystemParameters.FullPrimaryScreenWidth / TextureWidth, (int)SystemParameters.FullPrimaryScreenHeight / TextureHeight)); + presentationParameters.BackBufferWidth = maxScale * TextureWidth; + presentationParameters.BackBufferHeight = maxScale * TextureHeight; } else - { - _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; - } -#elif XBOX - _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.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.Max(1, Math.Min((int)SystemParameters.FullPrimaryScreenWidth / TextureWidth, (int)SystemParameters.FullPrimaryScreenHeight / TextureHeight)); - presentationParameters.BackBufferWidth = _textureScale * TextureWidth; - presentationParameters.BackBufferHeight = _textureScale * TextureHeight; - } #endif + { + var displayMode = e.GraphicsDeviceInformation.Adapter.CurrentDisplayMode; // use display mode + presentationParameters.BackBufferWidth = displayMode.Width; + presentationParameters.BackBufferHeight = displayMode.Height; + } } +#endif private void OnGraphicsDeviceServiceDeviceCreated(object sender, EventArgs e) { _graphicsDevice = _game.GraphicsDevice; _spriteBatch = new SpriteBatch(_graphicsDevice); _texture = new Texture2D(_graphicsDevice, TextureWidth, TextureHeight, false, SurfaceFormat.Color); - _pixels = new uint[TextureWidth * TextureHeight]; - SetTexturePosition(); - } - - private void SetTexturePosition() - { - _texturePosition.X = (_graphicsDevice.PresentationParameters.BackBufferWidth - TextureWidth * _textureScale) / 2; // centered - _texturePosition.Y = (_graphicsDevice.PresentationParameters.BackBufferHeight - TextureHeight * _textureScale) / 2; } private const int TextureWidth = 560; @@ -130,9 +108,8 @@ private void SetTexturePosition() private GraphicsDevice _graphicsDevice; private SpriteBatch _spriteBatch; private Texture2D _texture; - private Vector2 _texturePosition; - private int _textureScale; - private uint[] _pixels; + + private uint[] _pixels = new uint[TextureWidth * TextureHeight]; private bool _pixelsDirty; } }