Refactored XnaVideoService.

Redefined binary resources as EmbeddedResource type.
Miscellaneous cosmetic or otherwise minor changes.
This commit is contained in:
Sean Fausett 2012-04-14 16:46:32 +12:00
parent b0d09b7fb7
commit f16c1b0b90
34 changed files with 218 additions and 227 deletions

View File

@ -3,6 +3,8 @@
<Words>
<Recognized>
<Word>Alloc</Word>
<Word>x</Word>
<Word>y</Word>
</Recognized>
</Words>
</Dictionary>

View File

@ -8,7 +8,7 @@ using Jellyfish.Library;
[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")]

View File

@ -8,7 +8,7 @@ using Jellyfish.Library;
[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")]

View File

@ -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 @@ namespace Jellyfish.Library
}
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));
}
}
}
}

View File

@ -8,7 +8,7 @@ using Jellyfish.Library;
[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")]

View File

@ -20,7 +20,7 @@ namespace Jellyfish.Library
_spriteBatch = new SpriteBatch(GraphicsDevice);
_spriteFont = Game.Content.Load<SpriteFont>(FontName);
var titleSafeArea = Game.GraphicsDevice.DisplayMode.TitleSafeArea;
var titleSafeArea = Game.GraphicsDevice.Viewport.TitleSafeArea;
Position = new Vector2(titleSafeArea.X, titleSafeArea.Y);
}

View File

@ -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 @@ namespace Jellyfish.Library
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));

View File

@ -14,7 +14,7 @@ using Jellyfish.Library;
[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")]

View File

@ -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;

View File

@ -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 @@ namespace Jellyfish.Library
{
}
[SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
public void Update(ref TouchCollection touches)
{
for (int i = 0; i < base.Count; i++)

View File

@ -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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
<signature of Ty Coon>, 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

View File

@ -1,6 +1,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Jellyfish.Library;
namespace Jellyfish.Virtu
{
@ -13,25 +14,27 @@ namespace Jellyfish.Virtu
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 @@ namespace Jellyfish.Virtu
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)

View File

@ -15,8 +15,8 @@ namespace Jellyfish.Virtu
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()

View File

@ -66,7 +66,7 @@ namespace Jellyfish.Virtu
// 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;
}

View File

@ -50,7 +50,12 @@ namespace Jellyfish.Virtu
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 @@ namespace Jellyfish.Virtu
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>();
storageService.Load(Machine.LastStateFileName, stream =>
_storageService.Load(Machine.LastStateFileName, stream =>
{
try
{
@ -116,7 +125,12 @@ namespace Jellyfish.Virtu
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 @@ namespace Jellyfish.Virtu
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>();
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<DebugService>();
_storageService = Services.GetService<StorageService>();
Initialize();
Reset();
LoadState();
@ -207,6 +233,9 @@ namespace Jellyfish.Virtu
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);
}

View File

@ -94,12 +94,12 @@ namespace Jellyfish.Virtu
_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))

View File

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 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 @@ namespace Jellyfish.Virtu.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Resource &apos;{0}&apos; invalid..
/// </summary>
internal static string ResourceInvalid {
get {
return ResourceManager.GetString("ResourceInvalid", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Resource &apos;{0}&apos; not found..
/// </summary>

View File

@ -112,17 +112,14 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ResourceNotFound" xml:space="preserve">
<value>Resource '{0}' not found.</value>
</data>
<data name="ResourceInvalid" xml:space="preserve">
<value>Resource '{0}' invalid.</value>
</data>
<data name="ServiceAlreadyPresent" xml:space="preserve">
<value>Service type '{0}' already present.</value>
</data>

View File

@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.Globalization;
namespace Jellyfish.Virtu.Services
{
@ -15,6 +16,11 @@ namespace Jellyfish.Virtu.Services
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);

View File

@ -2,6 +2,7 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.IsolatedStorage;
using Jellyfish.Library;
namespace Jellyfish.Virtu.Services
{

View File

@ -1,4 +1,5 @@
using System;
using Jellyfish.Library;
namespace Jellyfish.Virtu.Services
{
@ -7,6 +8,8 @@ namespace Jellyfish.Virtu.Services
protected MachineService(Machine machine)
{
Machine = machine;
_debugService = new Lazy<DebugService>(() => Machine.Services.GetService<DebugService>());
}
~MachineService()
@ -25,6 +28,8 @@ namespace Jellyfish.Virtu.Services
}
protected Machine Machine { get; private set; }
protected DebugService DebugService { get { return Machine.Services.GetService<DebugService>(); } }
protected DebugService DebugService { get { return _debugService.Value; } }
private Lazy<DebugService> _debugService;
}
}

View File

@ -65,7 +65,7 @@ namespace Jellyfish.Virtu.Services
}
}
public static void LoadResource(string resourceName, int resourceSize, Action<Stream> reader)
public static void LoadResource(string resourceName, Action<Stream> reader)
{
if (reader == null)
{
@ -74,7 +74,7 @@ namespace Jellyfish.Virtu.Services
try
{
using (var stream = GetResourceStream(resourceName, resourceSize))
using (var stream = GetResourceStream(resourceName))
{
reader(stream);
}
@ -122,21 +122,16 @@ namespace Jellyfish.Virtu.Services
}
}
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> _resourceManager = new Lazy<ResourceManager>(() => new ResourceManager("Jellyfish.Virtu.g", typeof(StorageService).Assembly) { IgnoreCase = true });
}
}

View File

@ -230,15 +230,15 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Resource Include="..\Disks\Default.dsk">
<EmbeddedResource Include="..\Disks\Default.dsk">
<Link>Disks\Default.dsk</Link>
</Resource>
<Resource Include="..\Roms\AppleIIe.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\AppleIIe.rom">
<Link>Roms\AppleIIe.rom</Link>
</Resource>
<Resource Include="..\Roms\DiskII.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\DiskII.rom">
<Link>Roms\DiskII.rom</Link>
</Resource>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">

View File

@ -228,15 +228,15 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Resource Include="..\..\Disks\Default.dsk">
<EmbeddedResource Include="..\..\Disks\Default.dsk">
<Link>Disks\Default.dsk</Link>
</Resource>
<Resource Include="..\..\Roms\AppleIIe.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\..\Roms\AppleIIe.rom">
<Link>Roms\AppleIIe.rom</Link>
</Resource>
<Resource Include="..\..\Roms\DiskII.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\..\Roms\DiskII.rom">
<Link>Roms\DiskII.rom</Link>
</Resource>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="..\..\CustomDictionary.xml">

View File

@ -9,7 +9,7 @@ using Jellyfish.Virtu;
[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)]

View File

@ -9,7 +9,7 @@ using Jellyfish.Virtu;
[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)]

View File

@ -219,15 +219,15 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Resource Include="..\Disks\Default.dsk">
<EmbeddedResource Include="..\Disks\Default.dsk">
<Link>Disks\Default.dsk</Link>
</Resource>
<Resource Include="..\Roms\AppleIIe.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\AppleIIe.rom">
<Link>Roms\AppleIIe.rom</Link>
</Resource>
<Resource Include="..\Roms\DiskII.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\DiskII.rom">
<Link>Roms\DiskII.rom</Link>
</Resource>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">

View File

@ -10,7 +10,7 @@ using Jellyfish.Virtu;
[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)]

View File

@ -232,15 +232,15 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Resource Include="..\Disks\Default.dsk">
<EmbeddedResource Include="..\Disks\Default.dsk">
<Link>Disks\Default.dsk</Link>
</Resource>
<Resource Include="..\Roms\AppleIIe.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\AppleIIe.rom">
<Link>Roms\AppleIIe.rom</Link>
</Resource>
<Resource Include="..\Roms\DiskII.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\DiskII.rom">
<Link>Roms\DiskII.rom</Link>
</Resource>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">

View File

@ -230,15 +230,15 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Resource Include="..\Disks\Default.dsk">
<EmbeddedResource Include="..\Disks\Default.dsk">
<Link>Disks\Default.dsk</Link>
</Resource>
<Resource Include="..\Roms\AppleIIe.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\AppleIIe.rom">
<Link>Roms\AppleIIe.rom</Link>
</Resource>
<Resource Include="..\Roms\DiskII.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\DiskII.rom">
<Link>Roms\DiskII.rom</Link>
</Resource>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">

View File

@ -234,15 +234,15 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Resource Include="..\Disks\Default.dsk">
<EmbeddedResource Include="..\Disks\Default.dsk">
<Link>Disks\Default.dsk</Link>
</Resource>
<Resource Include="..\Roms\AppleIIe.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\AppleIIe.rom">
<Link>Roms\AppleIIe.rom</Link>
</Resource>
<Resource Include="..\Roms\DiskII.rom">
</EmbeddedResource>
<EmbeddedResource Include="..\Roms\DiskII.rom">
<Link>Roms\DiskII.rom</Link>
</Resource>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">

View File

@ -15,7 +15,7 @@ using Jellyfish.Virtu;
[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)]

View File

@ -86,7 +86,7 @@ namespace Jellyfish.Virtu.Services
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 @@ namespace Jellyfish.Virtu.Services
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);

View File

@ -20,10 +20,10 @@ namespace Jellyfish.Virtu.Services
}
_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 @@ namespace Jellyfish.Virtu.Services
_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 @@ namespace Jellyfish.Virtu.Services
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 @@ namespace Jellyfish.Virtu.Services
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;
}
}