parent
6d0c8e7c54
commit
27a5e3ac89
|
@ -0,0 +1,14 @@
|
||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Visual Studio
|
||||||
|
*.cs diff=csharp
|
||||||
|
*.sln merge=union
|
||||||
|
*.csproj merge=union
|
||||||
|
|
||||||
|
# Virtu
|
||||||
|
*.do binary
|
||||||
|
*.dsk binary
|
||||||
|
*.nib binary
|
||||||
|
*.po binary
|
||||||
|
*.rom binary
|
|
@ -1,6 +1,6 @@
|
||||||
bin/
|
bin/
|
||||||
obj/
|
obj/
|
||||||
|
|
||||||
*.cachefile
|
*.cachefile
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
|
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
|
||||||
public sealed class AssemblyMetadataAttribute : Attribute
|
public sealed class AssemblyMetadataAttribute : Attribute
|
||||||
{
|
{
|
||||||
public AssemblyMetadataAttribute(string key, string value)
|
public AssemblyMetadataAttribute(string key, string value)
|
||||||
{
|
{
|
||||||
Key = key;
|
Key = key;
|
||||||
Value = value;
|
Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Key { get; private set; }
|
public string Key { get; private set; }
|
||||||
public string Value { get; private set; }
|
public string Value { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Dictionary>
|
<Dictionary>
|
||||||
<Words>
|
<Words>
|
||||||
<Recognized>
|
<Recognized>
|
||||||
<Word>x</Word>
|
<Word>x</Word>
|
||||||
<Word>y</Word>
|
<Word>y</Word>
|
||||||
</Recognized>
|
</Recognized>
|
||||||
</Words>
|
</Words>
|
||||||
</Dictionary>
|
</Dictionary>
|
||||||
|
|
|
@ -1,173 +1,173 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public sealed partial class DirectSound : IDisposable
|
public sealed partial class DirectSound : IDisposable
|
||||||
{
|
{
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
public DirectSound(int sampleRate, int sampleChannels, int sampleBits, int sampleSize, Action<IntPtr, int> updater)
|
public DirectSound(int sampleRate, int sampleChannels, int sampleBits, int sampleSize, Action<IntPtr, int> updater)
|
||||||
{
|
{
|
||||||
_sampleRate = sampleRate;
|
_sampleRate = sampleRate;
|
||||||
_sampleChannels = sampleChannels;
|
_sampleChannels = sampleChannels;
|
||||||
_sampleBits = sampleBits;
|
_sampleBits = sampleBits;
|
||||||
_sampleSize = sampleSize;
|
_sampleSize = sampleSize;
|
||||||
|
|
||||||
_thread = new Thread(Run) { Name = "DirectSound" };
|
_thread = new Thread(Run) { Name = "DirectSound" };
|
||||||
_updater = updater;
|
_updater = updater;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_position1Event.Close();
|
_position1Event.Close();
|
||||||
_position2Event.Close();
|
_position2Event.Close();
|
||||||
_stopEvent.Close();
|
_stopEvent.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVolume(float volume)
|
public void SetVolume(float volume)
|
||||||
{
|
{
|
||||||
int attenuation = (volume < 0.01) ? (int)BufferVolume.Min : (int)Math.Floor(100 * 20 * Math.Log10(volume)); // 100 db
|
int attenuation = (volume < 0.01) ? (int)BufferVolume.Min : (int)Math.Floor(100 * 20 * Math.Log10(volume)); // 100 db
|
||||||
lock (_bufferLock)
|
lock (_bufferLock)
|
||||||
{
|
{
|
||||||
if (_buffer != null)
|
if (_buffer != null)
|
||||||
{
|
{
|
||||||
_buffer.SetVolume(attenuation);
|
_buffer.SetVolume(attenuation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start(IntPtr window)
|
public void Start(IntPtr window)
|
||||||
{
|
{
|
||||||
_window = window;
|
_window = window;
|
||||||
_thread.Start();
|
_thread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
_stopEvent.Set();
|
_stopEvent.Set();
|
||||||
_thread.Join();
|
_thread.Join();
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
int hresult = NativeMethods.DirectSoundCreate(IntPtr.Zero, out _device, IntPtr.Zero);
|
int hresult = NativeMethods.DirectSoundCreate(IntPtr.Zero, out _device, IntPtr.Zero);
|
||||||
if (hresult < 0)
|
if (hresult < 0)
|
||||||
{
|
{
|
||||||
Marshal.ThrowExceptionForHR(hresult);
|
Marshal.ThrowExceptionForHR(hresult);
|
||||||
}
|
}
|
||||||
|
|
||||||
_device.SetCooperativeLevel(_window, CooperativeLevel.Normal);
|
_device.SetCooperativeLevel(_window, CooperativeLevel.Normal);
|
||||||
|
|
||||||
GCHandleHelpers.Pin(new WaveFormat(_sampleRate, _sampleChannels, _sampleBits), waveFormat =>
|
GCHandleHelpers.Pin(new WaveFormat(_sampleRate, _sampleChannels, _sampleBits), waveFormat =>
|
||||||
{
|
{
|
||||||
var description = new BufferDescription(BufferCapabilities.CtrlPositionNotify | BufferCapabilities.CtrlVolume, BlockCount * _sampleSize, waveFormat);
|
var description = new BufferDescription(BufferCapabilities.CtrlPositionNotify | BufferCapabilities.CtrlVolume, BlockCount * _sampleSize, waveFormat);
|
||||||
_device.CreateSoundBuffer(description, out _buffer, IntPtr.Zero);
|
_device.CreateSoundBuffer(description, out _buffer, IntPtr.Zero);
|
||||||
});
|
});
|
||||||
ClearBuffer();
|
ClearBuffer();
|
||||||
|
|
||||||
var positionEvents = new BufferPositionNotify[BlockCount]
|
var positionEvents = new BufferPositionNotify[BlockCount]
|
||||||
{
|
{
|
||||||
new BufferPositionNotify(0 * _sampleSize, _position1Event), new BufferPositionNotify(1 * _sampleSize, _position2Event)
|
new BufferPositionNotify(0 * _sampleSize, _position1Event), new BufferPositionNotify(1 * _sampleSize, _position2Event)
|
||||||
};
|
};
|
||||||
((IDirectSoundNotify)_buffer).SetNotificationPositions(positionEvents.Length, positionEvents);
|
((IDirectSoundNotify)_buffer).SetNotificationPositions(positionEvents.Length, positionEvents);
|
||||||
|
|
||||||
_buffer.Play(0, 0, BufferPlay.Looping);
|
_buffer.Play(0, 0, BufferPlay.Looping);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
private void ClearBuffer()
|
private void ClearBuffer()
|
||||||
{
|
{
|
||||||
UpdateBuffer(0, 0, BufferLock.EntireBuffer, (buffer, bufferSize) => MarshalHelpers.ZeroMemory(buffer, bufferSize));
|
UpdateBuffer(0, 0, BufferLock.EntireBuffer, (buffer, bufferSize) => MarshalHelpers.ZeroMemory(buffer, bufferSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RestoreBuffer()
|
private void RestoreBuffer()
|
||||||
{
|
{
|
||||||
BufferStatus status;
|
BufferStatus status;
|
||||||
_buffer.GetStatus(out status);
|
_buffer.GetStatus(out status);
|
||||||
if ((status & BufferStatus.BufferLost) != 0)
|
if ((status & BufferStatus.BufferLost) != 0)
|
||||||
{
|
{
|
||||||
_buffer.Restore();
|
_buffer.Restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateBuffer(int offset, int count, BufferLock flags, Action<IntPtr, int> updater)
|
private void UpdateBuffer(int offset, int count, BufferLock flags, Action<IntPtr, int> updater)
|
||||||
{
|
{
|
||||||
RestoreBuffer();
|
RestoreBuffer();
|
||||||
|
|
||||||
IntPtr buffer1, buffer2;
|
IntPtr buffer1, buffer2;
|
||||||
int buffer1Size, buffer2Size;
|
int buffer1Size, buffer2Size;
|
||||||
_buffer.Lock(offset, count, out buffer1, out buffer1Size, out buffer2, out buffer2Size, flags);
|
_buffer.Lock(offset, count, out buffer1, out buffer1Size, out buffer2, out buffer2Size, flags);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (buffer1 != IntPtr.Zero)
|
if (buffer1 != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
updater(buffer1, buffer1Size);
|
updater(buffer1, buffer1Size);
|
||||||
}
|
}
|
||||||
if (buffer2 != IntPtr.Zero)
|
if (buffer2 != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
updater(buffer2, buffer2Size);
|
updater(buffer2, buffer2Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_buffer.Unlock(buffer1, buffer1Size, buffer2, buffer2Size);
|
_buffer.Unlock(buffer1, buffer1Size, buffer2, buffer2Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Uninitialize()
|
private void Uninitialize()
|
||||||
{
|
{
|
||||||
lock (_bufferLock)
|
lock (_bufferLock)
|
||||||
{
|
{
|
||||||
if (_buffer != null)
|
if (_buffer != null)
|
||||||
{
|
{
|
||||||
_buffer.Stop();
|
_buffer.Stop();
|
||||||
Marshal.ReleaseComObject(_buffer);
|
Marshal.ReleaseComObject(_buffer);
|
||||||
_buffer = null;
|
_buffer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_device != null)
|
if (_device != null)
|
||||||
{
|
{
|
||||||
Marshal.ReleaseComObject(_device);
|
Marshal.ReleaseComObject(_device);
|
||||||
_device = null;
|
_device = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
private void Run() // com mta thread
|
private void Run() // com mta thread
|
||||||
{
|
{
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
var eventHandles = new EventWaitHandle[] { _position1Event, _position2Event, _stopEvent };
|
var eventHandles = new EventWaitHandle[] { _position1Event, _position2Event, _stopEvent };
|
||||||
int index = WaitHandle.WaitAny(eventHandles);
|
int index = WaitHandle.WaitAny(eventHandles);
|
||||||
|
|
||||||
while (index < BlockCount)
|
while (index < BlockCount)
|
||||||
{
|
{
|
||||||
UpdateBuffer(((index + 1) % BlockCount) * _sampleSize, _sampleSize, BufferLock.None, _updater); // update next block in circular buffer
|
UpdateBuffer(((index + 1) % BlockCount) * _sampleSize, _sampleSize, BufferLock.None, _updater); // update next block in circular buffer
|
||||||
index = WaitHandle.WaitAny(eventHandles);
|
index = WaitHandle.WaitAny(eventHandles);
|
||||||
}
|
}
|
||||||
|
|
||||||
Uninitialize();
|
Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int BlockCount = 2;
|
private const int BlockCount = 2;
|
||||||
|
|
||||||
private int _sampleRate;
|
private int _sampleRate;
|
||||||
private int _sampleChannels;
|
private int _sampleChannels;
|
||||||
private int _sampleBits;
|
private int _sampleBits;
|
||||||
private int _sampleSize;
|
private int _sampleSize;
|
||||||
|
|
||||||
private Thread _thread;
|
private Thread _thread;
|
||||||
private IntPtr _window;
|
private IntPtr _window;
|
||||||
private IDirectSound _device;
|
private IDirectSound _device;
|
||||||
private IDirectSoundBuffer _buffer;
|
private IDirectSoundBuffer _buffer;
|
||||||
private readonly object _bufferLock = new object();
|
private readonly object _bufferLock = new object();
|
||||||
private Action<IntPtr, int> _updater;
|
private Action<IntPtr, int> _updater;
|
||||||
|
|
||||||
private AutoResetEvent _position1Event = new AutoResetEvent(false);
|
private AutoResetEvent _position1Event = new AutoResetEvent(false);
|
||||||
private AutoResetEvent _position2Event = new AutoResetEvent(false);
|
private AutoResetEvent _position2Event = new AutoResetEvent(false);
|
||||||
private ManualResetEvent _stopEvent = new ManualResetEvent(false);
|
private ManualResetEvent _stopEvent = new ManualResetEvent(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,110 +1,110 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public sealed partial class DirectSound
|
public sealed partial class DirectSound
|
||||||
{
|
{
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum BufferCapabilities { PrimaryBuffer = 0x00000001, CtrlVolume = 0x00000080, CtrlPositionNotify = 0x00000100, StickyFocus = 0x00004000, GlobalFocus = 0x00008000 }
|
private enum BufferCapabilities { PrimaryBuffer = 0x00000001, CtrlVolume = 0x00000080, CtrlPositionNotify = 0x00000100, StickyFocus = 0x00004000, GlobalFocus = 0x00008000 }
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum BufferLock { None = 0x00000000, FromWriteCursor = 0x00000001, EntireBuffer = 0x00000002 }
|
private enum BufferLock { None = 0x00000000, FromWriteCursor = 0x00000001, EntireBuffer = 0x00000002 }
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum BufferPlay { Looping = 0x00000001 }
|
private enum BufferPlay { Looping = 0x00000001 }
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum BufferStatus { Playing = 0x00000001, BufferLost = 0x00000002, Looping = 0x00000004, Terminated = 0x00000020 }
|
private enum BufferStatus { Playing = 0x00000001, BufferLost = 0x00000002, Looping = 0x00000004, Terminated = 0x00000020 }
|
||||||
|
|
||||||
private enum BufferVolume { Min = -10000, Max = 0 }
|
private enum BufferVolume { Min = -10000, Max = 0 }
|
||||||
|
|
||||||
private enum CooperativeLevel { Normal = 1, Priority = 2 }
|
private enum CooperativeLevel { Normal = 1, Priority = 2 }
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
private sealed class BufferDescription
|
private sealed class BufferDescription
|
||||||
{
|
{
|
||||||
public BufferDescription(BufferCapabilities capabilities, int size, IntPtr format)
|
public BufferDescription(BufferCapabilities capabilities, int size, IntPtr format)
|
||||||
{
|
{
|
||||||
dwSize = Marshal.SizeOf(typeof(BufferDescription));
|
dwSize = Marshal.SizeOf(typeof(BufferDescription));
|
||||||
dwFlags = capabilities;
|
dwFlags = capabilities;
|
||||||
dwBufferBytes = size;
|
dwBufferBytes = size;
|
||||||
lpwfxFormat = format;
|
lpwfxFormat = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int dwSize;
|
public int dwSize;
|
||||||
public BufferCapabilities dwFlags;
|
public BufferCapabilities dwFlags;
|
||||||
public int dwBufferBytes;
|
public int dwBufferBytes;
|
||||||
public int dwReserved;
|
public int dwReserved;
|
||||||
public IntPtr lpwfxFormat;
|
public IntPtr lpwfxFormat;
|
||||||
public Guid guid3DAlgorithm;
|
public Guid guid3DAlgorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
private struct BufferPositionNotify
|
private struct BufferPositionNotify
|
||||||
{
|
{
|
||||||
[SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle")]
|
[SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle")]
|
||||||
public BufferPositionNotify(int offset, EventWaitHandle notifyEvent)
|
public BufferPositionNotify(int offset, EventWaitHandle notifyEvent)
|
||||||
{
|
{
|
||||||
dwOffset = offset;
|
dwOffset = offset;
|
||||||
hEventNotify = notifyEvent.SafeWaitHandle.DangerousGetHandle();
|
hEventNotify = notifyEvent.SafeWaitHandle.DangerousGetHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int dwOffset;
|
public int dwOffset;
|
||||||
public IntPtr hEventNotify;
|
public IntPtr hEventNotify;
|
||||||
}
|
}
|
||||||
|
|
||||||
[ComImport, Guid("279AFA83-4981-11CE-A521-0020AF0BE560"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
[ComImport, Guid("279AFA83-4981-11CE-A521-0020AF0BE560"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
private interface IDirectSound
|
private interface IDirectSound
|
||||||
{
|
{
|
||||||
void CreateSoundBuffer(BufferDescription pcDSBufferDesc, [MarshalAs(UnmanagedType.Interface)] out IDirectSoundBuffer pDSBuffer, IntPtr pUnkOuter);
|
void CreateSoundBuffer(BufferDescription pcDSBufferDesc, [MarshalAs(UnmanagedType.Interface)] out IDirectSoundBuffer pDSBuffer, IntPtr pUnkOuter);
|
||||||
void GetCaps(IntPtr pDSCaps);
|
void GetCaps(IntPtr pDSCaps);
|
||||||
void DuplicateSoundBuffer([MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer pDSBufferOriginal, [MarshalAs(UnmanagedType.Interface)] out IDirectSoundBuffer pDSBufferDuplicate);
|
void DuplicateSoundBuffer([MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer pDSBufferOriginal, [MarshalAs(UnmanagedType.Interface)] out IDirectSoundBuffer pDSBufferDuplicate);
|
||||||
void SetCooperativeLevel(IntPtr hwnd, CooperativeLevel dwLevel);
|
void SetCooperativeLevel(IntPtr hwnd, CooperativeLevel dwLevel);
|
||||||
void Compact();
|
void Compact();
|
||||||
void GetSpeakerConfig(out int dwSpeakerConfig);
|
void GetSpeakerConfig(out int dwSpeakerConfig);
|
||||||
void SetSpeakerConfig(int dwSpeakerConfig);
|
void SetSpeakerConfig(int dwSpeakerConfig);
|
||||||
void Initialize([MarshalAs(UnmanagedType.LPStruct)] Guid pcGuidDevice);
|
void Initialize([MarshalAs(UnmanagedType.LPStruct)] Guid pcGuidDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ComImport, Guid("279AFA85-4981-11CE-A521-0020AF0BE560"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
[ComImport, Guid("279AFA85-4981-11CE-A521-0020AF0BE560"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
private interface IDirectSoundBuffer
|
private interface IDirectSoundBuffer
|
||||||
{
|
{
|
||||||
void GetCaps(IntPtr pDSBufferCaps);
|
void GetCaps(IntPtr pDSBufferCaps);
|
||||||
void GetCurrentPosition(out int dwCurrentPlayCursor, out int dwCurrentWriteCursor);
|
void GetCurrentPosition(out int dwCurrentPlayCursor, out int dwCurrentWriteCursor);
|
||||||
void GetFormat(IntPtr pwfxFormat, int dwSizeAllocated, out int dwSizeWritten);
|
void GetFormat(IntPtr pwfxFormat, int dwSizeAllocated, out int dwSizeWritten);
|
||||||
void GetVolume(out int lVolume);
|
void GetVolume(out int lVolume);
|
||||||
void GetPan(out int lPan);
|
void GetPan(out int lPan);
|
||||||
void GetFrequency(out int dwFrequency);
|
void GetFrequency(out int dwFrequency);
|
||||||
void GetStatus(out BufferStatus dwStatus);
|
void GetStatus(out BufferStatus dwStatus);
|
||||||
void Initialize([MarshalAs(UnmanagedType.Interface)] IDirectSound pDirectSound, BufferDescription pcDSBufferDesc);
|
void Initialize([MarshalAs(UnmanagedType.Interface)] IDirectSound pDirectSound, BufferDescription pcDSBufferDesc);
|
||||||
void Lock(int dwOffset, int dwBytes, out IntPtr pvAudioPtr1, out int dwAudioBytes1, out IntPtr pvAudioPtr2, out int dwAudioBytes2, BufferLock dwFlags);
|
void Lock(int dwOffset, int dwBytes, out IntPtr pvAudioPtr1, out int dwAudioBytes1, out IntPtr pvAudioPtr2, out int dwAudioBytes2, BufferLock dwFlags);
|
||||||
void Play(int dwReserved1, int dwPriority, BufferPlay dwFlags);
|
void Play(int dwReserved1, int dwPriority, BufferPlay dwFlags);
|
||||||
void SetCurrentPosition(int dwNewPosition);
|
void SetCurrentPosition(int dwNewPosition);
|
||||||
void SetFormat(WaveFormat pcfxFormat);
|
void SetFormat(WaveFormat pcfxFormat);
|
||||||
void SetVolume(int lVolume);
|
void SetVolume(int lVolume);
|
||||||
void SetPan(int lPan);
|
void SetPan(int lPan);
|
||||||
void SetFrequency(int dwFrequency);
|
void SetFrequency(int dwFrequency);
|
||||||
void Stop();
|
void Stop();
|
||||||
void Unlock(IntPtr pvAudioPtr1, int dwAudioBytes1, IntPtr pvAudioPtr2, int dwAudioBytes2);
|
void Unlock(IntPtr pvAudioPtr1, int dwAudioBytes1, IntPtr pvAudioPtr2, int dwAudioBytes2);
|
||||||
void Restore();
|
void Restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ComImport, Guid("B0210783-89CD-11D0-AF08-00A0C925CD16"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
[ComImport, Guid("B0210783-89CD-11D0-AF08-00A0C925CD16"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
private interface IDirectSoundNotify
|
private interface IDirectSoundNotify
|
||||||
{
|
{
|
||||||
void SetNotificationPositions(int dwPositionNotifies, [MarshalAs(UnmanagedType.LPArray)] BufferPositionNotify[] pcPositionNotifies);
|
void SetNotificationPositions(int dwPositionNotifies, [MarshalAs(UnmanagedType.LPArray)] BufferPositionNotify[] pcPositionNotifies);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
[SuppressUnmanagedCodeSecurity]
|
[SuppressUnmanagedCodeSecurity]
|
||||||
private static class NativeMethods
|
private static class NativeMethods
|
||||||
{
|
{
|
||||||
[DllImport("dsound.dll")]
|
[DllImport("dsound.dll")]
|
||||||
public static extern int DirectSoundCreate(IntPtr pcGuidDevice, [MarshalAs(UnmanagedType.Interface)] out IDirectSound pDS, IntPtr pUnkOuter);
|
public static extern int DirectSoundCreate(IntPtr pcGuidDevice, [MarshalAs(UnmanagedType.Interface)] out IDirectSound pDS, IntPtr pUnkOuter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public static class DispatcherExtensions
|
public static class DispatcherExtensions
|
||||||
{
|
{
|
||||||
public static void Post(this Dispatcher dispatcher, Action action)
|
public static void Post(this Dispatcher dispatcher, Action action)
|
||||||
{
|
{
|
||||||
if (dispatcher == null)
|
if (dispatcher == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("dispatcher");
|
throw new ArgumentNullException("dispatcher");
|
||||||
}
|
}
|
||||||
if (action == null)
|
if (action == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("action");
|
throw new ArgumentNullException("action");
|
||||||
}
|
}
|
||||||
|
|
||||||
new DispatcherSynchronizationContext(dispatcher).Post(state => action(), null);
|
new DispatcherSynchronizationContext(dispatcher).Post(state => action(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Send(this Dispatcher dispatcher, Action action)
|
public static void Send(this Dispatcher dispatcher, Action action)
|
||||||
{
|
{
|
||||||
if (dispatcher == null)
|
if (dispatcher == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("dispatcher");
|
throw new ArgumentNullException("dispatcher");
|
||||||
}
|
}
|
||||||
if (action == null)
|
if (action == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("action");
|
throw new ArgumentNullException("action");
|
||||||
}
|
}
|
||||||
|
|
||||||
new DispatcherSynchronizationContext(dispatcher).Send(state => action(), null);
|
new DispatcherSynchronizationContext(dispatcher).Send(state => action(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public abstract class DisposableBase : IDisposable
|
public abstract class DisposableBase : IDisposable
|
||||||
{
|
{
|
||||||
protected DisposableBase()
|
protected DisposableBase()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~DisposableBase()
|
~DisposableBase()
|
||||||
{
|
{
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<UserControl x:Class="Jellyfish.Library.FrameRateCounter" x:Name="frameRateControl"
|
<UserControl x:Class="Jellyfish.Library.FrameRateCounter" x:Name="frameRateControl"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<TextBlock FontFamily="Consolas" FontSize="12" Foreground="White">
|
<TextBlock FontFamily="Consolas" FontSize="12" Foreground="White">
|
||||||
<TextBlock.Text>
|
<TextBlock.Text>
|
||||||
<Binding Path="FrameRate" ElementName="frameRateControl" StringFormat="{}{0:D} fps"/>
|
<Binding Path="FrameRate" ElementName="frameRateControl" StringFormat="{}{0:D} fps"/>
|
||||||
</TextBlock.Text>
|
</TextBlock.Text>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
@ -1,42 +1,42 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public sealed partial class FrameRateCounter : UserControl
|
public sealed partial class FrameRateCounter : UserControl
|
||||||
{
|
{
|
||||||
public FrameRateCounter()
|
public FrameRateCounter()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
CompositionTarget.Rendering += OnCompositionTargetRendering;
|
CompositionTarget.Rendering += OnCompositionTargetRendering;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
_frameCount++;
|
_frameCount++;
|
||||||
|
|
||||||
long time = DateTime.UtcNow.Ticks;
|
long time = DateTime.UtcNow.Ticks;
|
||||||
if (time - _lastTime >= TimeSpan.TicksPerSecond)
|
if (time - _lastTime >= TimeSpan.TicksPerSecond)
|
||||||
{
|
{
|
||||||
_lastTime = time;
|
_lastTime = time;
|
||||||
FrameRate = _frameCount;
|
FrameRate = _frameCount;
|
||||||
_frameCount = 0;
|
_frameCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty FrameRateProperty = DependencyProperty.Register("FrameRate", typeof(int), typeof(FrameRateCounter),
|
public static readonly DependencyProperty FrameRateProperty = DependencyProperty.Register("FrameRate", typeof(int), typeof(FrameRateCounter),
|
||||||
new PropertyMetadata(0));
|
new PropertyMetadata(0));
|
||||||
|
|
||||||
public int FrameRate
|
public int FrameRate
|
||||||
{
|
{
|
||||||
get { return (int)GetValue(FrameRateProperty); }
|
get { return (int)GetValue(FrameRateProperty); }
|
||||||
set { SetValue(FrameRateProperty, value); }
|
set { SetValue(FrameRateProperty, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _frameCount;
|
private int _frameCount;
|
||||||
private long _lastTime;
|
private long _lastTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,32 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public static class GCHandleHelpers
|
public static class GCHandleHelpers
|
||||||
{
|
{
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
public static void Pin(object value, Action<IntPtr> action)
|
public static void Pin(object value, Action<IntPtr> action)
|
||||||
{
|
{
|
||||||
if (action == null)
|
if (action == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("action");
|
throw new ArgumentNullException("action");
|
||||||
}
|
}
|
||||||
|
|
||||||
var gcHandle = new GCHandle();
|
var gcHandle = new GCHandle();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
gcHandle = GCHandle.Alloc(value, GCHandleType.Pinned);
|
gcHandle = GCHandle.Alloc(value, GCHandleType.Pinned);
|
||||||
action(gcHandle.AddrOfPinnedObject());
|
action(gcHandle.AddrOfPinnedObject());
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (gcHandle.IsAllocated)
|
if (gcHandle.IsAllocated)
|
||||||
{
|
{
|
||||||
gcHandle.Free();
|
gcHandle.Free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
|
[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
|
||||||
[assembly: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Jellyfish.Library.FrameRateCounter.#frameRateControl")]
|
[assembly: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Jellyfish.Library.FrameRateCounter.#frameRateControl")]
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public static class IEnumerableExtensions
|
public static class IEnumerableExtensions
|
||||||
{
|
{
|
||||||
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
|
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("source");
|
throw new ArgumentNullException("source");
|
||||||
}
|
}
|
||||||
if (action == null)
|
if (action == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("action");
|
throw new ArgumentNullException("action");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (T item in source)
|
foreach (T item in source)
|
||||||
{
|
{
|
||||||
action(item);
|
action(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2012
|
# Visual Studio 2012
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public static class MarshalHelpers
|
public static class MarshalHelpers
|
||||||
{
|
{
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
public static void FillMemory(IntPtr buffer, int bufferSize, byte value)
|
public static void FillMemory(IntPtr buffer, int bufferSize, byte value)
|
||||||
{
|
{
|
||||||
NativeMethods.FillMemory(buffer, (IntPtr)bufferSize, value);
|
NativeMethods.FillMemory(buffer, (IntPtr)bufferSize, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
public static void ZeroMemory(IntPtr buffer, int bufferSize)
|
public static void ZeroMemory(IntPtr buffer, int bufferSize)
|
||||||
{
|
{
|
||||||
NativeMethods.ZeroMemory(buffer, (IntPtr)bufferSize);
|
NativeMethods.ZeroMemory(buffer, (IntPtr)bufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
[SuppressUnmanagedCodeSecurity]
|
[SuppressUnmanagedCodeSecurity]
|
||||||
private static class NativeMethods
|
private static class NativeMethods
|
||||||
{
|
{
|
||||||
[SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
|
[SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
public static extern void FillMemory(IntPtr destination, IntPtr length, byte fill);
|
public static extern void FillMemory(IntPtr destination, IntPtr length, byte fill);
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
|
[SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
public static extern void ZeroMemory(IntPtr destination, IntPtr length);
|
public static extern void ZeroMemory(IntPtr destination, IntPtr length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public static class MathHelpers
|
public static class MathHelpers
|
||||||
{
|
{
|
||||||
public static int Clamp(int value, int min, int max)
|
public static int Clamp(int value, int min, int max)
|
||||||
{
|
{
|
||||||
return (value < min) ? min : (value > max) ? max : value;
|
return (value < min) ? min : (value > max) ? max : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ClampByte(int value)
|
public static int ClampByte(int value)
|
||||||
{
|
{
|
||||||
return Clamp(value, byte.MinValue, byte.MaxValue);
|
return Clamp(value, byte.MinValue, byte.MaxValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,95 +1,95 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public abstract class ApplicationBase : Application
|
public abstract class ApplicationBase : Application
|
||||||
{
|
{
|
||||||
protected ApplicationBase() :
|
protected ApplicationBase() :
|
||||||
this(null)
|
this(null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ApplicationBase(string name)
|
protected ApplicationBase(string name)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
|
|
||||||
UnhandledException += OnApplicationUnhandledException;
|
UnhandledException += OnApplicationUnhandledException;
|
||||||
//AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
|
//AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
|
||||||
|
|
||||||
if (Debugger.IsAttached)
|
if (Debugger.IsAttached)
|
||||||
{
|
{
|
||||||
var settings = Application.Current.Host.Settings;
|
var settings = Application.Current.Host.Settings;
|
||||||
settings.EnableFrameRateCounter = true;
|
settings.EnableFrameRateCounter = true;
|
||||||
//settings.EnableRedrawRegions = true;
|
//settings.EnableRedrawRegions = true;
|
||||||
//settings.EnableCacheVisualization = true;
|
//settings.EnableCacheVisualization = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void InitializeOutOfBrowserUpdate()
|
protected void InitializeOutOfBrowserUpdate()
|
||||||
{
|
{
|
||||||
if (IsRunningOutOfBrowser)
|
if (IsRunningOutOfBrowser)
|
||||||
{
|
{
|
||||||
CheckAndDownloadUpdateCompleted += OnApplicationCheckAndDownloadUpdateCompleted;
|
CheckAndDownloadUpdateCompleted += OnApplicationCheckAndDownloadUpdateCompleted;
|
||||||
CheckAndDownloadUpdateAsync();
|
CheckAndDownloadUpdateAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetExceptionCaption(string title, bool isTerminating = false)
|
private string GetExceptionCaption(string title, bool isTerminating = false)
|
||||||
{
|
{
|
||||||
var caption = new StringBuilder();
|
var caption = new StringBuilder();
|
||||||
if (!string.IsNullOrEmpty(Name))
|
if (!string.IsNullOrEmpty(Name))
|
||||||
{
|
{
|
||||||
caption.Append(Name).Append(' ');
|
caption.Append(Name).Append(' ');
|
||||||
}
|
}
|
||||||
caption.Append(title);
|
caption.Append(title);
|
||||||
if (isTerminating)
|
if (isTerminating)
|
||||||
{
|
{
|
||||||
caption.Append(" (Terminating)");
|
caption.Append(" (Terminating)");
|
||||||
}
|
}
|
||||||
|
|
||||||
return caption.ToString();
|
return caption.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnApplicationCheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e)
|
private void OnApplicationCheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Error != null)
|
if (e.Error != null)
|
||||||
{
|
{
|
||||||
if (e.Error is PlatformNotSupportedException)
|
if (e.Error is PlatformNotSupportedException)
|
||||||
{
|
{
|
||||||
MessageBox.Show("An application update is available, but it requires the latest version of Silverlight.");
|
MessageBox.Show("An application update is available, but it requires the latest version of Silverlight.");
|
||||||
}
|
}
|
||||||
//else if (Debugger.IsAttached)
|
//else if (Debugger.IsAttached)
|
||||||
//{
|
//{
|
||||||
// Debugger.Break();
|
// Debugger.Break();
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
else if (e.UpdateAvailable)
|
else if (e.UpdateAvailable)
|
||||||
{
|
{
|
||||||
MessageBox.Show("An application update was downloaded. Restart the application to run the latest version.");
|
MessageBox.Show("An application update was downloaded. Restart the application to run the latest version.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
|
private void OnApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("Application Exception"), MessageBoxButton.OK);
|
MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("Application Exception"), MessageBoxButton.OK);
|
||||||
if (Debugger.IsAttached)
|
if (Debugger.IsAttached)
|
||||||
{
|
{
|
||||||
Debugger.Break();
|
Debugger.Break();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
//private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||||
//{
|
//{
|
||||||
// MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating), MessageBoxButton.OK);
|
// MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating), MessageBoxButton.OK);
|
||||||
// if (Debugger.IsAttached)
|
// if (Debugger.IsAttached)
|
||||||
// {
|
// {
|
||||||
// Debugger.Break();
|
// Debugger.Break();
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,133 +1,133 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProductVersion>8.0.50727</ProductVersion>
|
<ProductVersion>8.0.50727</ProductVersion>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<ProjectGuid>{99CA7796-B72A-4F8C-BCDB-0D688220A331}</ProjectGuid>
|
<ProjectGuid>{99CA7796-B72A-4F8C-BCDB-0D688220A331}</ProjectGuid>
|
||||||
<ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
<ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>Jellyfish.Library</RootNamespace>
|
<RootNamespace>Jellyfish.Library</RootNamespace>
|
||||||
<AssemblyName>Jellyfish.Library</AssemblyName>
|
<AssemblyName>Jellyfish.Library</AssemblyName>
|
||||||
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
|
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
|
||||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
|
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
|
||||||
<SilverlightApplication>false</SilverlightApplication>
|
<SilverlightApplication>false</SilverlightApplication>
|
||||||
<ValidateXaml>true</ValidateXaml>
|
<ValidateXaml>true</ValidateXaml>
|
||||||
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
|
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- This property group is only here to support building this project using the
|
<!-- This property group is only here to support building this project using the
|
||||||
MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs
|
MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs
|
||||||
to set the TargetFrameworkVersion to v3.5 -->
|
to set the TargetFrameworkVersion to v3.5 -->
|
||||||
<PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
|
<PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>bin\</OutputPath>
|
<OutputPath>bin\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE;SILVERLIGHT;CODE_ANALYSIS</DefineConstants>
|
<DefineConstants>DEBUG;TRACE;SILVERLIGHT;CODE_ANALYSIS</DefineConstants>
|
||||||
<NoStdLib>true</NoStdLib>
|
<NoStdLib>true</NoStdLib>
|
||||||
<NoConfig>true</NoConfig>
|
<NoConfig>true</NoConfig>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<OutputPath>bin\</OutputPath>
|
<OutputPath>bin\</OutputPath>
|
||||||
<DefineConstants>TRACE;SILVERLIGHT;CODE_ANALYSIS</DefineConstants>
|
<DefineConstants>TRACE;SILVERLIGHT;CODE_ANALYSIS</DefineConstants>
|
||||||
<NoStdLib>true</NoStdLib>
|
<NoStdLib>true</NoStdLib>
|
||||||
<NoConfig>true</NoConfig>
|
<NoConfig>true</NoConfig>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SignAssembly>false</SignAssembly>
|
<SignAssembly>false</SignAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyOriginatorKeyFile>..\..\..\Jellyfish\StrongName.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>..\..\..\Jellyfish\StrongName.snk</AssemblyOriginatorKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="mscorlib" />
|
<Reference Include="mscorlib" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Net" />
|
<Reference Include="System.Net" />
|
||||||
<Reference Include="System.Windows" />
|
<Reference Include="System.Windows" />
|
||||||
<Reference Include="System.Windows.Browser" />
|
<Reference Include="System.Windows.Browser" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\AssemblyMetadataAttribute.cs">
|
<Compile Include="..\AssemblyMetadataAttribute.cs">
|
||||||
<Link>AssemblyMetadataAttribute.cs</Link>
|
<Link>AssemblyMetadataAttribute.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DispatcherExtensions.cs">
|
<Compile Include="..\DispatcherExtensions.cs">
|
||||||
<Link>DispatcherExtensions.cs</Link>
|
<Link>DispatcherExtensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DisposableBase.cs">
|
<Compile Include="..\DisposableBase.cs">
|
||||||
<Link>DisposableBase.cs</Link>
|
<Link>DisposableBase.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\FrameRateCounter.xaml.cs">
|
<Compile Include="..\FrameRateCounter.xaml.cs">
|
||||||
<Link>FrameRateCounter.xaml.cs</Link>
|
<Link>FrameRateCounter.xaml.cs</Link>
|
||||||
<DependentUpon>FrameRateCounter.xaml</DependentUpon>
|
<DependentUpon>FrameRateCounter.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\GlobalSuppressions.cs">
|
<Compile Include="..\GlobalSuppressions.cs">
|
||||||
<Link>GlobalSuppressions.cs</Link>
|
<Link>GlobalSuppressions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\IEnumerableExtensions.cs">
|
<Compile Include="..\IEnumerableExtensions.cs">
|
||||||
<Link>IEnumerableExtensions.cs</Link>
|
<Link>IEnumerableExtensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MathHelpers.cs">
|
<Compile Include="..\MathHelpers.cs">
|
||||||
<Link>MathHelpers.cs</Link>
|
<Link>MathHelpers.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\StreamExtensions.cs">
|
<Compile Include="..\StreamExtensions.cs">
|
||||||
<Link>StreamExtensions.cs</Link>
|
<Link>StreamExtensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\StringBuilderExtensions.cs">
|
<Compile Include="..\StringBuilderExtensions.cs">
|
||||||
<Link>StringBuilderExtensions.cs</Link>
|
<Link>StringBuilderExtensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\WaveFormat.cs">
|
<Compile Include="..\WaveFormat.cs">
|
||||||
<Link>WaveFormat.cs</Link>
|
<Link>WaveFormat.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="ApplicationBase.cs" />
|
<Compile Include="ApplicationBase.cs" />
|
||||||
<Compile Include="WaveMediaStreamSource.cs" />
|
<Compile Include="WaveMediaStreamSource.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Include="..\FrameRateCounter.xaml">
|
<Page Include="..\FrameRateCounter.xaml">
|
||||||
<Link>FrameRateCounter.xaml</Link>
|
<Link>FrameRateCounter.xaml</Link>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
|
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
|
||||||
<Link>CustomDictionary.xml</Link>
|
<Link>CustomDictionary.xml</Link>
|
||||||
</CodeAnalysisDictionary>
|
</CodeAnalysisDictionary>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio>
|
<VisualStudio>
|
||||||
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
|
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
|
||||||
<SilverlightProjectProperties />
|
<SilverlightProjectProperties />
|
||||||
</FlavorProperties>
|
</FlavorProperties>
|
||||||
</VisualStudio>
|
</VisualStudio>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
|
@ -1,20 +1,20 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2012
|
# Visual Studio 2012
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Resources;
|
using System.Resources;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
[assembly: AssemblyTitle("Library")]
|
[assembly: AssemblyTitle("Library")]
|
||||||
[assembly: AssemblyDescription("Common Library")]
|
[assembly: AssemblyDescription("Common Library")]
|
||||||
[assembly: AssemblyProduct("Jellyfish.Library.Silverlight")]
|
[assembly: AssemblyProduct("Jellyfish.Library.Silverlight")]
|
||||||
[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
|
[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2009-2012 Digital Jellyfish Design Ltd")]
|
[assembly: AssemblyCopyright("Copyright © 2009-2012 Digital Jellyfish Design Ltd")]
|
||||||
[assembly: AssemblyMetadata("Developer", "Sean Fausett")]
|
[assembly: AssemblyMetadata("Developer", "Sean Fausett")]
|
||||||
|
|
||||||
[assembly: AssemblyVersion("0.4.0.0")]
|
[assembly: AssemblyVersion("0.4.0.0")]
|
||||||
[assembly: AssemblyFileVersion("0.4.0.0")]
|
[assembly: AssemblyFileVersion("0.4.0.0")]
|
||||||
[assembly: AssemblyInformationalVersion("0.4.0.0")]
|
[assembly: AssemblyInformationalVersion("0.4.0.0")]
|
||||||
|
|
||||||
[assembly: CLSCompliant(false)]
|
[assembly: CLSCompliant(false)]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")]
|
[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")]
|
||||||
|
|
||||||
[assembly: NeutralResourcesLanguage("en")]
|
[assembly: NeutralResourcesLanguage("en")]
|
||||||
|
|
|
@ -1,76 +1,76 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public sealed class WaveMediaStreamSource : MediaStreamSource, IDisposable
|
public sealed class WaveMediaStreamSource : MediaStreamSource, IDisposable
|
||||||
{
|
{
|
||||||
public WaveMediaStreamSource(int sampleRate, int sampleChannels, int sampleBits, int sampleSize, int sampleLatency, Action<byte[], int> updater)
|
public WaveMediaStreamSource(int sampleRate, int sampleChannels, int sampleBits, int sampleSize, int sampleLatency, Action<byte[], int> updater)
|
||||||
{
|
{
|
||||||
_bufferSize = sampleSize;
|
_bufferSize = sampleSize;
|
||||||
_buffer = new byte[_bufferSize];
|
_buffer = new byte[_bufferSize];
|
||||||
_bufferStream = new MemoryStream(_buffer);
|
_bufferStream = new MemoryStream(_buffer);
|
||||||
_waveFormat = new WaveFormat(sampleRate, sampleChannels, sampleBits);
|
_waveFormat = new WaveFormat(sampleRate, sampleChannels, sampleBits);
|
||||||
AudioBufferLength = sampleLatency; // ms; avoids audio delay
|
AudioBufferLength = sampleLatency; // ms; avoids audio delay
|
||||||
_updater = updater;
|
_updater = updater;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_bufferStream.Dispose();
|
_bufferStream.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CloseMedia()
|
protected override void CloseMedia()
|
||||||
{
|
{
|
||||||
_audioDescription = null;
|
_audioDescription = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void GetDiagnosticAsync(MediaStreamSourceDiagnosticKind diagnosticKind)
|
protected override void GetDiagnosticAsync(MediaStreamSourceDiagnosticKind diagnosticKind)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void GetSampleAsync(MediaStreamType mediaStreamType)
|
protected override void GetSampleAsync(MediaStreamType mediaStreamType)
|
||||||
{
|
{
|
||||||
_updater(_buffer, _bufferSize);
|
_updater(_buffer, _bufferSize);
|
||||||
|
|
||||||
var sample = new MediaStreamSample(_audioDescription, _bufferStream, 0, _bufferSize, _timestamp, _emptySampleDict);
|
var sample = new MediaStreamSample(_audioDescription, _bufferStream, 0, _bufferSize, _timestamp, _emptySampleDict);
|
||||||
_timestamp += _bufferSize * 10000000L / _waveFormat.AverageBytesPerSec; // 100 ns
|
_timestamp += _bufferSize * 10000000L / _waveFormat.AverageBytesPerSec; // 100 ns
|
||||||
|
|
||||||
ReportGetSampleCompleted(sample);
|
ReportGetSampleCompleted(sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OpenMediaAsync()
|
protected override void OpenMediaAsync()
|
||||||
{
|
{
|
||||||
_timestamp = 0;
|
_timestamp = 0;
|
||||||
|
|
||||||
var sourceAttributes = new Dictionary<MediaSourceAttributesKeys, string>() { { MediaSourceAttributesKeys.Duration, "0" }, { MediaSourceAttributesKeys.CanSeek, "false" } };
|
var sourceAttributes = new Dictionary<MediaSourceAttributesKeys, string>() { { MediaSourceAttributesKeys.Duration, "0" }, { MediaSourceAttributesKeys.CanSeek, "false" } };
|
||||||
var streamAttributes = new Dictionary<MediaStreamAttributeKeys, string>() { { MediaStreamAttributeKeys.CodecPrivateData, _waveFormat.ToHexString() } };
|
var streamAttributes = new Dictionary<MediaStreamAttributeKeys, string>() { { MediaStreamAttributeKeys.CodecPrivateData, _waveFormat.ToHexString() } };
|
||||||
_audioDescription = new MediaStreamDescription(MediaStreamType.Audio, streamAttributes);
|
_audioDescription = new MediaStreamDescription(MediaStreamType.Audio, streamAttributes);
|
||||||
var availableStreams = new List<MediaStreamDescription>() { _audioDescription };
|
var availableStreams = new List<MediaStreamDescription>() { _audioDescription };
|
||||||
|
|
||||||
ReportOpenMediaCompleted(sourceAttributes, availableStreams);
|
ReportOpenMediaCompleted(sourceAttributes, availableStreams);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SeekAsync(long seekToTime)
|
protected override void SeekAsync(long seekToTime)
|
||||||
{
|
{
|
||||||
ReportSeekCompleted(seekToTime);
|
ReportSeekCompleted(seekToTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SwitchMediaStreamAsync(MediaStreamDescription mediaStreamDescription)
|
protected override void SwitchMediaStreamAsync(MediaStreamDescription mediaStreamDescription)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] _buffer;
|
private byte[] _buffer;
|
||||||
private int _bufferSize;
|
private int _bufferSize;
|
||||||
private MemoryStream _bufferStream;
|
private MemoryStream _bufferStream;
|
||||||
private Action<byte[], int> _updater;
|
private Action<byte[], int> _updater;
|
||||||
private WaveFormat _waveFormat;
|
private WaveFormat _waveFormat;
|
||||||
private long _timestamp;
|
private long _timestamp;
|
||||||
private MediaStreamDescription _audioDescription;
|
private MediaStreamDescription _audioDescription;
|
||||||
private Dictionary<MediaSampleAttributeKeys, string> _emptySampleDict = new Dictionary<MediaSampleAttributeKeys, string>();
|
private Dictionary<MediaSampleAttributeKeys, string> _emptySampleDict = new Dictionary<MediaSampleAttributeKeys, string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,94 +1,94 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public static class StreamExtensions
|
public static class StreamExtensions
|
||||||
{
|
{
|
||||||
[SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "3#")]
|
[SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "3#")]
|
||||||
public static int ReadBlock(this Stream stream, byte[] buffer, int offset, ref int count)
|
public static int ReadBlock(this Stream stream, byte[] buffer, int offset, ref int count)
|
||||||
{
|
{
|
||||||
int read = ReadBlock(stream, buffer, offset, count, count);
|
int read = ReadBlock(stream, buffer, offset, count, count);
|
||||||
count -= read;
|
count -= read;
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
|
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
|
||||||
public static int ReadBlock(this Stream stream, byte[] buffer, int offset = 0, int count = int.MaxValue, int minCount = int.MaxValue)
|
public static int ReadBlock(this Stream stream, byte[] buffer, int offset = 0, int count = int.MaxValue, int minCount = int.MaxValue)
|
||||||
{
|
{
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("stream");
|
throw new ArgumentNullException("stream");
|
||||||
}
|
}
|
||||||
if (buffer == null)
|
if (buffer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("buffer");
|
throw new ArgumentNullException("buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
count = Math.Min(count, buffer.Length - offset);
|
count = Math.Min(count, buffer.Length - offset);
|
||||||
minCount = Math.Min(minCount, buffer.Length - offset);
|
minCount = Math.Min(minCount, buffer.Length - offset);
|
||||||
|
|
||||||
int total = 0;
|
int total = 0;
|
||||||
int read;
|
int read;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
total += read = stream.Read(buffer, offset + total, count - total);
|
total += read = stream.Read(buffer, offset + total, count - total);
|
||||||
}
|
}
|
||||||
while ((read > 0) && (total < count));
|
while ((read > 0) && (total < count));
|
||||||
|
|
||||||
if (total < minCount)
|
if (total < minCount)
|
||||||
{
|
{
|
||||||
throw new EndOfStreamException();
|
throw new EndOfStreamException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
|
[SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
|
||||||
public static int ReadWord(this Stream stream, bool optional = false)
|
public static int ReadWord(this Stream stream, bool optional = false)
|
||||||
{
|
{
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("stream");
|
throw new ArgumentNullException("stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
int lowByte = stream.ReadByte();
|
int lowByte = stream.ReadByte();
|
||||||
int highByte = stream.ReadByte();
|
int highByte = stream.ReadByte();
|
||||||
int word = lowByte | (highByte << 8);
|
int word = lowByte | (highByte << 8);
|
||||||
if ((word < 0) && !optional)
|
if ((word < 0) && !optional)
|
||||||
{
|
{
|
||||||
throw new EndOfStreamException();
|
throw new EndOfStreamException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return word;
|
return word;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SkipBlock(this Stream stream, int count)
|
public static void SkipBlock(this Stream stream, int count)
|
||||||
{
|
{
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("stream");
|
throw new ArgumentNullException("stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream.CanSeek)
|
if (stream.CanSeek)
|
||||||
{
|
{
|
||||||
stream.Seek(count, SeekOrigin.Current);
|
stream.Seek(count, SeekOrigin.Current);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int total = 0;
|
int total = 0;
|
||||||
int read;
|
int read;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
total += read = stream.Read(_skipBuffer, 0, Math.Min(count - total, SkipBufferSize));
|
total += read = stream.Read(_skipBuffer, 0, Math.Min(count - total, SkipBufferSize));
|
||||||
}
|
}
|
||||||
while ((read > 0) && (total < count));
|
while ((read > 0) && (total < count));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int SkipBufferSize = 1024;
|
private const int SkipBufferSize = 1024;
|
||||||
|
|
||||||
private static byte[] _skipBuffer = new byte[SkipBufferSize];
|
private static byte[] _skipBuffer = new byte[SkipBufferSize];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +1,54 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public static class StringBuilderExtensions
|
public static class StringBuilderExtensions
|
||||||
{
|
{
|
||||||
public static StringBuilder AppendHex(this StringBuilder builder, short value) // little endian
|
public static StringBuilder AppendHex(this StringBuilder builder, short value) // little endian
|
||||||
{
|
{
|
||||||
if (builder == null)
|
if (builder == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("builder");
|
throw new ArgumentNullException("builder");
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}", value & 0xFF, value >> 8);
|
return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}", value & 0xFF, value >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StringBuilder AppendHex(this StringBuilder builder, int value) // little endian
|
public static StringBuilder AppendHex(this StringBuilder builder, int value) // little endian
|
||||||
{
|
{
|
||||||
if (builder == null)
|
if (builder == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("builder");
|
throw new ArgumentNullException("builder");
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}{2:X2}{3:X2}", value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, value >> 24);
|
return builder.AppendFormat(CultureInfo.InvariantCulture, "{0:X2}{1:X2}{2:X2}{3:X2}", value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, value >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StringBuilder AppendWithoutGarbage(this StringBuilder builder, int value)
|
public static StringBuilder AppendWithoutGarbage(this StringBuilder builder, int value)
|
||||||
{
|
{
|
||||||
if (builder == null)
|
if (builder == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("builder");
|
throw new ArgumentNullException("builder");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
{
|
{
|
||||||
builder.Append('-');
|
builder.Append('-');
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = builder.Length;
|
int index = builder.Length;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
builder.Insert(index, Digits, (value % 10) + 9, 1);
|
builder.Insert(index, Digits, (value % 10) + 9, 1);
|
||||||
value /= 10;
|
value /= 10;
|
||||||
}
|
}
|
||||||
while (value != 0);
|
while (value != 0);
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly char[] Digits = new char[] { '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
private static readonly char[] Digits = new char[] { '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +1,49 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public sealed class WaveFormat
|
public sealed class WaveFormat
|
||||||
{
|
{
|
||||||
public WaveFormat(int sampleRate, int sampleChannels, int sampleBits)
|
public WaveFormat(int sampleRate, int sampleChannels, int sampleBits)
|
||||||
{
|
{
|
||||||
_formatTag = WaveFormatPcm;
|
_formatTag = WaveFormatPcm;
|
||||||
_samplesPerSec = sampleRate;
|
_samplesPerSec = sampleRate;
|
||||||
_channels = (short)sampleChannels;
|
_channels = (short)sampleChannels;
|
||||||
_bitsPerSample = (short)sampleBits;
|
_bitsPerSample = (short)sampleBits;
|
||||||
_blockAlign = (short)(sampleChannels * sampleBits / 8);
|
_blockAlign = (short)(sampleChannels * sampleBits / 8);
|
||||||
_averageBytesPerSec = sampleRate * _blockAlign;
|
_averageBytesPerSec = sampleRate * _blockAlign;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ToHexString() // little endian
|
public string ToHexString() // little endian
|
||||||
{
|
{
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
builder.AppendHex(_formatTag);
|
builder.AppendHex(_formatTag);
|
||||||
builder.AppendHex(_channels);
|
builder.AppendHex(_channels);
|
||||||
builder.AppendHex(_samplesPerSec);
|
builder.AppendHex(_samplesPerSec);
|
||||||
builder.AppendHex(_averageBytesPerSec);
|
builder.AppendHex(_averageBytesPerSec);
|
||||||
builder.AppendHex(_blockAlign);
|
builder.AppendHex(_blockAlign);
|
||||||
builder.AppendHex(_bitsPerSample);
|
builder.AppendHex(_bitsPerSample);
|
||||||
builder.AppendHex(_size);
|
builder.AppendHex(_size);
|
||||||
|
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SamplesPerSec { get { return _samplesPerSec; } } // no auto props
|
public int SamplesPerSec { get { return _samplesPerSec; } } // no auto props
|
||||||
public int Channels { get { return _channels; } }
|
public int Channels { get { return _channels; } }
|
||||||
public int BitsPerSample { get { return _bitsPerSample; } }
|
public int BitsPerSample { get { return _bitsPerSample; } }
|
||||||
public int AverageBytesPerSec { get { return _averageBytesPerSec; } }
|
public int AverageBytesPerSec { get { return _averageBytesPerSec; } }
|
||||||
|
|
||||||
private const int WaveFormatPcm = 1;
|
private const int WaveFormatPcm = 1;
|
||||||
|
|
||||||
private short _formatTag;
|
private short _formatTag;
|
||||||
private short _channels;
|
private short _channels;
|
||||||
private int _samplesPerSec;
|
private int _samplesPerSec;
|
||||||
private int _averageBytesPerSec;
|
private int _averageBytesPerSec;
|
||||||
private short _blockAlign;
|
private short _blockAlign;
|
||||||
private short _bitsPerSample;
|
private short _bitsPerSample;
|
||||||
private short _size;
|
private short _size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +1,65 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public abstract class ApplicationBase : Application
|
public abstract class ApplicationBase : Application
|
||||||
{
|
{
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
protected ApplicationBase() :
|
protected ApplicationBase() :
|
||||||
this(null)
|
this(null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
protected ApplicationBase(string name)
|
protected ApplicationBase(string name)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
|
|
||||||
DispatcherUnhandledException += OnApplicationDispatcherUnhandledException;
|
DispatcherUnhandledException += OnApplicationDispatcherUnhandledException;
|
||||||
AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += OnAppDomainUnhandledException;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetExceptionCaption(string title, bool isTerminating = false)
|
private string GetExceptionCaption(string title, bool isTerminating = false)
|
||||||
{
|
{
|
||||||
var caption = new StringBuilder();
|
var caption = new StringBuilder();
|
||||||
if (!string.IsNullOrEmpty(Name))
|
if (!string.IsNullOrEmpty(Name))
|
||||||
{
|
{
|
||||||
caption.Append(Name).Append(' ');
|
caption.Append(Name).Append(' ');
|
||||||
}
|
}
|
||||||
caption.Append(title);
|
caption.Append(title);
|
||||||
if (isTerminating)
|
if (isTerminating)
|
||||||
{
|
{
|
||||||
caption.Append(" (Terminating)");
|
caption.Append(" (Terminating)");
|
||||||
}
|
}
|
||||||
|
|
||||||
return caption.ToString();
|
return caption.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnApplicationDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
private void OnApplicationDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
MessageBox.Show(e.Exception.ToString(), GetExceptionCaption("Application Dispatcher Exception", isTerminating: true));
|
MessageBox.Show(e.Exception.ToString(), GetExceptionCaption("Application Dispatcher Exception", isTerminating: true));
|
||||||
if (Debugger.IsAttached)
|
if (Debugger.IsAttached)
|
||||||
{
|
{
|
||||||
Debugger.Break();
|
Debugger.Break();
|
||||||
}
|
}
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating));
|
MessageBox.Show(e.ExceptionObject.ToString(), GetExceptionCaption("AppDomain Exception", e.IsTerminating));
|
||||||
if (Debugger.IsAttached)
|
if (Debugger.IsAttached)
|
||||||
{
|
{
|
||||||
Debugger.Break();
|
Debugger.Break();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,120 +1,120 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProductVersion>8.0.30703</ProductVersion>
|
<ProductVersion>8.0.30703</ProductVersion>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<ProjectGuid>{93900841-7250-4D3A-837E-43EE3FD118DC}</ProjectGuid>
|
<ProjectGuid>{93900841-7250-4D3A-837E-43EE3FD118DC}</ProjectGuid>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>Jellyfish.Library</RootNamespace>
|
<RootNamespace>Jellyfish.Library</RootNamespace>
|
||||||
<AssemblyName>Jellyfish.Library</AssemblyName>
|
<AssemblyName>Jellyfish.Library</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>bin\</OutputPath>
|
<OutputPath>bin\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE;WINDOWS;CODE_ANALYSIS</DefineConstants>
|
<DefineConstants>DEBUG;TRACE;WINDOWS;CODE_ANALYSIS</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<OutputPath>bin\</OutputPath>
|
<OutputPath>bin\</OutputPath>
|
||||||
<DefineConstants>TRACE;WINDOWS;CODE_ANALYSIS</DefineConstants>
|
<DefineConstants>TRACE;WINDOWS;CODE_ANALYSIS</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SignAssembly>false</SignAssembly>
|
<SignAssembly>false</SignAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyOriginatorKeyFile>..\..\..\Jellyfish\StrongName.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>..\..\..\Jellyfish\StrongName.snk</AssemblyOriginatorKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Xaml" />
|
<Reference Include="System.Xaml" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\DirectSound.cs">
|
<Compile Include="..\DirectSound.cs">
|
||||||
<Link>DirectSound.cs</Link>
|
<Link>DirectSound.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DirectSoundInterop.cs">
|
<Compile Include="..\DirectSoundInterop.cs">
|
||||||
<Link>DirectSoundInterop.cs</Link>
|
<Link>DirectSoundInterop.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DispatcherExtensions.cs">
|
<Compile Include="..\DispatcherExtensions.cs">
|
||||||
<Link>DispatcherExtensions.cs</Link>
|
<Link>DispatcherExtensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DisposableBase.cs">
|
<Compile Include="..\DisposableBase.cs">
|
||||||
<Link>DisposableBase.cs</Link>
|
<Link>DisposableBase.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\FrameRateCounter.xaml.cs">
|
<Compile Include="..\FrameRateCounter.xaml.cs">
|
||||||
<Link>FrameRateCounter.xaml.cs</Link>
|
<Link>FrameRateCounter.xaml.cs</Link>
|
||||||
<DependentUpon>FrameRateCounter.xaml</DependentUpon>
|
<DependentUpon>FrameRateCounter.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\GCHandleHelpers.cs">
|
<Compile Include="..\GCHandleHelpers.cs">
|
||||||
<Link>GCHandleHelpers.cs</Link>
|
<Link>GCHandleHelpers.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\GlobalSuppressions.cs">
|
<Compile Include="..\GlobalSuppressions.cs">
|
||||||
<Link>GlobalSuppressions.cs</Link>
|
<Link>GlobalSuppressions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\IEnumerableExtensions.cs">
|
<Compile Include="..\IEnumerableExtensions.cs">
|
||||||
<Link>IEnumerableExtensions.cs</Link>
|
<Link>IEnumerableExtensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MarshalHelpers.cs">
|
<Compile Include="..\MarshalHelpers.cs">
|
||||||
<Link>MarshalHelpers.cs</Link>
|
<Link>MarshalHelpers.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MathHelpers.cs">
|
<Compile Include="..\MathHelpers.cs">
|
||||||
<Link>MathHelpers.cs</Link>
|
<Link>MathHelpers.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\StreamExtensions.cs">
|
<Compile Include="..\StreamExtensions.cs">
|
||||||
<Link>StreamExtensions.cs</Link>
|
<Link>StreamExtensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\StringBuilderExtensions.cs">
|
<Compile Include="..\StringBuilderExtensions.cs">
|
||||||
<Link>StringBuilderExtensions.cs</Link>
|
<Link>StringBuilderExtensions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\WaveFormat.cs">
|
<Compile Include="..\WaveFormat.cs">
|
||||||
<Link>WaveFormat.cs</Link>
|
<Link>WaveFormat.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="ApplicationBase.cs" />
|
<Compile Include="ApplicationBase.cs" />
|
||||||
<Compile Include="WindowExtensions.cs" />
|
<Compile Include="WindowExtensions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Include="..\FrameRateCounter.xaml">
|
<Page Include="..\FrameRateCounter.xaml">
|
||||||
<Link>FrameRateCounter.xaml</Link>
|
<Link>FrameRateCounter.xaml</Link>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
|
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
|
||||||
<Link>CustomDictionary.xml</Link>
|
<Link>CustomDictionary.xml</Link>
|
||||||
</CodeAnalysisDictionary>
|
</CodeAnalysisDictionary>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
|
@ -1,20 +1,20 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2012
|
# Visual Studio 2012
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Resources;
|
using System.Resources;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
[assembly: AssemblyTitle("Library")]
|
[assembly: AssemblyTitle("Library")]
|
||||||
[assembly: AssemblyDescription("Common Library")]
|
[assembly: AssemblyDescription("Common Library")]
|
||||||
[assembly: AssemblyProduct("Jellyfish.Library.Wpf")]
|
[assembly: AssemblyProduct("Jellyfish.Library.Wpf")]
|
||||||
[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
|
[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2009-2012 Digital Jellyfish Design Ltd")]
|
[assembly: AssemblyCopyright("Copyright © 2009-2012 Digital Jellyfish Design Ltd")]
|
||||||
[assembly: AssemblyMetadata("Developer", "Sean Fausett")]
|
[assembly: AssemblyMetadata("Developer", "Sean Fausett")]
|
||||||
|
|
||||||
[assembly: AssemblyVersion("0.4.0.0")]
|
[assembly: AssemblyVersion("0.4.0.0")]
|
||||||
[assembly: AssemblyFileVersion("0.4.0.0")]
|
[assembly: AssemblyFileVersion("0.4.0.0")]
|
||||||
[assembly: AssemblyInformationalVersion("0.4.0.0")]
|
[assembly: AssemblyInformationalVersion("0.4.0.0")]
|
||||||
|
|
||||||
[assembly: CLSCompliant(false)]
|
[assembly: CLSCompliant(false)]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")]
|
[assembly: Guid("66034b9e-9f0b-47b0-aac4-cade9a748891")]
|
||||||
|
|
||||||
[assembly: NeutralResourcesLanguage("en")]
|
[assembly: NeutralResourcesLanguage("en")]
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
|
|
||||||
namespace Jellyfish.Library
|
namespace Jellyfish.Library
|
||||||
{
|
{
|
||||||
public static class WindowExtensions
|
public static class WindowExtensions
|
||||||
{
|
{
|
||||||
public static IntPtr GetHandle(this Window window)
|
public static IntPtr GetHandle(this Window window)
|
||||||
{
|
{
|
||||||
return new WindowInteropHelper(window).Handle;
|
return new WindowInteropHelper(window).Handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
560
License.txt
560
License.txt
|
@ -1,280 +1,280 @@
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 2, June 1991
|
Version 2, June 1991
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
Preamble
|
Preamble
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
The licenses for most software are designed to take away your
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
License is intended to guarantee your freedom to share and change free
|
License is intended to guarantee your freedom to share and change free
|
||||||
software--to make sure the software is free for all its users. This
|
software--to make sure the software is free for all its users. This
|
||||||
General Public License applies to most of the Free Software
|
General Public License applies to most of the Free Software
|
||||||
Foundation's software and to any other program whose authors commit to
|
Foundation's software and to any other program whose authors commit to
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
the GNU Lesser General Public License instead.) You can apply it to
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
your programs, too.
|
your programs, too.
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
When we speak of free software, we are referring to freedom, not
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
have the freedom to distribute copies of free software (and charge for
|
have the freedom to distribute copies of free software (and charge for
|
||||||
this service if you wish), that you receive source code or can get it
|
this service if you wish), that you receive source code or can get it
|
||||||
if you want it, that you can change the software or use pieces of it
|
if you want it, that you can change the software or use pieces of it
|
||||||
in new free programs; and that you know you can do these things.
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
To protect your rights, we need to make restrictions that forbid
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
These restrictions translate to certain responsibilities for you if you
|
These restrictions translate to certain responsibilities for you if you
|
||||||
distribute copies of the software, or if you modify it.
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
For example, if you distribute copies of such a program, whether
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
you have. You must make sure that they, too, receive or can get the
|
you have. You must make sure that they, too, receive or can get the
|
||||||
source code. And you must show them these terms so they know their
|
source code. And you must show them these terms so they know their
|
||||||
rights.
|
rights.
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
distribute and/or modify the software.
|
distribute and/or modify the software.
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
Also, for each author's protection and ours, we want to make certain
|
||||||
that everyone understands that there is no warranty for this free
|
that everyone understands that there is no warranty for this free
|
||||||
software. If the software is modified by someone else and passed on, we
|
software. If the software is modified by someone else and passed on, we
|
||||||
want its recipients to know that what they have is not the original, so
|
want its recipients to know that what they have is not the original, so
|
||||||
that any problems introduced by others will not reflect on the original
|
that any problems introduced by others will not reflect on the original
|
||||||
authors' reputations.
|
authors' reputations.
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
Finally, any free program is threatened constantly by software
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
program will individually obtain patent licenses, in effect making the
|
program will individually obtain patent licenses, in effect making the
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
The precise terms and conditions for copying, distribution and
|
||||||
modification follow.
|
modification follow.
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
0. This License applies to any program or other work which contains
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
under the terms of this General Public License. The "Program", below,
|
under the terms of this General Public License. The "Program", below,
|
||||||
refers to any such program or work, and a "work based on the Program"
|
refers to any such program or work, and a "work based on the Program"
|
||||||
means either the Program or any derivative work under copyright law:
|
means either the Program or any derivative work under copyright law:
|
||||||
that is to say, a work containing the Program or a portion of it,
|
that is to say, a work containing the Program or a portion of it,
|
||||||
either verbatim or with modifications and/or translated into another
|
either verbatim or with modifications and/or translated into another
|
||||||
language. (Hereinafter, translation is included without limitation in
|
language. (Hereinafter, translation is included without limitation in
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
Activities other than copying, distribution and modification are not
|
||||||
covered by this License; they are outside its scope. The act of
|
covered by this License; they are outside its scope. The act of
|
||||||
running the Program is not restricted, and the output from the Program
|
running the Program is not restricted, and the output from the Program
|
||||||
is covered only if its contents constitute a work based on the
|
is covered only if its contents constitute a work based on the
|
||||||
Program (independent of having been made by running the Program).
|
Program (independent of having been made by running the Program).
|
||||||
Whether that is true depends on what the Program does.
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
source code as you receive it, in any medium, provided that you
|
source code as you receive it, in any medium, provided that you
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
notices that refer to this License and to the absence of any warranty;
|
notices that refer to this License and to the absence of any warranty;
|
||||||
and give any other recipients of the Program a copy of this License
|
and give any other recipients of the Program a copy of this License
|
||||||
along with the Program.
|
along with the Program.
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
of it, thus forming a work based on the Program, and copy and
|
of it, thus forming a work based on the Program, and copy and
|
||||||
distribute such modifications or work under the terms of Section 1
|
distribute such modifications or work under the terms of Section 1
|
||||||
above, provided that you also meet all of these conditions:
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
a) You must cause the modified files to carry prominent notices
|
||||||
stating that you changed the files and the date of any change.
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
b) You must cause any work that you distribute or publish, that in
|
||||||
whole or in part contains or is derived from the Program or any
|
whole or in part contains or is derived from the Program or any
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
parties under the terms of this License.
|
parties under the terms of this License.
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
c) If the modified program normally reads commands interactively
|
||||||
when run, you must cause it, when started running for such
|
when run, you must cause it, when started running for such
|
||||||
interactive use in the most ordinary way, to print or display an
|
interactive use in the most ordinary way, to print or display an
|
||||||
announcement including an appropriate copyright notice and a
|
announcement including an appropriate copyright notice and a
|
||||||
notice that there is no warranty (or else, saying that you provide
|
notice that there is no warranty (or else, saying that you provide
|
||||||
a warranty) and that users may redistribute the program under
|
a warranty) and that users may redistribute the program under
|
||||||
these conditions, and telling the user how to view a copy of this
|
these conditions, and telling the user how to view a copy of this
|
||||||
License. (Exception: if the Program itself is interactive but
|
License. (Exception: if the Program itself is interactive but
|
||||||
does not normally print such an announcement, your work based on
|
does not normally print such an announcement, your work based on
|
||||||
the Program is not required to print an announcement.)
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
These requirements apply to the modified work as a whole. If
|
||||||
identifiable sections of that work are not derived from the Program,
|
identifiable sections of that work are not derived from the Program,
|
||||||
and can be reasonably considered independent and separate works in
|
and can be reasonably considered independent and separate works in
|
||||||
themselves, then this License, and its terms, do not apply to those
|
themselves, then this License, and its terms, do not apply to those
|
||||||
sections when you distribute them as separate works. But when you
|
sections when you distribute them as separate works. But when you
|
||||||
distribute the same sections as part of a whole which is a work based
|
distribute the same sections as part of a whole which is a work based
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
this License, whose permissions for other licensees extend to the
|
this License, whose permissions for other licensees extend to the
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
exercise the right to control the distribution of derivative or
|
exercise the right to control the distribution of derivative or
|
||||||
collective works based on the Program.
|
collective works based on the Program.
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
In addition, mere aggregation of another work not based on the Program
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
a storage or distribution medium does not bring the other work under
|
a storage or distribution medium does not bring the other work under
|
||||||
the scope of this License.
|
the scope of this License.
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
under Section 2) in object code or executable form under the terms of
|
under Section 2) in object code or executable form under the terms of
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
source code, which must be distributed under the terms of Sections
|
source code, which must be distributed under the terms of Sections
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
b) Accompany it with a written offer, valid for at least three
|
||||||
years, to give any third party, for a charge no more than your
|
years, to give any third party, for a charge no more than your
|
||||||
cost of physically performing source distribution, a complete
|
cost of physically performing source distribution, a complete
|
||||||
machine-readable copy of the corresponding source code, to be
|
machine-readable copy of the corresponding source code, to be
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
customarily used for software interchange; or,
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
c) Accompany it with the information you received as to the offer
|
||||||
to distribute corresponding source code. (This alternative is
|
to distribute corresponding source code. (This alternative is
|
||||||
allowed only for noncommercial distribution and only if you
|
allowed only for noncommercial distribution and only if you
|
||||||
received the program in object code or executable form with such
|
received the program in object code or executable form with such
|
||||||
an offer, in accord with Subsection b above.)
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
The source code for a work means the preferred form of the work for
|
||||||
making modifications to it. For an executable work, complete source
|
making modifications to it. For an executable work, complete source
|
||||||
code means all the source code for all modules it contains, plus any
|
code means all the source code for all modules it contains, plus any
|
||||||
associated interface definition files, plus the scripts used to
|
associated interface definition files, plus the scripts used to
|
||||||
control compilation and installation of the executable. However, as a
|
control compilation and installation of the executable. However, as a
|
||||||
special exception, the source code distributed need not include
|
special exception, the source code distributed need not include
|
||||||
anything that is normally distributed (in either source or binary
|
anything that is normally distributed (in either source or binary
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
operating system on which the executable runs, unless that component
|
operating system on which the executable runs, unless that component
|
||||||
itself accompanies the executable.
|
itself accompanies the executable.
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
If distribution of executable or object code is made by offering
|
||||||
access to copy from a designated place, then offering equivalent
|
access to copy from a designated place, then offering equivalent
|
||||||
access to copy the source code from the same place counts as
|
access to copy the source code from the same place counts as
|
||||||
distribution of the source code, even though third parties are not
|
distribution of the source code, even though third parties are not
|
||||||
compelled to copy the source along with the object code.
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
except as expressly provided under this License. Any attempt
|
except as expressly provided under this License. Any attempt
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
void, and will automatically terminate your rights under this License.
|
void, and will automatically terminate your rights under this License.
|
||||||
However, parties who have received copies, or rights, from you under
|
However, parties who have received copies, or rights, from you under
|
||||||
this License will not have their licenses terminated so long as such
|
this License will not have their licenses terminated so long as such
|
||||||
parties remain in full compliance.
|
parties remain in full compliance.
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
5. You are not required to accept this License, since you have not
|
||||||
signed it. However, nothing else grants you permission to modify or
|
signed it. However, nothing else grants you permission to modify or
|
||||||
distribute the Program or its derivative works. These actions are
|
distribute the Program or its derivative works. These actions are
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
modifying or distributing the Program (or any work based on the
|
modifying or distributing the Program (or any work based on the
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
all its terms and conditions for copying, distributing or modifying
|
all its terms and conditions for copying, distributing or modifying
|
||||||
the Program or works based on it.
|
the Program or works based on it.
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
Program), the recipient automatically receives a license from the
|
Program), the recipient automatically receives a license from the
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
these terms and conditions. You may not impose any further
|
these terms and conditions. You may not impose any further
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
You are not responsible for enforcing compliance by third parties to
|
You are not responsible for enforcing compliance by third parties to
|
||||||
this License.
|
this License.
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
infringement or for any other reason (not limited to patent issues),
|
infringement or for any other reason (not limited to patent issues),
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
excuse you from the conditions of this License. If you cannot
|
excuse you from the conditions of this License. If you cannot
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
License and any other pertinent obligations, then as a consequence you
|
License and any other pertinent obligations, then as a consequence you
|
||||||
may not distribute the Program at all. For example, if a patent
|
may not distribute the Program at all. For example, if a patent
|
||||||
license would not permit royalty-free redistribution of the Program by
|
license would not permit royalty-free redistribution of the Program by
|
||||||
all those who receive copies directly or indirectly through you, then
|
all those who receive copies directly or indirectly through you, then
|
||||||
the only way you could satisfy both it and this License would be to
|
the only way you could satisfy both it and this License would be to
|
||||||
refrain entirely from distribution of the Program.
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
If any portion of this section is held invalid or unenforceable under
|
||||||
any particular circumstance, the balance of the section is intended to
|
any particular circumstance, the balance of the section is intended to
|
||||||
apply and the section as a whole is intended to apply in other
|
apply and the section as a whole is intended to apply in other
|
||||||
circumstances.
|
circumstances.
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
It is not the purpose of this section to induce you to infringe any
|
||||||
patents or other property right claims or to contest validity of any
|
patents or other property right claims or to contest validity of any
|
||||||
such claims; this section has the sole purpose of protecting the
|
such claims; this section has the sole purpose of protecting the
|
||||||
integrity of the free software distribution system, which is
|
integrity of the free software distribution system, which is
|
||||||
implemented by public license practices. Many people have made
|
implemented by public license practices. Many people have made
|
||||||
generous contributions to the wide range of software distributed
|
generous contributions to the wide range of software distributed
|
||||||
through that system in reliance on consistent application of that
|
through that system in reliance on consistent application of that
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
to distribute software through any other system and a licensee cannot
|
to distribute software through any other system and a licensee cannot
|
||||||
impose that choice.
|
impose that choice.
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
This section is intended to make thoroughly clear what is believed to
|
||||||
be a consequence of the rest of this License.
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
original copyright holder who places the Program under this License
|
original copyright holder who places the Program under this License
|
||||||
may add an explicit geographical distribution limitation excluding
|
may add an explicit geographical distribution limitation excluding
|
||||||
those countries, so that distribution is permitted only in or among
|
those countries, so that distribution is permitted only in or among
|
||||||
countries not thus excluded. In such case, this License incorporates
|
countries not thus excluded. In such case, this License incorporates
|
||||||
the limitation as if written in the body of this License.
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
of the General Public License from time to time. Such new versions will
|
of the General Public License from time to time. Such new versions will
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
address new problems or concerns.
|
address new problems or concerns.
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
Each version is given a distinguishing version number. If the Program
|
||||||
specifies a version number of this License which applies to it and "any
|
specifies a version number of this License which applies to it and "any
|
||||||
later version", you have the option of following the terms and conditions
|
later version", you have the option of following the terms and conditions
|
||||||
either of that version or of any later version published by the Free
|
either of that version or of any later version published by the Free
|
||||||
Software Foundation. If the Program does not specify a version number of
|
Software Foundation. If the Program does not specify a version number of
|
||||||
this License, you may choose any version ever published by the Free Software
|
this License, you may choose any version ever published by the Free Software
|
||||||
Foundation.
|
Foundation.
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
programs whose distribution conditions are different, write to the author
|
programs whose distribution conditions are different, write to the author
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
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 preserving the free status of all derivatives of our free software and
|
||||||
of promoting the sharing and reuse of software generally.
|
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
|
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
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
REPAIR OR CORRECTION.
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
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
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed class Cassette : MachineComponent
|
public sealed class Cassette : MachineComponent
|
||||||
{
|
{
|
||||||
public Cassette(Machine machine) :
|
public Cassette(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
|
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
|
||||||
public bool ReadInput()
|
public bool ReadInput()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
|
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
|
||||||
public void ToggleOutput()
|
public void ToggleOutput()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
6522
Virtu/Cpu.cs
6522
Virtu/Cpu.cs
File diff suppressed because it is too large
Load Diff
166
Virtu/CpuData.cs
166
Virtu/CpuData.cs
|
@ -1,83 +1,83 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public partial class Cpu
|
public partial class Cpu
|
||||||
{
|
{
|
||||||
private const int OpCodeCount = 256;
|
private const int OpCodeCount = 256;
|
||||||
|
|
||||||
private readonly Action[] ExecuteOpCode65N02;
|
private readonly Action[] ExecuteOpCode65N02;
|
||||||
private readonly Action[] ExecuteOpCode65C02;
|
private readonly Action[] ExecuteOpCode65C02;
|
||||||
|
|
||||||
private const int PC = 0x01;
|
private const int PC = 0x01;
|
||||||
private const int PZ = 0x02;
|
private const int PZ = 0x02;
|
||||||
private const int PI = 0x04;
|
private const int PI = 0x04;
|
||||||
private const int PD = 0x08;
|
private const int PD = 0x08;
|
||||||
private const int PB = 0x10;
|
private const int PB = 0x10;
|
||||||
private const int PR = 0x20;
|
private const int PR = 0x20;
|
||||||
private const int PV = 0x40;
|
private const int PV = 0x40;
|
||||||
private const int PN = 0x80;
|
private const int PN = 0x80;
|
||||||
|
|
||||||
private const int DataCount = 256;
|
private const int DataCount = 256;
|
||||||
|
|
||||||
private static readonly int[] DataPN = new int[DataCount]
|
private static readonly int[] DataPN = new int[DataCount]
|
||||||
{
|
{
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly int[] DataPZ = new int[DataCount]
|
private static readonly int[] DataPZ = new int[DataCount]
|
||||||
{
|
{
|
||||||
PZ, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
PZ, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly int[] DataPNZ = new int[DataCount]
|
private static readonly int[] DataPNZ = new int[DataCount]
|
||||||
{
|
{
|
||||||
PZ, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
PZ, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN,
|
||||||
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN
|
PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN, PN
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Dictionary>
|
<Dictionary>
|
||||||
<Acronyms>
|
<Acronyms>
|
||||||
<CasingExceptions>
|
<CasingExceptions>
|
||||||
<Acronym>Io</Acronym>
|
<Acronym>Io</Acronym>
|
||||||
<Acronym>RPC</Acronym>
|
<Acronym>RPC</Acronym>
|
||||||
</CasingExceptions>
|
</CasingExceptions>
|
||||||
</Acronyms>
|
</Acronyms>
|
||||||
<Words>
|
<Words>
|
||||||
<Recognized>
|
<Recognized>
|
||||||
<Word>Annunciator</Word>
|
<Word>Annunciator</Word>
|
||||||
<Word>Cpu</Word>
|
<Word>Cpu</Word>
|
||||||
<Word>Dsk</Word>
|
<Word>Dsk</Word>
|
||||||
<Word>Prg</Word>
|
<Word>Prg</Word>
|
||||||
<Word>Unpause</Word>
|
<Word>Unpause</Word>
|
||||||
<Word>Virtu</Word>
|
<Word>Virtu</Word>
|
||||||
<Word>Xex</Word>
|
<Word>Xex</Word>
|
||||||
<Word>Xna</Word>
|
<Word>Xna</Word>
|
||||||
<Word>x</Word>
|
<Word>x</Word>
|
||||||
<Word>y</Word>
|
<Word>y</Word>
|
||||||
</Recognized>
|
</Recognized>
|
||||||
<Unrecognized>
|
<Unrecognized>
|
||||||
<Word>DownRight</Word>
|
<Word>DownRight</Word>
|
||||||
<Word>GamePad</Word>
|
<Word>GamePad</Word>
|
||||||
<Word>UpRight</Word>
|
<Word>UpRight</Word>
|
||||||
</Unrecognized>
|
</Unrecognized>
|
||||||
</Words>
|
</Words>
|
||||||
</Dictionary>
|
</Dictionary>
|
||||||
|
|
194
Virtu/Disk525.cs
194
Virtu/Disk525.cs
|
@ -1,97 +1,97 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public abstract class Disk525
|
public abstract class Disk525
|
||||||
{
|
{
|
||||||
protected Disk525(string name, byte[] data, bool isWriteProtected)
|
protected Disk525(string name, byte[] data, bool isWriteProtected)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Data = data;
|
Data = data;
|
||||||
IsWriteProtected = isWriteProtected;
|
IsWriteProtected = isWriteProtected;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Disk525 CreateDisk(string name, Stream stream, bool isWriteProtected)
|
public static Disk525 CreateDisk(string name, Stream stream, bool isWriteProtected)
|
||||||
{
|
{
|
||||||
if (name == null)
|
if (name == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("name");
|
throw new ArgumentNullException("name");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.EndsWith(".do", StringComparison.OrdinalIgnoreCase) ||
|
if (name.EndsWith(".do", StringComparison.OrdinalIgnoreCase) ||
|
||||||
name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) // assumes dos sector skew
|
name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) // assumes dos sector skew
|
||||||
{
|
{
|
||||||
return new DiskDsk(name, stream, isWriteProtected, SectorSkew.Dos);
|
return new DiskDsk(name, stream, isWriteProtected, SectorSkew.Dos);
|
||||||
}
|
}
|
||||||
else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase))
|
else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new DiskNib(name, stream, isWriteProtected);
|
return new DiskNib(name, stream, isWriteProtected);
|
||||||
}
|
}
|
||||||
else if (name.EndsWith(".po", StringComparison.OrdinalIgnoreCase))
|
else if (name.EndsWith(".po", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new DiskDsk(name, stream, isWriteProtected, SectorSkew.ProDos);
|
return new DiskDsk(name, stream, isWriteProtected, SectorSkew.ProDos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "version")]
|
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "version")]
|
||||||
public static Disk525 LoadState(BinaryReader reader, Version version)
|
public static Disk525 LoadState(BinaryReader reader, Version version)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
string name = reader.ReadString();
|
string name = reader.ReadString();
|
||||||
var data = reader.ReadBytes(reader.ReadInt32());
|
var data = reader.ReadBytes(reader.ReadInt32());
|
||||||
bool isWriteProtected = reader.ReadBoolean();
|
bool isWriteProtected = reader.ReadBoolean();
|
||||||
|
|
||||||
if (name.EndsWith(".do", StringComparison.OrdinalIgnoreCase) ||
|
if (name.EndsWith(".do", StringComparison.OrdinalIgnoreCase) ||
|
||||||
name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) // assumes dos sector skew
|
name.EndsWith(".dsk", StringComparison.OrdinalIgnoreCase)) // assumes dos sector skew
|
||||||
{
|
{
|
||||||
return new DiskDsk(name, data, isWriteProtected, SectorSkew.Dos);
|
return new DiskDsk(name, data, isWriteProtected, SectorSkew.Dos);
|
||||||
}
|
}
|
||||||
else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase))
|
else if (name.EndsWith(".nib", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new DiskNib(name, data, isWriteProtected);
|
return new DiskNib(name, data, isWriteProtected);
|
||||||
}
|
}
|
||||||
else if (name.EndsWith(".po", StringComparison.OrdinalIgnoreCase))
|
else if (name.EndsWith(".po", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new DiskDsk(name, data, isWriteProtected, SectorSkew.ProDos);
|
return new DiskDsk(name, data, isWriteProtected, SectorSkew.ProDos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveState(BinaryWriter writer)
|
public void SaveState(BinaryWriter writer)
|
||||||
{
|
{
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(Name);
|
writer.Write(Name);
|
||||||
writer.Write(Data.Length);
|
writer.Write(Data.Length);
|
||||||
writer.Write(Data);
|
writer.Write(Data);
|
||||||
writer.Write(IsWriteProtected);
|
writer.Write(IsWriteProtected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ReadTrack(int number, int fraction, byte[] buffer);
|
public abstract void ReadTrack(int number, int fraction, byte[] buffer);
|
||||||
public abstract void WriteTrack(int number, int fraction, byte[] buffer);
|
public abstract void WriteTrack(int number, int fraction, byte[] buffer);
|
||||||
|
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
||||||
public byte[] Data { get; protected set; }
|
public byte[] Data { get; protected set; }
|
||||||
public bool IsWriteProtected { get; private set; }
|
public bool IsWriteProtected { get; private set; }
|
||||||
|
|
||||||
public const int SectorCount = 16;
|
public const int SectorCount = 16;
|
||||||
public const int SectorSize = 0x100;
|
public const int SectorSize = 0x100;
|
||||||
public const int TrackCount = 35;
|
public const int TrackCount = 35;
|
||||||
public const int TrackSize = 0x1A00;
|
public const int TrackSize = 0x1A00;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
648
Virtu/DiskDsk.cs
648
Virtu/DiskDsk.cs
|
@ -1,324 +1,324 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public enum SectorSkew { None = 0, Dos, ProDos };
|
public enum SectorSkew { None = 0, Dos, ProDos };
|
||||||
|
|
||||||
public sealed class DiskDsk : Disk525
|
public sealed class DiskDsk : Disk525
|
||||||
{
|
{
|
||||||
public DiskDsk(string name, byte[] data, bool isWriteProtected, SectorSkew sectorSkew) :
|
public DiskDsk(string name, byte[] data, bool isWriteProtected, SectorSkew sectorSkew) :
|
||||||
base(name, data, isWriteProtected)
|
base(name, data, isWriteProtected)
|
||||||
{
|
{
|
||||||
_sectorSkew = SectorSkewMode[(int)sectorSkew];
|
_sectorSkew = SectorSkewMode[(int)sectorSkew];
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiskDsk(string name, Stream stream, bool isWriteProtected, SectorSkew sectorSkew) :
|
public DiskDsk(string name, Stream stream, bool isWriteProtected, SectorSkew sectorSkew) :
|
||||||
base(name, new byte[TrackCount * SectorCount * SectorSize], isWriteProtected)
|
base(name, new byte[TrackCount * SectorCount * SectorSize], isWriteProtected)
|
||||||
{
|
{
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("stream");
|
throw new ArgumentNullException("stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.ReadBlock(Data);
|
stream.ReadBlock(Data);
|
||||||
_sectorSkew = SectorSkewMode[(int)sectorSkew];
|
_sectorSkew = SectorSkewMode[(int)sectorSkew];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReadTrack(int number, int fraction, byte[] buffer)
|
public override void ReadTrack(int number, int fraction, byte[] buffer)
|
||||||
{
|
{
|
||||||
int track = number / 2;
|
int track = number / 2;
|
||||||
|
|
||||||
_trackBuffer = buffer;
|
_trackBuffer = buffer;
|
||||||
_trackOffset = 0;
|
_trackOffset = 0;
|
||||||
|
|
||||||
WriteNibble(0xFF, 48); // gap 0
|
WriteNibble(0xFF, 48); // gap 0
|
||||||
|
|
||||||
for (int sector = 0; sector < SectorCount; sector++)
|
for (int sector = 0; sector < SectorCount; sector++)
|
||||||
{
|
{
|
||||||
WriteNibble(0xD5); // address prologue
|
WriteNibble(0xD5); // address prologue
|
||||||
WriteNibble(0xAA);
|
WriteNibble(0xAA);
|
||||||
WriteNibble(0x96);
|
WriteNibble(0x96);
|
||||||
|
|
||||||
WriteNibble44(Volume);
|
WriteNibble44(Volume);
|
||||||
WriteNibble44(track);
|
WriteNibble44(track);
|
||||||
WriteNibble44(sector);
|
WriteNibble44(sector);
|
||||||
WriteNibble44(Volume ^ track ^ sector);
|
WriteNibble44(Volume ^ track ^ sector);
|
||||||
|
|
||||||
WriteNibble(0xDE); // address epilogue
|
WriteNibble(0xDE); // address epilogue
|
||||||
WriteNibble(0xAA);
|
WriteNibble(0xAA);
|
||||||
WriteNibble(0xEB);
|
WriteNibble(0xEB);
|
||||||
WriteNibble(0xFF, 8);
|
WriteNibble(0xFF, 8);
|
||||||
|
|
||||||
WriteNibble(0xD5); // data prologue
|
WriteNibble(0xD5); // data prologue
|
||||||
WriteNibble(0xAA);
|
WriteNibble(0xAA);
|
||||||
WriteNibble(0xAD);
|
WriteNibble(0xAD);
|
||||||
|
|
||||||
WriteDataNibbles((track * SectorCount + _sectorSkew[sector]) * SectorSize);
|
WriteDataNibbles((track * SectorCount + _sectorSkew[sector]) * SectorSize);
|
||||||
|
|
||||||
WriteNibble(0xDE); // data epilogue
|
WriteNibble(0xDE); // data epilogue
|
||||||
WriteNibble(0xAA);
|
WriteNibble(0xAA);
|
||||||
WriteNibble(0xEB);
|
WriteNibble(0xEB);
|
||||||
WriteNibble(0xFF, 16);
|
WriteNibble(0xFF, 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteTrack(int number, int fraction, byte[] buffer)
|
public override void WriteTrack(int number, int fraction, byte[] buffer)
|
||||||
{
|
{
|
||||||
if (IsWriteProtected)
|
if (IsWriteProtected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int track = number / 2;
|
int track = number / 2;
|
||||||
|
|
||||||
_trackBuffer = buffer;
|
_trackBuffer = buffer;
|
||||||
_trackOffset = 0;
|
_trackOffset = 0;
|
||||||
int sectorsDone = 0;
|
int sectorsDone = 0;
|
||||||
|
|
||||||
for (int sector = 0; sector < SectorCount; sector++)
|
for (int sector = 0; sector < SectorCount; sector++)
|
||||||
{
|
{
|
||||||
if (!Read3Nibbles(0xD5, 0xAA, 0x96, 0x304))
|
if (!Read3Nibbles(0xD5, 0xAA, 0x96, 0x304))
|
||||||
break; // no address prologue
|
break; // no address prologue
|
||||||
|
|
||||||
/*int readVolume = */ReadNibble44();
|
/*int readVolume = */ReadNibble44();
|
||||||
|
|
||||||
int readTrack = ReadNibble44();
|
int readTrack = ReadNibble44();
|
||||||
if (readTrack != track)
|
if (readTrack != track)
|
||||||
break; // bad track number
|
break; // bad track number
|
||||||
|
|
||||||
int readSector = ReadNibble44();
|
int readSector = ReadNibble44();
|
||||||
if (readSector > SectorCount)
|
if (readSector > SectorCount)
|
||||||
break; // bad sector number
|
break; // bad sector number
|
||||||
if ((sectorsDone & (0x1 << readSector)) != 0)
|
if ((sectorsDone & (0x1 << readSector)) != 0)
|
||||||
break; // already done this sector
|
break; // already done this sector
|
||||||
|
|
||||||
if (ReadNibble44() != (Volume ^ readTrack ^ readSector))
|
if (ReadNibble44() != (Volume ^ readTrack ^ readSector))
|
||||||
break; // bad address checksum
|
break; // bad address checksum
|
||||||
|
|
||||||
if ((ReadNibble() != 0xDE) || (ReadNibble() != 0xAA))
|
if ((ReadNibble() != 0xDE) || (ReadNibble() != 0xAA))
|
||||||
break; // bad address epilogue
|
break; // bad address epilogue
|
||||||
|
|
||||||
if (!Read3Nibbles(0xD5, 0xAA, 0xAD, 0x20))
|
if (!Read3Nibbles(0xD5, 0xAA, 0xAD, 0x20))
|
||||||
break; // no data prologue
|
break; // no data prologue
|
||||||
|
|
||||||
if (!ReadDataNibbles((track * SectorCount + _sectorSkew[sector]) * SectorSize))
|
if (!ReadDataNibbles((track * SectorCount + _sectorSkew[sector]) * SectorSize))
|
||||||
break; // bad data checksum
|
break; // bad data checksum
|
||||||
|
|
||||||
if ((ReadNibble() != 0xDE) || (ReadNibble() != 0xAA))
|
if ((ReadNibble() != 0xDE) || (ReadNibble() != 0xAA))
|
||||||
break; // bad data epilogue
|
break; // bad data epilogue
|
||||||
|
|
||||||
sectorsDone |= 0x1 << sector;
|
sectorsDone |= 0x1 << sector;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sectorsDone != 0xFFFF)
|
if (sectorsDone != 0xFFFF)
|
||||||
throw new InvalidOperationException("disk error"); // TODO: we should alert the user and "dump" a NIB
|
throw new InvalidOperationException("disk error"); // TODO: we should alert the user and "dump" a NIB
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte ReadNibble()
|
private byte ReadNibble()
|
||||||
{
|
{
|
||||||
byte data = _trackBuffer[_trackOffset];
|
byte data = _trackBuffer[_trackOffset];
|
||||||
if (_trackOffset++ == TrackSize)
|
if (_trackOffset++ == TrackSize)
|
||||||
{
|
{
|
||||||
_trackOffset = 0;
|
_trackOffset = 0;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool Read3Nibbles(byte data1, byte data2, byte data3, int maxReads)
|
private bool Read3Nibbles(byte data1, byte data2, byte data3, int maxReads)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
while (--maxReads > 0)
|
while (--maxReads > 0)
|
||||||
{
|
{
|
||||||
if (ReadNibble() != data1)
|
if (ReadNibble() != data1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ReadNibble() != data2)
|
if (ReadNibble() != data2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ReadNibble() != data3)
|
if (ReadNibble() != data3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int ReadNibble44()
|
private int ReadNibble44()
|
||||||
{
|
{
|
||||||
return (((ReadNibble() << 1) | 0x1) & ReadNibble());
|
return (((ReadNibble() << 1) | 0x1) & ReadNibble());
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte ReadTranslatedNibble()
|
private byte ReadTranslatedNibble()
|
||||||
{
|
{
|
||||||
byte data = NibbleToByte[ReadNibble()];
|
byte data = NibbleToByte[ReadNibble()];
|
||||||
// TODO: check that invalid nibbles aren't used
|
// TODO: check that invalid nibbles aren't used
|
||||||
// (put 0xFFs for invalid nibbles in the table)
|
// (put 0xFFs for invalid nibbles in the table)
|
||||||
//if (data == 0xFF)
|
//if (data == 0xFF)
|
||||||
//{
|
//{
|
||||||
//throw an exception
|
//throw an exception
|
||||||
//}
|
//}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ReadDataNibbles(int sectorOffset)
|
private bool ReadDataNibbles(int sectorOffset)
|
||||||
{
|
{
|
||||||
byte a, x, y;
|
byte a, x, y;
|
||||||
|
|
||||||
y = SecondaryBufferLength;
|
y = SecondaryBufferLength;
|
||||||
a = 0;
|
a = 0;
|
||||||
do // fill and de-nibblize secondary buffer
|
do // fill and de-nibblize secondary buffer
|
||||||
{
|
{
|
||||||
a = _secondaryBuffer[--y] = (byte)(a ^ ReadTranslatedNibble());
|
a = _secondaryBuffer[--y] = (byte)(a ^ ReadTranslatedNibble());
|
||||||
}
|
}
|
||||||
while (y > 0);
|
while (y > 0);
|
||||||
|
|
||||||
do // fill and de-nibblize secondary buffer
|
do // fill and de-nibblize secondary buffer
|
||||||
{
|
{
|
||||||
a = _primaryBuffer[y++] = (byte)(a ^ ReadTranslatedNibble());
|
a = _primaryBuffer[y++] = (byte)(a ^ ReadTranslatedNibble());
|
||||||
}
|
}
|
||||||
while (y != 0);
|
while (y != 0);
|
||||||
|
|
||||||
int checksum = a ^ ReadTranslatedNibble(); // should be 0
|
int checksum = a ^ ReadTranslatedNibble(); // should be 0
|
||||||
|
|
||||||
x = y = 0;
|
x = y = 0;
|
||||||
do // decode data
|
do // decode data
|
||||||
{
|
{
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
{
|
{
|
||||||
x = SecondaryBufferLength;
|
x = SecondaryBufferLength;
|
||||||
}
|
}
|
||||||
a = (byte)((_primaryBuffer[y] << 2) | SwapBits[_secondaryBuffer[--x] & 0x03]);
|
a = (byte)((_primaryBuffer[y] << 2) | SwapBits[_secondaryBuffer[--x] & 0x03]);
|
||||||
_secondaryBuffer[x] >>= 2;
|
_secondaryBuffer[x] >>= 2;
|
||||||
Data[sectorOffset + y] = a;
|
Data[sectorOffset + y] = a;
|
||||||
}
|
}
|
||||||
while (++y != 0);
|
while (++y != 0);
|
||||||
|
|
||||||
return (checksum == 0);
|
return (checksum == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteNibble(int data)
|
private void WriteNibble(int data)
|
||||||
{
|
{
|
||||||
_trackBuffer[_trackOffset++] = (byte)data;
|
_trackBuffer[_trackOffset++] = (byte)data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteNibble(int data, int count)
|
private void WriteNibble(int data, int count)
|
||||||
{
|
{
|
||||||
while (count-- > 0)
|
while (count-- > 0)
|
||||||
{
|
{
|
||||||
WriteNibble(data);
|
WriteNibble(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteNibble44(int data)
|
private void WriteNibble44(int data)
|
||||||
{
|
{
|
||||||
WriteNibble((data >> 1) | 0xAA);
|
WriteNibble((data >> 1) | 0xAA);
|
||||||
WriteNibble(data | 0xAA);
|
WriteNibble(data | 0xAA);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteDataNibbles(int sectorOffset)
|
private void WriteDataNibbles(int sectorOffset)
|
||||||
{
|
{
|
||||||
byte a, x, y;
|
byte a, x, y;
|
||||||
|
|
||||||
for (x = 0; x < SecondaryBufferLength; x++)
|
for (x = 0; x < SecondaryBufferLength; x++)
|
||||||
{
|
{
|
||||||
_secondaryBuffer[x] = 0; // zero secondary buffer
|
_secondaryBuffer[x] = 0; // zero secondary buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
y = 2;
|
y = 2;
|
||||||
do // fill buffers
|
do // fill buffers
|
||||||
{
|
{
|
||||||
x = 0;
|
x = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
a = Data[sectorOffset + --y];
|
a = Data[sectorOffset + --y];
|
||||||
_secondaryBuffer[x] = (byte)((_secondaryBuffer[x] << 2) | SwapBits[a & 0x03]); // b1,b0 -> secondary buffer
|
_secondaryBuffer[x] = (byte)((_secondaryBuffer[x] << 2) | SwapBits[a & 0x03]); // b1,b0 -> secondary buffer
|
||||||
_primaryBuffer[y] = (byte)(a >> 2); // b7-b2 -> primary buffer
|
_primaryBuffer[y] = (byte)(a >> 2); // b7-b2 -> primary buffer
|
||||||
}
|
}
|
||||||
while (++x < SecondaryBufferLength);
|
while (++x < SecondaryBufferLength);
|
||||||
}
|
}
|
||||||
while (y != 0);
|
while (y != 0);
|
||||||
|
|
||||||
y = SecondaryBufferLength;
|
y = SecondaryBufferLength;
|
||||||
do // write secondary buffer
|
do // write secondary buffer
|
||||||
{
|
{
|
||||||
WriteNibble(ByteToNibble[_secondaryBuffer[y] ^ _secondaryBuffer[y - 1]]);
|
WriteNibble(ByteToNibble[_secondaryBuffer[y] ^ _secondaryBuffer[y - 1]]);
|
||||||
}
|
}
|
||||||
while (--y != 0);
|
while (--y != 0);
|
||||||
|
|
||||||
a = _secondaryBuffer[0];
|
a = _secondaryBuffer[0];
|
||||||
do // write primary buffer
|
do // write primary buffer
|
||||||
{
|
{
|
||||||
WriteNibble(ByteToNibble[a ^ _primaryBuffer[y]]);
|
WriteNibble(ByteToNibble[a ^ _primaryBuffer[y]]);
|
||||||
a = _primaryBuffer[y];
|
a = _primaryBuffer[y];
|
||||||
}
|
}
|
||||||
while (++y != 0);
|
while (++y != 0);
|
||||||
|
|
||||||
WriteNibble(ByteToNibble[a]); // data checksum
|
WriteNibble(ByteToNibble[a]); // data checksum
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] _trackBuffer;
|
private byte[] _trackBuffer;
|
||||||
private int _trackOffset;
|
private int _trackOffset;
|
||||||
private byte[] _primaryBuffer = new byte[0x100];
|
private byte[] _primaryBuffer = new byte[0x100];
|
||||||
private const int SecondaryBufferLength = 0x56;
|
private const int SecondaryBufferLength = 0x56;
|
||||||
private byte[] _secondaryBuffer = new byte[SecondaryBufferLength + 1];
|
private byte[] _secondaryBuffer = new byte[SecondaryBufferLength + 1];
|
||||||
private int[] _sectorSkew;
|
private int[] _sectorSkew;
|
||||||
private const int Volume = 0xFE;
|
private const int Volume = 0xFE;
|
||||||
|
|
||||||
private static readonly byte[] SwapBits = { 0, 2, 1, 3 };
|
private static readonly byte[] SwapBits = { 0, 2, 1, 3 };
|
||||||
|
|
||||||
private static readonly int[] SectorSkewNone = new int[SectorCount]
|
private static readonly int[] SectorSkewNone = new int[SectorCount]
|
||||||
{
|
{
|
||||||
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
|
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly int[] SectorSkewDos = new int[SectorCount]
|
private static readonly int[] SectorSkewDos = new int[SectorCount]
|
||||||
{
|
{
|
||||||
0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4, 0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF
|
0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4, 0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly int[] SectorSkewProDos = new int[SectorCount]
|
private static readonly int[] SectorSkewProDos = new int[SectorCount]
|
||||||
{
|
{
|
||||||
0x0, 0x8, 0x1, 0x9, 0x2, 0xA, 0x3, 0xB, 0x4, 0xC, 0x5, 0xD, 0x6, 0xE, 0x7, 0xF
|
0x0, 0x8, 0x1, 0x9, 0x2, 0xA, 0x3, 0xB, 0x4, 0xC, 0x5, 0xD, 0x6, 0xE, 0x7, 0xF
|
||||||
};
|
};
|
||||||
|
|
||||||
private const int SectorSkewCount = 3;
|
private const int SectorSkewCount = 3;
|
||||||
|
|
||||||
private static readonly int[][] SectorSkewMode = new int[SectorSkewCount][]
|
private static readonly int[][] SectorSkewMode = new int[SectorSkewCount][]
|
||||||
{
|
{
|
||||||
SectorSkewNone, SectorSkewDos, SectorSkewProDos
|
SectorSkewNone, SectorSkewDos, SectorSkewProDos
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly byte[] ByteToNibble = new byte[]
|
private static readonly byte[] ByteToNibble = new byte[]
|
||||||
{
|
{
|
||||||
0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6, 0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3,
|
0x96, 0x97, 0x9A, 0x9B, 0x9D, 0x9E, 0x9F, 0xA6, 0xA7, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB3,
|
||||||
0xB4, 0xB5, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xCB, 0xCD, 0xCE, 0xCF, 0xD3,
|
0xB4, 0xB5, 0xB6, 0xB7, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xCB, 0xCD, 0xCE, 0xCF, 0xD3,
|
||||||
0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE5, 0xE6, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC,
|
0xD6, 0xD7, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE5, 0xE6, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC,
|
||||||
0xED, 0xEE, 0xEF, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
0xED, 0xEE, 0xEF, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly byte[] NibbleToByte = new byte[]
|
private static readonly byte[] NibbleToByte = new byte[]
|
||||||
{
|
{
|
||||||
// padding for offset (not used)
|
// padding for offset (not used)
|
||||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
|
||||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
|
||||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
|
||||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95,
|
||||||
|
|
||||||
// nibble translate table
|
// nibble translate table
|
||||||
0x00, 0x01, 0x98, 0x99, 0x02, 0x03, 0x9C, 0x04, 0x05, 0x06,
|
0x00, 0x01, 0x98, 0x99, 0x02, 0x03, 0x9C, 0x04, 0x05, 0x06,
|
||||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x07, 0x08, 0xA8, 0xA9, 0xAA, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
|
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x07, 0x08, 0xA8, 0xA9, 0xAA, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
|
||||||
0xB0, 0xB1, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xB8, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
|
0xB0, 0xB1, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0xB8, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
|
||||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x1B, 0xCC, 0x1C, 0x1D, 0x1E,
|
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x1B, 0xCC, 0x1C, 0x1D, 0x1E,
|
||||||
0xD0, 0xD1, 0xD2, 0x1F, 0xD4, 0xD5, 0x20, 0x21, 0xD8, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
0xD0, 0xD1, 0xD2, 0x1F, 0xD4, 0xD5, 0x20, 0x21, 0xD8, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x29, 0x2A, 0x2B, 0xE8, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
|
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x29, 0x2A, 0x2B, 0xE8, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
|
||||||
0xF0, 0xF1, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0xF8, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
|
0xF0, 0xF1, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0xF8, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,287 +1,287 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
using Jellyfish.Virtu.Services;
|
using Jellyfish.Virtu.Services;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed class DiskIIController : PeripheralCard
|
public sealed class DiskIIController : PeripheralCard
|
||||||
{
|
{
|
||||||
public DiskIIController(Machine machine) :
|
public DiskIIController(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
Drive1 = new DiskIIDrive(machine);
|
Drive1 = new DiskIIDrive(machine);
|
||||||
Drive2 = new DiskIIDrive(machine);
|
Drive2 = new DiskIIDrive(machine);
|
||||||
|
|
||||||
Drives = new Collection<DiskIIDrive> { Drive1, Drive2 };
|
Drives = new Collection<DiskIIDrive> { Drive1, Drive2 };
|
||||||
|
|
||||||
BootDrive = Drive1;
|
BootDrive = Drive1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
StorageService.LoadResource("Roms/DiskII.rom", stream => stream.ReadBlock(_romRegionC1C7));
|
StorageService.LoadResource("Roms/DiskII.rom", stream => stream.ReadBlock(_romRegionC1C7));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
_phaseStates = 0;
|
_phaseStates = 0;
|
||||||
SetMotorOn(false);
|
SetMotorOn(false);
|
||||||
SetDriveNumber(0);
|
SetDriveNumber(0);
|
||||||
_loadMode = false;
|
_loadMode = false;
|
||||||
_writeMode = false;
|
_writeMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadState(BinaryReader reader, Version version)
|
public override void LoadState(BinaryReader reader, Version version)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
_latch = reader.ReadInt32();
|
_latch = reader.ReadInt32();
|
||||||
_phaseStates = reader.ReadInt32();
|
_phaseStates = reader.ReadInt32();
|
||||||
_motorOn = reader.ReadBoolean();
|
_motorOn = reader.ReadBoolean();
|
||||||
_driveNumber = reader.ReadInt32();
|
_driveNumber = reader.ReadInt32();
|
||||||
_loadMode = reader.ReadBoolean();
|
_loadMode = reader.ReadBoolean();
|
||||||
_writeMode = reader.ReadBoolean();
|
_writeMode = reader.ReadBoolean();
|
||||||
_driveSpin = reader.ReadBoolean();
|
_driveSpin = reader.ReadBoolean();
|
||||||
foreach (var drive in Drives)
|
foreach (var drive in Drives)
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage("Loading machine '{0}'", drive.GetType().Name);
|
DebugService.WriteMessage("Loading machine '{0}'", drive.GetType().Name);
|
||||||
drive.LoadState(reader, version);
|
drive.LoadState(reader, version);
|
||||||
//DebugService.WriteMessage("Loaded machine '{0}'", drive.GetType().Name);
|
//DebugService.WriteMessage("Loaded machine '{0}'", drive.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SaveState(BinaryWriter writer)
|
public override void SaveState(BinaryWriter writer)
|
||||||
{
|
{
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(_latch);
|
writer.Write(_latch);
|
||||||
writer.Write(_phaseStates);
|
writer.Write(_phaseStates);
|
||||||
writer.Write(_motorOn);
|
writer.Write(_motorOn);
|
||||||
writer.Write(_driveNumber);
|
writer.Write(_driveNumber);
|
||||||
writer.Write(_loadMode);
|
writer.Write(_loadMode);
|
||||||
writer.Write(_writeMode);
|
writer.Write(_writeMode);
|
||||||
writer.Write(_driveSpin);
|
writer.Write(_driveSpin);
|
||||||
foreach (var drive in Drives)
|
foreach (var drive in Drives)
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage("Saving machine '{0}'", drive.GetType().Name);
|
DebugService.WriteMessage("Saving machine '{0}'", drive.GetType().Name);
|
||||||
drive.SaveState(writer);
|
drive.SaveState(writer);
|
||||||
//DebugService.WriteMessage("Saved machine '{0}'", drive.GetType().Name);
|
//DebugService.WriteMessage("Saved machine '{0}'", drive.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||||
public override int ReadIoRegionC0C0(int address)
|
public override int ReadIoRegionC0C0(int address)
|
||||||
{
|
{
|
||||||
switch (address & 0xF)
|
switch (address & 0xF)
|
||||||
{
|
{
|
||||||
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
|
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
|
||||||
SetPhase(address);
|
SetPhase(address);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x8:
|
case 0x8:
|
||||||
SetMotorOn(false);
|
SetMotorOn(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x9:
|
case 0x9:
|
||||||
SetMotorOn(true);
|
SetMotorOn(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xA:
|
case 0xA:
|
||||||
SetDriveNumber(0);
|
SetDriveNumber(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xB:
|
case 0xB:
|
||||||
SetDriveNumber(1);
|
SetDriveNumber(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC:
|
case 0xC:
|
||||||
_loadMode = false;
|
_loadMode = false;
|
||||||
if (_motorOn)
|
if (_motorOn)
|
||||||
{
|
{
|
||||||
if (!_writeMode)
|
if (!_writeMode)
|
||||||
{
|
{
|
||||||
return _latch = Drives[_driveNumber].Read();
|
return _latch = Drives[_driveNumber].Read();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteLatch();
|
WriteLatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xD:
|
case 0xD:
|
||||||
_loadMode = true;
|
_loadMode = true;
|
||||||
if (_motorOn && !_writeMode)
|
if (_motorOn && !_writeMode)
|
||||||
{
|
{
|
||||||
// write protect is forced if phase 1 is on [F9.7]
|
// write protect is forced if phase 1 is on [F9.7]
|
||||||
_latch &= 0x7F;
|
_latch &= 0x7F;
|
||||||
if (Drives[_driveNumber].IsWriteProtected ||
|
if (Drives[_driveNumber].IsWriteProtected ||
|
||||||
(_phaseStates & Phase1On) != 0)
|
(_phaseStates & Phase1On) != 0)
|
||||||
{
|
{
|
||||||
_latch |= 0x80;
|
_latch |= 0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xE:
|
case 0xE:
|
||||||
_writeMode = false;
|
_writeMode = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xF:
|
case 0xF:
|
||||||
_writeMode = true;
|
_writeMode = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((address & 1) == 0)
|
if ((address & 1) == 0)
|
||||||
{
|
{
|
||||||
// only even addresses return the latch
|
// only even addresses return the latch
|
||||||
if (_motorOn)
|
if (_motorOn)
|
||||||
{
|
{
|
||||||
return _latch;
|
return _latch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// simple hack to fool DOS SAMESLOT drive spin check (usually at $BD34)
|
// simple hack to fool DOS SAMESLOT drive spin check (usually at $BD34)
|
||||||
_driveSpin = !_driveSpin;
|
_driveSpin = !_driveSpin;
|
||||||
return _driveSpin ? 0x7E : 0x7F;
|
return _driveSpin ? 0x7E : 0x7F;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReadFloatingBus();
|
return ReadFloatingBus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int ReadIoRegionC1C7(int address)
|
public override int ReadIoRegionC1C7(int address)
|
||||||
{
|
{
|
||||||
return _romRegionC1C7[address & 0xFF];
|
return _romRegionC1C7[address & 0xFF];
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteIoRegionC0C0(int address, int data)
|
public override void WriteIoRegionC0C0(int address, int data)
|
||||||
{
|
{
|
||||||
switch (address & 0xF)
|
switch (address & 0xF)
|
||||||
{
|
{
|
||||||
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
|
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
|
||||||
SetPhase(address);
|
SetPhase(address);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x8:
|
case 0x8:
|
||||||
SetMotorOn(false);
|
SetMotorOn(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x9:
|
case 0x9:
|
||||||
SetMotorOn(true);
|
SetMotorOn(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xA:
|
case 0xA:
|
||||||
SetDriveNumber(0);
|
SetDriveNumber(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xB:
|
case 0xB:
|
||||||
SetDriveNumber(1);
|
SetDriveNumber(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC:
|
case 0xC:
|
||||||
_loadMode = false;
|
_loadMode = false;
|
||||||
if (_writeMode)
|
if (_writeMode)
|
||||||
{
|
{
|
||||||
WriteLatch();
|
WriteLatch();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xD:
|
case 0xD:
|
||||||
_loadMode = true;
|
_loadMode = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xE:
|
case 0xE:
|
||||||
_writeMode = false;
|
_writeMode = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xF:
|
case 0xF:
|
||||||
_writeMode = true;
|
_writeMode = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_motorOn && _writeMode)
|
if (_motorOn && _writeMode)
|
||||||
{
|
{
|
||||||
if (_loadMode)
|
if (_loadMode)
|
||||||
{
|
{
|
||||||
// any address writes latch for sequencer LD; OE1/2 irrelevant ['323 datasheet]
|
// any address writes latch for sequencer LD; OE1/2 irrelevant ['323 datasheet]
|
||||||
_latch = data;
|
_latch = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteLatch()
|
private void WriteLatch()
|
||||||
{
|
{
|
||||||
// write protect is forced if phase 1 is on [F9.7]
|
// write protect is forced if phase 1 is on [F9.7]
|
||||||
if ((_phaseStates & Phase1On) == 0)
|
if ((_phaseStates & Phase1On) == 0)
|
||||||
{
|
{
|
||||||
Drives[_driveNumber].Write(_latch);
|
Drives[_driveNumber].Write(_latch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Flush()
|
private void Flush()
|
||||||
{
|
{
|
||||||
Drives[_driveNumber].FlushTrack();
|
Drives[_driveNumber].FlushTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetDriveNumber(int driveNumber)
|
private void SetDriveNumber(int driveNumber)
|
||||||
{
|
{
|
||||||
if (_driveNumber != driveNumber)
|
if (_driveNumber != driveNumber)
|
||||||
{
|
{
|
||||||
Flush();
|
Flush();
|
||||||
_driveNumber = driveNumber;
|
_driveNumber = driveNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetMotorOn(bool state)
|
private void SetMotorOn(bool state)
|
||||||
{
|
{
|
||||||
if (_motorOn && !state)
|
if (_motorOn && !state)
|
||||||
{
|
{
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
_motorOn = state;
|
_motorOn = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPhase(int address)
|
private void SetPhase(int address)
|
||||||
{
|
{
|
||||||
int phase = (address >> 1) & 0x3;
|
int phase = (address >> 1) & 0x3;
|
||||||
int state = address & 1;
|
int state = address & 1;
|
||||||
_phaseStates &= ~(1 << phase);
|
_phaseStates &= ~(1 << phase);
|
||||||
_phaseStates |= (state << phase);
|
_phaseStates |= (state << phase);
|
||||||
|
|
||||||
if (_motorOn)
|
if (_motorOn)
|
||||||
{
|
{
|
||||||
Drives[_driveNumber].ApplyPhaseChange(_phaseStates);
|
Drives[_driveNumber].ApplyPhaseChange(_phaseStates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiskIIDrive Drive1 { get; private set; }
|
public DiskIIDrive Drive1 { get; private set; }
|
||||||
public DiskIIDrive Drive2 { get; private set; }
|
public DiskIIDrive Drive2 { get; private set; }
|
||||||
|
|
||||||
public Collection<DiskIIDrive> Drives { get; private set; }
|
public Collection<DiskIIDrive> Drives { get; private set; }
|
||||||
|
|
||||||
public DiskIIDrive BootDrive { get; private set; }
|
public DiskIIDrive BootDrive { get; private set; }
|
||||||
|
|
||||||
private const int Phase0On = 1 << 0;
|
private const int Phase0On = 1 << 0;
|
||||||
private const int Phase1On = 1 << 1;
|
private const int Phase1On = 1 << 1;
|
||||||
private const int Phase2On = 1 << 2;
|
private const int Phase2On = 1 << 2;
|
||||||
private const int Phase3On = 1 << 3;
|
private const int Phase3On = 1 << 3;
|
||||||
|
|
||||||
private int _latch;
|
private int _latch;
|
||||||
private int _phaseStates;
|
private int _phaseStates;
|
||||||
private bool _motorOn;
|
private bool _motorOn;
|
||||||
private int _driveNumber;
|
private int _driveNumber;
|
||||||
private bool _loadMode;
|
private bool _loadMode;
|
||||||
private bool _writeMode;
|
private bool _writeMode;
|
||||||
private bool _driveSpin;
|
private bool _driveSpin;
|
||||||
|
|
||||||
private byte[] _romRegionC1C7 = new byte[0x0100];
|
private byte[] _romRegionC1C7 = new byte[0x0100];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,172 +1,172 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
using Jellyfish.Virtu.Services;
|
using Jellyfish.Virtu.Services;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed class DiskIIDrive : MachineComponent
|
public sealed class DiskIIDrive : MachineComponent
|
||||||
{
|
{
|
||||||
public DiskIIDrive(Machine machine) :
|
public DiskIIDrive(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
DriveArmStepDelta[0] = new int[] { 0, 0, 1, 1, 0, 0, 1, 1, -1, -1, 0, 0, -1, -1, 0, 0 }; // phase 0
|
DriveArmStepDelta[0] = new int[] { 0, 0, 1, 1, 0, 0, 1, 1, -1, -1, 0, 0, -1, -1, 0, 0 }; // phase 0
|
||||||
DriveArmStepDelta[1] = new int[] { 0, -1, 0, -1, 1, 0, 1, 0, 0, -1, 0, -1, 1, 0, 1, 0 }; // phase 1
|
DriveArmStepDelta[1] = new int[] { 0, -1, 0, -1, 1, 0, 1, 0, 0, -1, 0, -1, 1, 0, 1, 0 }; // phase 1
|
||||||
DriveArmStepDelta[2] = new int[] { 0, 0, -1, -1, 0, 0, -1, -1, 1, 1, 0, 0, 1, 1, 0, 0 }; // phase 2
|
DriveArmStepDelta[2] = new int[] { 0, 0, -1, -1, 0, 0, -1, -1, 1, 1, 0, 0, 1, 1, 0, 0 }; // phase 2
|
||||||
DriveArmStepDelta[3] = new int[] { 0, 1, 0, 1, -1, 0, -1, 0, 0, 1, 0, 1, -1, 0, -1, 0 }; // phase 3
|
DriveArmStepDelta[3] = new int[] { 0, 1, 0, 1, -1, 0, -1, 0, 0, 1, 0, 1, -1, 0, -1, 0 }; // phase 3
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadState(BinaryReader reader, Version version)
|
public override void LoadState(BinaryReader reader, Version version)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
_trackLoaded = reader.ReadBoolean();
|
_trackLoaded = reader.ReadBoolean();
|
||||||
_trackChanged = reader.ReadBoolean();
|
_trackChanged = reader.ReadBoolean();
|
||||||
_trackNumber = reader.ReadInt32();
|
_trackNumber = reader.ReadInt32();
|
||||||
_trackOffset = reader.ReadInt32();
|
_trackOffset = reader.ReadInt32();
|
||||||
if (_trackLoaded)
|
if (_trackLoaded)
|
||||||
{
|
{
|
||||||
reader.Read(_trackData, 0, _trackData.Length);
|
reader.Read(_trackData, 0, _trackData.Length);
|
||||||
}
|
}
|
||||||
if (reader.ReadBoolean())
|
if (reader.ReadBoolean())
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage("Loading machine '{0}'", typeof(Disk525).Name);
|
DebugService.WriteMessage("Loading machine '{0}'", typeof(Disk525).Name);
|
||||||
_disk = Disk525.LoadState(reader, version);
|
_disk = Disk525.LoadState(reader, version);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_disk = null;
|
_disk = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SaveState(BinaryWriter writer)
|
public override void SaveState(BinaryWriter writer)
|
||||||
{
|
{
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(_trackLoaded);
|
writer.Write(_trackLoaded);
|
||||||
writer.Write(_trackChanged);
|
writer.Write(_trackChanged);
|
||||||
writer.Write(_trackNumber);
|
writer.Write(_trackNumber);
|
||||||
writer.Write(_trackOffset);
|
writer.Write(_trackOffset);
|
||||||
if (_trackLoaded)
|
if (_trackLoaded)
|
||||||
{
|
{
|
||||||
writer.Write(_trackData);
|
writer.Write(_trackData);
|
||||||
}
|
}
|
||||||
writer.Write(_disk != null);
|
writer.Write(_disk != null);
|
||||||
if (_disk != null)
|
if (_disk != null)
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage("Saving machine '{0}'", _disk.GetType().Name);
|
DebugService.WriteMessage("Saving machine '{0}'", _disk.GetType().Name);
|
||||||
_disk.SaveState(writer);
|
_disk.SaveState(writer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InsertDisk(string name, Stream stream, bool isWriteProtected)
|
public void InsertDisk(string name, Stream stream, bool isWriteProtected)
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage("Inserting disk '{0}'", name);
|
DebugService.WriteMessage("Inserting disk '{0}'", name);
|
||||||
FlushTrack();
|
FlushTrack();
|
||||||
_disk = Disk525.CreateDisk(name, stream, isWriteProtected);
|
_disk = Disk525.CreateDisk(name, stream, isWriteProtected);
|
||||||
_trackLoaded = false;
|
_trackLoaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveDisk()
|
public void RemoveDisk()
|
||||||
{
|
{
|
||||||
if (_disk != null)
|
if (_disk != null)
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage("Removing disk '{0}'", _disk.Name);
|
DebugService.WriteMessage("Removing disk '{0}'", _disk.Name);
|
||||||
_trackLoaded = false;
|
_trackLoaded = false;
|
||||||
_trackChanged = false;
|
_trackChanged = false;
|
||||||
_trackNumber = 0;
|
_trackNumber = 0;
|
||||||
_trackOffset = 0;
|
_trackOffset = 0;
|
||||||
_disk = null;
|
_disk = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyPhaseChange(int phaseState)
|
public void ApplyPhaseChange(int phaseState)
|
||||||
{
|
{
|
||||||
// step the drive head according to stepper magnet changes
|
// step the drive head according to stepper magnet changes
|
||||||
int delta = DriveArmStepDelta[_trackNumber & 0x3][phaseState];
|
int delta = DriveArmStepDelta[_trackNumber & 0x3][phaseState];
|
||||||
if (delta != 0)
|
if (delta != 0)
|
||||||
{
|
{
|
||||||
int newTrackNumber = MathHelpers.Clamp(_trackNumber + delta, 0, TrackNumberMax);
|
int newTrackNumber = MathHelpers.Clamp(_trackNumber + delta, 0, TrackNumberMax);
|
||||||
if (newTrackNumber != _trackNumber)
|
if (newTrackNumber != _trackNumber)
|
||||||
{
|
{
|
||||||
FlushTrack();
|
FlushTrack();
|
||||||
_trackNumber = newTrackNumber;
|
_trackNumber = newTrackNumber;
|
||||||
_trackOffset = 0;
|
_trackOffset = 0;
|
||||||
_trackLoaded = false;
|
_trackLoaded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Read()
|
public int Read()
|
||||||
{
|
{
|
||||||
if (LoadTrack())
|
if (LoadTrack())
|
||||||
{
|
{
|
||||||
int data = _trackData[_trackOffset++];
|
int data = _trackData[_trackOffset++];
|
||||||
if (_trackOffset >= Disk525.TrackSize)
|
if (_trackOffset >= Disk525.TrackSize)
|
||||||
{
|
{
|
||||||
_trackOffset = 0;
|
_trackOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _random.Next(0x01, 0xFF);
|
return _random.Next(0x01, 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(int data)
|
public void Write(int data)
|
||||||
{
|
{
|
||||||
if (LoadTrack())
|
if (LoadTrack())
|
||||||
{
|
{
|
||||||
_trackChanged = true;
|
_trackChanged = true;
|
||||||
_trackData[_trackOffset++] = (byte)data;
|
_trackData[_trackOffset++] = (byte)data;
|
||||||
if (_trackOffset >= Disk525.TrackSize)
|
if (_trackOffset >= Disk525.TrackSize)
|
||||||
{
|
{
|
||||||
_trackOffset = 0;
|
_trackOffset = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadTrack()
|
private bool LoadTrack()
|
||||||
{
|
{
|
||||||
if (!_trackLoaded && (_disk != null))
|
if (!_trackLoaded && (_disk != null))
|
||||||
{
|
{
|
||||||
_disk.ReadTrack(_trackNumber, 0, _trackData);
|
_disk.ReadTrack(_trackNumber, 0, _trackData);
|
||||||
_trackLoaded = true;
|
_trackLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _trackLoaded;
|
return _trackLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FlushTrack()
|
public void FlushTrack()
|
||||||
{
|
{
|
||||||
if (_trackChanged)
|
if (_trackChanged)
|
||||||
{
|
{
|
||||||
_disk.WriteTrack(_trackNumber, 0, _trackData);
|
_disk.WriteTrack(_trackNumber, 0, _trackData);
|
||||||
_trackChanged = false;
|
_trackChanged = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsWriteProtected { get { return _disk.IsWriteProtected; } }
|
public bool IsWriteProtected { get { return _disk.IsWriteProtected; } }
|
||||||
|
|
||||||
private const int TrackNumberMax = 0x44;
|
private const int TrackNumberMax = 0x44;
|
||||||
|
|
||||||
private const int PhaseCount = 4;
|
private const int PhaseCount = 4;
|
||||||
|
|
||||||
private readonly int[][] DriveArmStepDelta = new int[PhaseCount][];
|
private readonly int[][] DriveArmStepDelta = new int[PhaseCount][];
|
||||||
|
|
||||||
private bool _trackLoaded;
|
private bool _trackLoaded;
|
||||||
private bool _trackChanged;
|
private bool _trackChanged;
|
||||||
private int _trackNumber;
|
private int _trackNumber;
|
||||||
private int _trackOffset;
|
private int _trackOffset;
|
||||||
private byte[] _trackData = new byte[Disk525.TrackSize];
|
private byte[] _trackData = new byte[Disk525.TrackSize];
|
||||||
private Disk525 _disk;
|
private Disk525 _disk;
|
||||||
|
|
||||||
private Random _random = new Random();
|
private Random _random = new Random();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed class DiskNib : Disk525
|
public sealed class DiskNib : Disk525
|
||||||
{
|
{
|
||||||
public DiskNib(string name, byte[] data, bool isWriteProtected) :
|
public DiskNib(string name, byte[] data, bool isWriteProtected) :
|
||||||
base(name, data, isWriteProtected)
|
base(name, data, isWriteProtected)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiskNib(string name, Stream stream, bool isWriteProtected) :
|
public DiskNib(string name, Stream stream, bool isWriteProtected) :
|
||||||
base(name, new byte[TrackCount * TrackSize], isWriteProtected)
|
base(name, new byte[TrackCount * TrackSize], isWriteProtected)
|
||||||
{
|
{
|
||||||
if (stream == null)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("stream");
|
throw new ArgumentNullException("stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.ReadBlock(Data);
|
stream.ReadBlock(Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReadTrack(int number, int fraction, byte[] buffer)
|
public override void ReadTrack(int number, int fraction, byte[] buffer)
|
||||||
{
|
{
|
||||||
Buffer.BlockCopy(Data, (number / 2) * TrackSize, buffer, 0, TrackSize);
|
Buffer.BlockCopy(Data, (number / 2) * TrackSize, buffer, 0, TrackSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteTrack(int number, int fraction, byte[] buffer)
|
public override void WriteTrack(int number, int fraction, byte[] buffer)
|
||||||
{
|
{
|
||||||
Buffer.BlockCopy(buffer, 0, Data, (number / 2) * TrackSize, TrackSize);
|
Buffer.BlockCopy(buffer, 0, Data, (number / 2) * TrackSize, TrackSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,370 +1,370 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
using Jellyfish.Virtu.Services;
|
using Jellyfish.Virtu.Services;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed class GamePort : MachineComponent
|
public sealed class GamePort : MachineComponent
|
||||||
{
|
{
|
||||||
public GamePort(Machine machine) :
|
public GamePort(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
_resetPaddle0StrobeEvent = ResetPaddle0StrobeEvent; // cache delegates; avoids garbage
|
_resetPaddle0StrobeEvent = ResetPaddle0StrobeEvent; // cache delegates; avoids garbage
|
||||||
_resetPaddle1StrobeEvent = ResetPaddle1StrobeEvent;
|
_resetPaddle1StrobeEvent = ResetPaddle1StrobeEvent;
|
||||||
_resetPaddle2StrobeEvent = ResetPaddle2StrobeEvent;
|
_resetPaddle2StrobeEvent = ResetPaddle2StrobeEvent;
|
||||||
_resetPaddle3StrobeEvent = ResetPaddle3StrobeEvent;
|
_resetPaddle3StrobeEvent = ResetPaddle3StrobeEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_keyboardService = Machine.Services.GetService<KeyboardService>();
|
_keyboardService = Machine.Services.GetService<KeyboardService>();
|
||||||
_gamePortService = Machine.Services.GetService<GamePortService>();
|
_gamePortService = Machine.Services.GetService<GamePortService>();
|
||||||
|
|
||||||
JoystickDeadZone = 0.4f;
|
JoystickDeadZone = 0.4f;
|
||||||
|
|
||||||
InvertPaddles = true; // Raster Blaster
|
InvertPaddles = true; // Raster Blaster
|
||||||
SwapPaddles = true;
|
SwapPaddles = true;
|
||||||
Joystick0TouchX = 0.35f;
|
Joystick0TouchX = 0.35f;
|
||||||
Joystick0TouchY = 0.6f;
|
Joystick0TouchY = 0.6f;
|
||||||
Joystick0TouchWidth = 0.25f;
|
Joystick0TouchWidth = 0.25f;
|
||||||
Joystick0TouchHeight = 0.4f;
|
Joystick0TouchHeight = 0.4f;
|
||||||
Joystick0TouchRadius = 0.2f;
|
Joystick0TouchRadius = 0.2f;
|
||||||
Joystick0TouchKeepLast = true;
|
Joystick0TouchKeepLast = true;
|
||||||
Button0TouchX = 0;
|
Button0TouchX = 0;
|
||||||
Button0TouchY = 0;
|
Button0TouchY = 0;
|
||||||
Button0TouchWidth = 0.5f;
|
Button0TouchWidth = 0.5f;
|
||||||
Button0TouchHeight = 1;
|
Button0TouchHeight = 1;
|
||||||
Button1TouchX = 0.5f;
|
Button1TouchX = 0.5f;
|
||||||
Button1TouchY = 0;
|
Button1TouchY = 0;
|
||||||
Button1TouchWidth = 0.5f;
|
Button1TouchWidth = 0.5f;
|
||||||
Button1TouchHeight = 1;
|
Button1TouchHeight = 1;
|
||||||
Button2TouchX = 0.75f;
|
Button2TouchX = 0.75f;
|
||||||
Button2TouchY = 0;
|
Button2TouchY = 0;
|
||||||
Button2TouchWidth = 0.25f;
|
Button2TouchWidth = 0.25f;
|
||||||
Button2TouchHeight = 0.25f;
|
Button2TouchHeight = 0.25f;
|
||||||
Button2TouchOrder = 1;
|
Button2TouchOrder = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadState(BinaryReader reader, Version version)
|
public override void LoadState(BinaryReader reader, Version version)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
InvertPaddles = reader.ReadBoolean();
|
InvertPaddles = reader.ReadBoolean();
|
||||||
SwapPaddles = reader.ReadBoolean();
|
SwapPaddles = reader.ReadBoolean();
|
||||||
UseShiftKeyMod = reader.ReadBoolean();
|
UseShiftKeyMod = reader.ReadBoolean();
|
||||||
JoystickDeadZone = reader.ReadSingle();
|
JoystickDeadZone = reader.ReadSingle();
|
||||||
|
|
||||||
UseKeyboard = reader.ReadBoolean();
|
UseKeyboard = reader.ReadBoolean();
|
||||||
Joystick0UpLeftKey = reader.ReadInt32();
|
Joystick0UpLeftKey = reader.ReadInt32();
|
||||||
Joystick0UpKey = reader.ReadInt32();
|
Joystick0UpKey = reader.ReadInt32();
|
||||||
Joystick0UpRightKey = reader.ReadInt32();
|
Joystick0UpRightKey = reader.ReadInt32();
|
||||||
Joystick0LeftKey = reader.ReadInt32();
|
Joystick0LeftKey = reader.ReadInt32();
|
||||||
Joystick0RightKey = reader.ReadInt32();
|
Joystick0RightKey = reader.ReadInt32();
|
||||||
Joystick0DownLeftKey = reader.ReadInt32();
|
Joystick0DownLeftKey = reader.ReadInt32();
|
||||||
Joystick0DownKey = reader.ReadInt32();
|
Joystick0DownKey = reader.ReadInt32();
|
||||||
Joystick0DownRightKey = reader.ReadInt32();
|
Joystick0DownRightKey = reader.ReadInt32();
|
||||||
Joystick1UpLeftKey = reader.ReadInt32();
|
Joystick1UpLeftKey = reader.ReadInt32();
|
||||||
Joystick1UpKey = reader.ReadInt32();
|
Joystick1UpKey = reader.ReadInt32();
|
||||||
Joystick1UpRightKey = reader.ReadInt32();
|
Joystick1UpRightKey = reader.ReadInt32();
|
||||||
Joystick1LeftKey = reader.ReadInt32();
|
Joystick1LeftKey = reader.ReadInt32();
|
||||||
Joystick1RightKey = reader.ReadInt32();
|
Joystick1RightKey = reader.ReadInt32();
|
||||||
Joystick1DownLeftKey = reader.ReadInt32();
|
Joystick1DownLeftKey = reader.ReadInt32();
|
||||||
Joystick1DownKey = reader.ReadInt32();
|
Joystick1DownKey = reader.ReadInt32();
|
||||||
Joystick1DownRightKey = reader.ReadInt32();
|
Joystick1DownRightKey = reader.ReadInt32();
|
||||||
Button0Key = reader.ReadInt32();
|
Button0Key = reader.ReadInt32();
|
||||||
Button1Key = reader.ReadInt32();
|
Button1Key = reader.ReadInt32();
|
||||||
Button2Key = reader.ReadInt32();
|
Button2Key = reader.ReadInt32();
|
||||||
|
|
||||||
UseTouch = reader.ReadBoolean();
|
UseTouch = reader.ReadBoolean();
|
||||||
Joystick0TouchX = reader.ReadSingle();
|
Joystick0TouchX = reader.ReadSingle();
|
||||||
Joystick0TouchY = reader.ReadSingle();
|
Joystick0TouchY = reader.ReadSingle();
|
||||||
Joystick0TouchWidth = reader.ReadSingle();
|
Joystick0TouchWidth = reader.ReadSingle();
|
||||||
Joystick0TouchHeight = reader.ReadSingle();
|
Joystick0TouchHeight = reader.ReadSingle();
|
||||||
Joystick0TouchOrder = reader.ReadInt32();
|
Joystick0TouchOrder = reader.ReadInt32();
|
||||||
Joystick0TouchRadius = reader.ReadSingle();
|
Joystick0TouchRadius = reader.ReadSingle();
|
||||||
Joystick0TouchKeepLast = reader.ReadBoolean();
|
Joystick0TouchKeepLast = reader.ReadBoolean();
|
||||||
Joystick1TouchX = reader.ReadSingle();
|
Joystick1TouchX = reader.ReadSingle();
|
||||||
Joystick1TouchY = reader.ReadSingle();
|
Joystick1TouchY = reader.ReadSingle();
|
||||||
Joystick1TouchWidth = reader.ReadSingle();
|
Joystick1TouchWidth = reader.ReadSingle();
|
||||||
Joystick1TouchHeight = reader.ReadSingle();
|
Joystick1TouchHeight = reader.ReadSingle();
|
||||||
Joystick1TouchOrder = reader.ReadInt32();
|
Joystick1TouchOrder = reader.ReadInt32();
|
||||||
Joystick1TouchRadius = reader.ReadSingle();
|
Joystick1TouchRadius = reader.ReadSingle();
|
||||||
Joystick1TouchKeepLast = reader.ReadBoolean();
|
Joystick1TouchKeepLast = reader.ReadBoolean();
|
||||||
Button0TouchX = reader.ReadSingle();
|
Button0TouchX = reader.ReadSingle();
|
||||||
Button0TouchY = reader.ReadSingle();
|
Button0TouchY = reader.ReadSingle();
|
||||||
Button0TouchWidth = reader.ReadSingle();
|
Button0TouchWidth = reader.ReadSingle();
|
||||||
Button0TouchHeight = reader.ReadSingle();
|
Button0TouchHeight = reader.ReadSingle();
|
||||||
Button0TouchOrder = reader.ReadInt32();
|
Button0TouchOrder = reader.ReadInt32();
|
||||||
Button1TouchX = reader.ReadSingle();
|
Button1TouchX = reader.ReadSingle();
|
||||||
Button1TouchY = reader.ReadSingle();
|
Button1TouchY = reader.ReadSingle();
|
||||||
Button1TouchWidth = reader.ReadSingle();
|
Button1TouchWidth = reader.ReadSingle();
|
||||||
Button1TouchHeight = reader.ReadSingle();
|
Button1TouchHeight = reader.ReadSingle();
|
||||||
Button1TouchOrder = reader.ReadInt32();
|
Button1TouchOrder = reader.ReadInt32();
|
||||||
Button2TouchX = reader.ReadSingle();
|
Button2TouchX = reader.ReadSingle();
|
||||||
Button2TouchY = reader.ReadSingle();
|
Button2TouchY = reader.ReadSingle();
|
||||||
Button2TouchWidth = reader.ReadSingle();
|
Button2TouchWidth = reader.ReadSingle();
|
||||||
Button2TouchHeight = reader.ReadSingle();
|
Button2TouchHeight = reader.ReadSingle();
|
||||||
Button2TouchOrder = reader.ReadInt32();
|
Button2TouchOrder = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SaveState(BinaryWriter writer)
|
public override void SaveState(BinaryWriter writer)
|
||||||
{
|
{
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(InvertPaddles);
|
writer.Write(InvertPaddles);
|
||||||
writer.Write(SwapPaddles);
|
writer.Write(SwapPaddles);
|
||||||
writer.Write(UseShiftKeyMod);
|
writer.Write(UseShiftKeyMod);
|
||||||
writer.Write(JoystickDeadZone);
|
writer.Write(JoystickDeadZone);
|
||||||
|
|
||||||
writer.Write(UseKeyboard);
|
writer.Write(UseKeyboard);
|
||||||
writer.Write(Joystick0UpLeftKey);
|
writer.Write(Joystick0UpLeftKey);
|
||||||
writer.Write(Joystick0UpKey);
|
writer.Write(Joystick0UpKey);
|
||||||
writer.Write(Joystick0UpRightKey);
|
writer.Write(Joystick0UpRightKey);
|
||||||
writer.Write(Joystick0LeftKey);
|
writer.Write(Joystick0LeftKey);
|
||||||
writer.Write(Joystick0RightKey);
|
writer.Write(Joystick0RightKey);
|
||||||
writer.Write(Joystick0DownLeftKey);
|
writer.Write(Joystick0DownLeftKey);
|
||||||
writer.Write(Joystick0DownKey);
|
writer.Write(Joystick0DownKey);
|
||||||
writer.Write(Joystick0DownRightKey);
|
writer.Write(Joystick0DownRightKey);
|
||||||
writer.Write(Joystick1UpLeftKey);
|
writer.Write(Joystick1UpLeftKey);
|
||||||
writer.Write(Joystick1UpKey);
|
writer.Write(Joystick1UpKey);
|
||||||
writer.Write(Joystick1UpRightKey);
|
writer.Write(Joystick1UpRightKey);
|
||||||
writer.Write(Joystick1LeftKey);
|
writer.Write(Joystick1LeftKey);
|
||||||
writer.Write(Joystick1RightKey);
|
writer.Write(Joystick1RightKey);
|
||||||
writer.Write(Joystick1DownLeftKey);
|
writer.Write(Joystick1DownLeftKey);
|
||||||
writer.Write(Joystick1DownKey);
|
writer.Write(Joystick1DownKey);
|
||||||
writer.Write(Joystick1DownRightKey);
|
writer.Write(Joystick1DownRightKey);
|
||||||
writer.Write(Button0Key);
|
writer.Write(Button0Key);
|
||||||
writer.Write(Button1Key);
|
writer.Write(Button1Key);
|
||||||
writer.Write(Button2Key);
|
writer.Write(Button2Key);
|
||||||
|
|
||||||
writer.Write(UseTouch);
|
writer.Write(UseTouch);
|
||||||
writer.Write(Joystick0TouchX);
|
writer.Write(Joystick0TouchX);
|
||||||
writer.Write(Joystick0TouchY);
|
writer.Write(Joystick0TouchY);
|
||||||
writer.Write(Joystick0TouchWidth);
|
writer.Write(Joystick0TouchWidth);
|
||||||
writer.Write(Joystick0TouchHeight);
|
writer.Write(Joystick0TouchHeight);
|
||||||
writer.Write(Joystick0TouchOrder);
|
writer.Write(Joystick0TouchOrder);
|
||||||
writer.Write(Joystick0TouchRadius);
|
writer.Write(Joystick0TouchRadius);
|
||||||
writer.Write(Joystick0TouchKeepLast);
|
writer.Write(Joystick0TouchKeepLast);
|
||||||
writer.Write(Joystick1TouchX);
|
writer.Write(Joystick1TouchX);
|
||||||
writer.Write(Joystick1TouchY);
|
writer.Write(Joystick1TouchY);
|
||||||
writer.Write(Joystick1TouchWidth);
|
writer.Write(Joystick1TouchWidth);
|
||||||
writer.Write(Joystick1TouchHeight);
|
writer.Write(Joystick1TouchHeight);
|
||||||
writer.Write(Joystick1TouchOrder);
|
writer.Write(Joystick1TouchOrder);
|
||||||
writer.Write(Joystick1TouchRadius);
|
writer.Write(Joystick1TouchRadius);
|
||||||
writer.Write(Joystick1TouchKeepLast);
|
writer.Write(Joystick1TouchKeepLast);
|
||||||
writer.Write(Button0TouchX);
|
writer.Write(Button0TouchX);
|
||||||
writer.Write(Button0TouchY);
|
writer.Write(Button0TouchY);
|
||||||
writer.Write(Button0TouchWidth);
|
writer.Write(Button0TouchWidth);
|
||||||
writer.Write(Button0TouchHeight);
|
writer.Write(Button0TouchHeight);
|
||||||
writer.Write(Button0TouchOrder);
|
writer.Write(Button0TouchOrder);
|
||||||
writer.Write(Button1TouchX);
|
writer.Write(Button1TouchX);
|
||||||
writer.Write(Button1TouchY);
|
writer.Write(Button1TouchY);
|
||||||
writer.Write(Button1TouchWidth);
|
writer.Write(Button1TouchWidth);
|
||||||
writer.Write(Button1TouchHeight);
|
writer.Write(Button1TouchHeight);
|
||||||
writer.Write(Button1TouchOrder);
|
writer.Write(Button1TouchOrder);
|
||||||
writer.Write(Button2TouchX);
|
writer.Write(Button2TouchX);
|
||||||
writer.Write(Button2TouchY);
|
writer.Write(Button2TouchY);
|
||||||
writer.Write(Button2TouchWidth);
|
writer.Write(Button2TouchWidth);
|
||||||
writer.Write(Button2TouchHeight);
|
writer.Write(Button2TouchHeight);
|
||||||
writer.Write(Button2TouchOrder);
|
writer.Write(Button2TouchOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ReadButton0()
|
public bool ReadButton0()
|
||||||
{
|
{
|
||||||
return (_gamePortService.IsButton0Down || _keyboardService.IsOpenAppleKeyDown ||
|
return (_gamePortService.IsButton0Down || _keyboardService.IsOpenAppleKeyDown ||
|
||||||
(UseKeyboard && (Button0Key > 0) && _keyboardService.IsKeyDown(Button0Key)));
|
(UseKeyboard && (Button0Key > 0) && _keyboardService.IsKeyDown(Button0Key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ReadButton1()
|
public bool ReadButton1()
|
||||||
{
|
{
|
||||||
return (_gamePortService.IsButton1Down || _keyboardService.IsCloseAppleKeyDown ||
|
return (_gamePortService.IsButton1Down || _keyboardService.IsCloseAppleKeyDown ||
|
||||||
(UseKeyboard && (Button1Key > 0) && _keyboardService.IsKeyDown(Button1Key)));
|
(UseKeyboard && (Button1Key > 0) && _keyboardService.IsKeyDown(Button1Key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ReadButton2()
|
public bool ReadButton2()
|
||||||
{
|
{
|
||||||
return (_gamePortService.IsButton2Down || (UseShiftKeyMod && !_keyboardService.IsShiftKeyDown) || // Shift' [TN9]
|
return (_gamePortService.IsButton2Down || (UseShiftKeyMod && !_keyboardService.IsShiftKeyDown) || // Shift' [TN9]
|
||||||
(UseKeyboard && (Button2Key > 0) && _keyboardService.IsKeyDown(Button2Key)));
|
(UseKeyboard && (Button2Key > 0) && _keyboardService.IsKeyDown(Button2Key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||||
public void TriggerTimers()
|
public void TriggerTimers()
|
||||||
{
|
{
|
||||||
int paddle0 = _gamePortService.Paddle0;
|
int paddle0 = _gamePortService.Paddle0;
|
||||||
int paddle1 = _gamePortService.Paddle1;
|
int paddle1 = _gamePortService.Paddle1;
|
||||||
int paddle2 = _gamePortService.Paddle2;
|
int paddle2 = _gamePortService.Paddle2;
|
||||||
int paddle3 = _gamePortService.Paddle3;
|
int paddle3 = _gamePortService.Paddle3;
|
||||||
|
|
||||||
if (UseKeyboard) // override
|
if (UseKeyboard) // override
|
||||||
{
|
{
|
||||||
if (((Joystick0UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0UpLeftKey)) ||
|
if (((Joystick0UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0UpLeftKey)) ||
|
||||||
((Joystick0LeftKey > 0) && _keyboardService.IsKeyDown(Joystick0LeftKey)) ||
|
((Joystick0LeftKey > 0) && _keyboardService.IsKeyDown(Joystick0LeftKey)) ||
|
||||||
((Joystick0DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0DownLeftKey)))
|
((Joystick0DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0DownLeftKey)))
|
||||||
{
|
{
|
||||||
paddle0 -= PaddleScale;
|
paddle0 -= PaddleScale;
|
||||||
}
|
}
|
||||||
if (((Joystick0UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick0UpRightKey)) ||
|
if (((Joystick0UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick0UpRightKey)) ||
|
||||||
((Joystick0RightKey > 0) && _keyboardService.IsKeyDown(Joystick0RightKey)) ||
|
((Joystick0RightKey > 0) && _keyboardService.IsKeyDown(Joystick0RightKey)) ||
|
||||||
((Joystick0DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick0DownRightKey)))
|
((Joystick0DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick0DownRightKey)))
|
||||||
{
|
{
|
||||||
paddle0 += PaddleScale;
|
paddle0 += PaddleScale;
|
||||||
}
|
}
|
||||||
if (((Joystick0UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0UpLeftKey)) ||
|
if (((Joystick0UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0UpLeftKey)) ||
|
||||||
((Joystick0UpKey > 0) && _keyboardService.IsKeyDown(Joystick0UpKey)) ||
|
((Joystick0UpKey > 0) && _keyboardService.IsKeyDown(Joystick0UpKey)) ||
|
||||||
((Joystick0UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick0UpRightKey)))
|
((Joystick0UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick0UpRightKey)))
|
||||||
{
|
{
|
||||||
paddle1 -= PaddleScale;
|
paddle1 -= PaddleScale;
|
||||||
}
|
}
|
||||||
if (((Joystick0DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0DownLeftKey)) ||
|
if (((Joystick0DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick0DownLeftKey)) ||
|
||||||
((Joystick0DownKey > 0) && _keyboardService.IsKeyDown(Joystick0DownKey)) ||
|
((Joystick0DownKey > 0) && _keyboardService.IsKeyDown(Joystick0DownKey)) ||
|
||||||
((Joystick0DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick0DownRightKey)))
|
((Joystick0DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick0DownRightKey)))
|
||||||
{
|
{
|
||||||
paddle1 += PaddleScale;
|
paddle1 += PaddleScale;
|
||||||
}
|
}
|
||||||
if (((Joystick1UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1UpLeftKey)) ||
|
if (((Joystick1UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1UpLeftKey)) ||
|
||||||
((Joystick1LeftKey > 0) && _keyboardService.IsKeyDown(Joystick1LeftKey)) ||
|
((Joystick1LeftKey > 0) && _keyboardService.IsKeyDown(Joystick1LeftKey)) ||
|
||||||
((Joystick1DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1DownLeftKey)))
|
((Joystick1DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1DownLeftKey)))
|
||||||
{
|
{
|
||||||
paddle2 -= PaddleScale;
|
paddle2 -= PaddleScale;
|
||||||
}
|
}
|
||||||
if (((Joystick1UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick1UpRightKey)) ||
|
if (((Joystick1UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick1UpRightKey)) ||
|
||||||
((Joystick1RightKey > 0) && _keyboardService.IsKeyDown(Joystick1RightKey)) ||
|
((Joystick1RightKey > 0) && _keyboardService.IsKeyDown(Joystick1RightKey)) ||
|
||||||
((Joystick1DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick1DownRightKey)))
|
((Joystick1DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick1DownRightKey)))
|
||||||
{
|
{
|
||||||
paddle2 += PaddleScale;
|
paddle2 += PaddleScale;
|
||||||
}
|
}
|
||||||
if (((Joystick1UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1UpLeftKey)) ||
|
if (((Joystick1UpLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1UpLeftKey)) ||
|
||||||
((Joystick1UpKey > 0) && _keyboardService.IsKeyDown(Joystick1UpKey)) ||
|
((Joystick1UpKey > 0) && _keyboardService.IsKeyDown(Joystick1UpKey)) ||
|
||||||
((Joystick1UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick1UpRightKey)))
|
((Joystick1UpRightKey > 0) && _keyboardService.IsKeyDown(Joystick1UpRightKey)))
|
||||||
{
|
{
|
||||||
paddle3 -= PaddleScale;
|
paddle3 -= PaddleScale;
|
||||||
}
|
}
|
||||||
if (((Joystick1DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1DownLeftKey)) ||
|
if (((Joystick1DownLeftKey > 0) && _keyboardService.IsKeyDown(Joystick1DownLeftKey)) ||
|
||||||
((Joystick1DownKey > 0) && _keyboardService.IsKeyDown(Joystick1DownKey)) ||
|
((Joystick1DownKey > 0) && _keyboardService.IsKeyDown(Joystick1DownKey)) ||
|
||||||
((Joystick1DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick1DownRightKey)))
|
((Joystick1DownRightKey > 0) && _keyboardService.IsKeyDown(Joystick1DownRightKey)))
|
||||||
{
|
{
|
||||||
paddle3 += PaddleScale;
|
paddle3 += PaddleScale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (InvertPaddles)
|
if (InvertPaddles)
|
||||||
{
|
{
|
||||||
paddle0 = 2 * PaddleScale - paddle0;
|
paddle0 = 2 * PaddleScale - paddle0;
|
||||||
paddle1 = 2 * PaddleScale - paddle1;
|
paddle1 = 2 * PaddleScale - paddle1;
|
||||||
paddle2 = 2 * PaddleScale - paddle2;
|
paddle2 = 2 * PaddleScale - paddle2;
|
||||||
paddle3 = 2 * PaddleScale - paddle3;
|
paddle3 = 2 * PaddleScale - paddle3;
|
||||||
}
|
}
|
||||||
|
|
||||||
Paddle0Strobe = true;
|
Paddle0Strobe = true;
|
||||||
Paddle1Strobe = true;
|
Paddle1Strobe = true;
|
||||||
Paddle2Strobe = true;
|
Paddle2Strobe = true;
|
||||||
Paddle3Strobe = true;
|
Paddle3Strobe = true;
|
||||||
|
|
||||||
Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle1 : paddle0) * CyclesPerValue, _resetPaddle0StrobeEvent); // [7-29]
|
Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle1 : paddle0) * CyclesPerValue, _resetPaddle0StrobeEvent); // [7-29]
|
||||||
Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle0 : paddle1) * CyclesPerValue, _resetPaddle1StrobeEvent);
|
Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle0 : paddle1) * CyclesPerValue, _resetPaddle1StrobeEvent);
|
||||||
Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle3 : paddle2) * CyclesPerValue, _resetPaddle2StrobeEvent);
|
Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle3 : paddle2) * CyclesPerValue, _resetPaddle2StrobeEvent);
|
||||||
Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle2 : paddle3) * CyclesPerValue, _resetPaddle3StrobeEvent);
|
Machine.Events.AddEvent(MathHelpers.ClampByte(SwapPaddles ? paddle2 : paddle3) * CyclesPerValue, _resetPaddle3StrobeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetPaddle0StrobeEvent()
|
private void ResetPaddle0StrobeEvent()
|
||||||
{
|
{
|
||||||
Paddle0Strobe = false;
|
Paddle0Strobe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetPaddle1StrobeEvent()
|
private void ResetPaddle1StrobeEvent()
|
||||||
{
|
{
|
||||||
Paddle1Strobe = false;
|
Paddle1Strobe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetPaddle2StrobeEvent()
|
private void ResetPaddle2StrobeEvent()
|
||||||
{
|
{
|
||||||
Paddle2Strobe = false;
|
Paddle2Strobe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetPaddle3StrobeEvent()
|
private void ResetPaddle3StrobeEvent()
|
||||||
{
|
{
|
||||||
Paddle3Strobe = false;
|
Paddle3Strobe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public const int PaddleScale = 128;
|
public const int PaddleScale = 128;
|
||||||
|
|
||||||
public bool InvertPaddles { get; set; }
|
public bool InvertPaddles { get; set; }
|
||||||
public bool SwapPaddles { get; set; }
|
public bool SwapPaddles { get; set; }
|
||||||
public bool UseShiftKeyMod { get; set; }
|
public bool UseShiftKeyMod { get; set; }
|
||||||
public float JoystickDeadZone { get; set; }
|
public float JoystickDeadZone { get; set; }
|
||||||
|
|
||||||
public bool UseKeyboard { get; set; }
|
public bool UseKeyboard { get; set; }
|
||||||
public int Joystick0UpLeftKey { get; set; }
|
public int Joystick0UpLeftKey { get; set; }
|
||||||
public int Joystick0UpKey { get; set; }
|
public int Joystick0UpKey { get; set; }
|
||||||
public int Joystick0UpRightKey { get; set; }
|
public int Joystick0UpRightKey { get; set; }
|
||||||
public int Joystick0LeftKey { get; set; }
|
public int Joystick0LeftKey { get; set; }
|
||||||
public int Joystick0RightKey { get; set; }
|
public int Joystick0RightKey { get; set; }
|
||||||
public int Joystick0DownLeftKey { get; set; }
|
public int Joystick0DownLeftKey { get; set; }
|
||||||
public int Joystick0DownKey { get; set; }
|
public int Joystick0DownKey { get; set; }
|
||||||
public int Joystick0DownRightKey { get; set; }
|
public int Joystick0DownRightKey { get; set; }
|
||||||
public int Joystick1UpLeftKey { get; set; }
|
public int Joystick1UpLeftKey { get; set; }
|
||||||
public int Joystick1UpKey { get; set; }
|
public int Joystick1UpKey { get; set; }
|
||||||
public int Joystick1UpRightKey { get; set; }
|
public int Joystick1UpRightKey { get; set; }
|
||||||
public int Joystick1LeftKey { get; set; }
|
public int Joystick1LeftKey { get; set; }
|
||||||
public int Joystick1RightKey { get; set; }
|
public int Joystick1RightKey { get; set; }
|
||||||
public int Joystick1DownLeftKey { get; set; }
|
public int Joystick1DownLeftKey { get; set; }
|
||||||
public int Joystick1DownKey { get; set; }
|
public int Joystick1DownKey { get; set; }
|
||||||
public int Joystick1DownRightKey { get; set; }
|
public int Joystick1DownRightKey { get; set; }
|
||||||
public int Button0Key { get; set; }
|
public int Button0Key { get; set; }
|
||||||
public int Button1Key { get; set; }
|
public int Button1Key { get; set; }
|
||||||
public int Button2Key { get; set; }
|
public int Button2Key { get; set; }
|
||||||
|
|
||||||
public bool UseTouch { get; set; }
|
public bool UseTouch { get; set; }
|
||||||
public float Joystick0TouchX { get; set; }
|
public float Joystick0TouchX { get; set; }
|
||||||
public float Joystick0TouchY { get; set; }
|
public float Joystick0TouchY { get; set; }
|
||||||
public float Joystick0TouchWidth { get; set; }
|
public float Joystick0TouchWidth { get; set; }
|
||||||
public float Joystick0TouchHeight { get; set; }
|
public float Joystick0TouchHeight { get; set; }
|
||||||
public int Joystick0TouchOrder { get; set; }
|
public int Joystick0TouchOrder { get; set; }
|
||||||
public float Joystick0TouchRadius { get; set; }
|
public float Joystick0TouchRadius { get; set; }
|
||||||
public bool Joystick0TouchKeepLast { get; set; }
|
public bool Joystick0TouchKeepLast { get; set; }
|
||||||
public float Joystick1TouchX { get; set; }
|
public float Joystick1TouchX { get; set; }
|
||||||
public float Joystick1TouchY { get; set; }
|
public float Joystick1TouchY { get; set; }
|
||||||
public float Joystick1TouchWidth { get; set; }
|
public float Joystick1TouchWidth { get; set; }
|
||||||
public float Joystick1TouchHeight { get; set; }
|
public float Joystick1TouchHeight { get; set; }
|
||||||
public int Joystick1TouchOrder { get; set; }
|
public int Joystick1TouchOrder { get; set; }
|
||||||
public float Joystick1TouchRadius { get; set; }
|
public float Joystick1TouchRadius { get; set; }
|
||||||
public bool Joystick1TouchKeepLast { get; set; }
|
public bool Joystick1TouchKeepLast { get; set; }
|
||||||
public float Button0TouchX { get; set; }
|
public float Button0TouchX { get; set; }
|
||||||
public float Button0TouchY { get; set; }
|
public float Button0TouchY { get; set; }
|
||||||
public float Button0TouchWidth { get; set; }
|
public float Button0TouchWidth { get; set; }
|
||||||
public float Button0TouchHeight { get; set; }
|
public float Button0TouchHeight { get; set; }
|
||||||
public int Button0TouchOrder { get; set; }
|
public int Button0TouchOrder { get; set; }
|
||||||
public float Button1TouchX { get; set; }
|
public float Button1TouchX { get; set; }
|
||||||
public float Button1TouchY { get; set; }
|
public float Button1TouchY { get; set; }
|
||||||
public float Button1TouchWidth { get; set; }
|
public float Button1TouchWidth { get; set; }
|
||||||
public float Button1TouchHeight { get; set; }
|
public float Button1TouchHeight { get; set; }
|
||||||
public int Button1TouchOrder { get; set; }
|
public int Button1TouchOrder { get; set; }
|
||||||
public float Button2TouchX { get; set; }
|
public float Button2TouchX { get; set; }
|
||||||
public float Button2TouchY { get; set; }
|
public float Button2TouchY { get; set; }
|
||||||
public float Button2TouchWidth { get; set; }
|
public float Button2TouchWidth { get; set; }
|
||||||
public float Button2TouchHeight { get; set; }
|
public float Button2TouchHeight { get; set; }
|
||||||
public int Button2TouchOrder { get; set; }
|
public int Button2TouchOrder { get; set; }
|
||||||
|
|
||||||
public bool Paddle0Strobe { get; private set; }
|
public bool Paddle0Strobe { get; private set; }
|
||||||
public bool Paddle1Strobe { get; private set; }
|
public bool Paddle1Strobe { get; private set; }
|
||||||
public bool Paddle2Strobe { get; private set; }
|
public bool Paddle2Strobe { get; private set; }
|
||||||
public bool Paddle3Strobe { get; private set; }
|
public bool Paddle3Strobe { get; private set; }
|
||||||
|
|
||||||
private const int CyclesPerValue = 11;
|
private const int CyclesPerValue = 11;
|
||||||
|
|
||||||
private Action _resetPaddle0StrobeEvent;
|
private Action _resetPaddle0StrobeEvent;
|
||||||
private Action _resetPaddle1StrobeEvent;
|
private Action _resetPaddle1StrobeEvent;
|
||||||
private Action _resetPaddle2StrobeEvent;
|
private Action _resetPaddle2StrobeEvent;
|
||||||
private Action _resetPaddle3StrobeEvent;
|
private Action _resetPaddle3StrobeEvent;
|
||||||
|
|
||||||
private KeyboardService _keyboardService;
|
private KeyboardService _keyboardService;
|
||||||
private GamePortService _gamePortService;
|
private GamePortService _gamePortService;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
|
[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2012
|
# Visual Studio 2012
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "..\Library\Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "..\Library\Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Silverlight", "Silverlight\Jellyfish.Virtu.Silverlight.csproj", "{F8DB6D3A-807D-4E2D-92D5-469273E088DA}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Silverlight", "Silverlight\Jellyfish.Virtu.Silverlight.csproj", "{F8DB6D3A-807D-4E2D-92D5-469273E088DA}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Wpf", "Wpf\Jellyfish.Virtu.Wpf.csproj", "{C152D47E-BBC1-4C35-8646-465180720A72}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Wpf", "Wpf\Jellyfish.Virtu.Wpf.csproj", "{C152D47E-BBC1-4C35-8646-465180720A72}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.Build.0 = Release|Any CPU
|
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -1,120 +1,120 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Jellyfish.Virtu.Services;
|
using Jellyfish.Virtu.Services;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed class Keyboard : MachineComponent
|
public sealed class Keyboard : MachineComponent
|
||||||
{
|
{
|
||||||
public Keyboard(Machine machine) :
|
public Keyboard(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_keyboardService = Machine.Services.GetService<KeyboardService>();
|
_keyboardService = Machine.Services.GetService<KeyboardService>();
|
||||||
|
|
||||||
UseGamePort = true; // Raster Blaster
|
UseGamePort = true; // Raster Blaster
|
||||||
Button2Key = ' ';
|
Button2Key = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadState(BinaryReader reader, Version version)
|
public override void LoadState(BinaryReader reader, Version version)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
DisableResetKey = reader.ReadBoolean();
|
DisableResetKey = reader.ReadBoolean();
|
||||||
|
|
||||||
UseGamePort = reader.ReadBoolean();
|
UseGamePort = reader.ReadBoolean();
|
||||||
Joystick0UpLeftKey = reader.ReadInt32();
|
Joystick0UpLeftKey = reader.ReadInt32();
|
||||||
Joystick0UpKey = reader.ReadInt32();
|
Joystick0UpKey = reader.ReadInt32();
|
||||||
Joystick0UpRightKey = reader.ReadInt32();
|
Joystick0UpRightKey = reader.ReadInt32();
|
||||||
Joystick0LeftKey = reader.ReadInt32();
|
Joystick0LeftKey = reader.ReadInt32();
|
||||||
Joystick0RightKey = reader.ReadInt32();
|
Joystick0RightKey = reader.ReadInt32();
|
||||||
Joystick0DownLeftKey = reader.ReadInt32();
|
Joystick0DownLeftKey = reader.ReadInt32();
|
||||||
Joystick0DownKey = reader.ReadInt32();
|
Joystick0DownKey = reader.ReadInt32();
|
||||||
Joystick0DownRightKey = reader.ReadInt32();
|
Joystick0DownRightKey = reader.ReadInt32();
|
||||||
Joystick1UpLeftKey = reader.ReadInt32();
|
Joystick1UpLeftKey = reader.ReadInt32();
|
||||||
Joystick1UpKey = reader.ReadInt32();
|
Joystick1UpKey = reader.ReadInt32();
|
||||||
Joystick1UpRightKey = reader.ReadInt32();
|
Joystick1UpRightKey = reader.ReadInt32();
|
||||||
Joystick1LeftKey = reader.ReadInt32();
|
Joystick1LeftKey = reader.ReadInt32();
|
||||||
Joystick1RightKey = reader.ReadInt32();
|
Joystick1RightKey = reader.ReadInt32();
|
||||||
Joystick1DownLeftKey = reader.ReadInt32();
|
Joystick1DownLeftKey = reader.ReadInt32();
|
||||||
Joystick1DownKey = reader.ReadInt32();
|
Joystick1DownKey = reader.ReadInt32();
|
||||||
Joystick1DownRightKey = reader.ReadInt32();
|
Joystick1DownRightKey = reader.ReadInt32();
|
||||||
Button0Key = reader.ReadInt32();
|
Button0Key = reader.ReadInt32();
|
||||||
Button1Key = reader.ReadInt32();
|
Button1Key = reader.ReadInt32();
|
||||||
Button2Key = reader.ReadInt32();
|
Button2Key = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SaveState(BinaryWriter writer)
|
public override void SaveState(BinaryWriter writer)
|
||||||
{
|
{
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(DisableResetKey);
|
writer.Write(DisableResetKey);
|
||||||
|
|
||||||
writer.Write(UseGamePort);
|
writer.Write(UseGamePort);
|
||||||
writer.Write(Joystick0UpLeftKey);
|
writer.Write(Joystick0UpLeftKey);
|
||||||
writer.Write(Joystick0UpKey);
|
writer.Write(Joystick0UpKey);
|
||||||
writer.Write(Joystick0UpRightKey);
|
writer.Write(Joystick0UpRightKey);
|
||||||
writer.Write(Joystick0LeftKey);
|
writer.Write(Joystick0LeftKey);
|
||||||
writer.Write(Joystick0RightKey);
|
writer.Write(Joystick0RightKey);
|
||||||
writer.Write(Joystick0DownLeftKey);
|
writer.Write(Joystick0DownLeftKey);
|
||||||
writer.Write(Joystick0DownKey);
|
writer.Write(Joystick0DownKey);
|
||||||
writer.Write(Joystick0DownRightKey);
|
writer.Write(Joystick0DownRightKey);
|
||||||
writer.Write(Joystick1UpLeftKey);
|
writer.Write(Joystick1UpLeftKey);
|
||||||
writer.Write(Joystick1UpKey);
|
writer.Write(Joystick1UpKey);
|
||||||
writer.Write(Joystick1UpRightKey);
|
writer.Write(Joystick1UpRightKey);
|
||||||
writer.Write(Joystick1LeftKey);
|
writer.Write(Joystick1LeftKey);
|
||||||
writer.Write(Joystick1RightKey);
|
writer.Write(Joystick1RightKey);
|
||||||
writer.Write(Joystick1DownLeftKey);
|
writer.Write(Joystick1DownLeftKey);
|
||||||
writer.Write(Joystick1DownKey);
|
writer.Write(Joystick1DownKey);
|
||||||
writer.Write(Joystick1DownRightKey);
|
writer.Write(Joystick1DownRightKey);
|
||||||
writer.Write(Button0Key);
|
writer.Write(Button0Key);
|
||||||
writer.Write(Button1Key);
|
writer.Write(Button1Key);
|
||||||
writer.Write(Button2Key);
|
writer.Write(Button2Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetStrobe()
|
public void ResetStrobe()
|
||||||
{
|
{
|
||||||
Strobe = false;
|
Strobe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DisableResetKey { get; set; }
|
public bool DisableResetKey { get; set; }
|
||||||
|
|
||||||
public bool UseGamePort { get; set; }
|
public bool UseGamePort { get; set; }
|
||||||
public int Joystick0UpLeftKey { get; set; }
|
public int Joystick0UpLeftKey { get; set; }
|
||||||
public int Joystick0UpKey { get; set; }
|
public int Joystick0UpKey { get; set; }
|
||||||
public int Joystick0UpRightKey { get; set; }
|
public int Joystick0UpRightKey { get; set; }
|
||||||
public int Joystick0LeftKey { get; set; }
|
public int Joystick0LeftKey { get; set; }
|
||||||
public int Joystick0RightKey { get; set; }
|
public int Joystick0RightKey { get; set; }
|
||||||
public int Joystick0DownLeftKey { get; set; }
|
public int Joystick0DownLeftKey { get; set; }
|
||||||
public int Joystick0DownKey { get; set; }
|
public int Joystick0DownKey { get; set; }
|
||||||
public int Joystick0DownRightKey { get; set; }
|
public int Joystick0DownRightKey { get; set; }
|
||||||
public int Joystick1UpLeftKey { get; set; }
|
public int Joystick1UpLeftKey { get; set; }
|
||||||
public int Joystick1UpKey { get; set; }
|
public int Joystick1UpKey { get; set; }
|
||||||
public int Joystick1UpRightKey { get; set; }
|
public int Joystick1UpRightKey { get; set; }
|
||||||
public int Joystick1LeftKey { get; set; }
|
public int Joystick1LeftKey { get; set; }
|
||||||
public int Joystick1RightKey { get; set; }
|
public int Joystick1RightKey { get; set; }
|
||||||
public int Joystick1DownLeftKey { get; set; }
|
public int Joystick1DownLeftKey { get; set; }
|
||||||
public int Joystick1DownKey { get; set; }
|
public int Joystick1DownKey { get; set; }
|
||||||
public int Joystick1DownRightKey { get; set; }
|
public int Joystick1DownRightKey { get; set; }
|
||||||
public int Button0Key { get; set; }
|
public int Button0Key { get; set; }
|
||||||
public int Button1Key { get; set; }
|
public int Button1Key { get; set; }
|
||||||
public int Button2Key { get; set; }
|
public int Button2Key { get; set; }
|
||||||
|
|
||||||
public bool IsAnyKeyDown { get { return _keyboardService.IsAnyKeyDown; } }
|
public bool IsAnyKeyDown { get { return _keyboardService.IsAnyKeyDown; } }
|
||||||
public int Latch { get { return _latch; } set { _latch = value; Strobe = true; } }
|
public int Latch { get { return _latch; } set { _latch = value; Strobe = true; } }
|
||||||
public bool Strobe { get; private set; }
|
public bool Strobe { get; private set; }
|
||||||
|
|
||||||
private KeyboardService _keyboardService;
|
private KeyboardService _keyboardService;
|
||||||
|
|
||||||
private int _latch;
|
private int _latch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
546
Virtu/Machine.cs
546
Virtu/Machine.cs
|
@ -1,273 +1,273 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Jellyfish.Virtu.Services;
|
using Jellyfish.Virtu.Services;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public enum MachineState { Stopped = 0, Starting, Running, Pausing, Paused, Stopping }
|
public enum MachineState { Stopped = 0, Starting, Running, Pausing, Paused, Stopping }
|
||||||
|
|
||||||
public sealed class Machine : IDisposable
|
public sealed class Machine : IDisposable
|
||||||
{
|
{
|
||||||
public Machine()
|
public Machine()
|
||||||
{
|
{
|
||||||
Events = new MachineEvents();
|
Events = new MachineEvents();
|
||||||
Services = new MachineServices();
|
Services = new MachineServices();
|
||||||
|
|
||||||
Cpu = new Cpu(this);
|
Cpu = new Cpu(this);
|
||||||
Memory = new Memory(this);
|
Memory = new Memory(this);
|
||||||
Keyboard = new Keyboard(this);
|
Keyboard = new Keyboard(this);
|
||||||
GamePort = new GamePort(this);
|
GamePort = new GamePort(this);
|
||||||
Cassette = new Cassette(this);
|
Cassette = new Cassette(this);
|
||||||
Speaker = new Speaker(this);
|
Speaker = new Speaker(this);
|
||||||
Video = new Video(this);
|
Video = new Video(this);
|
||||||
NoSlotClock = new NoSlotClock(this);
|
NoSlotClock = new NoSlotClock(this);
|
||||||
|
|
||||||
var emptySlot = new PeripheralCard(this);
|
var emptySlot = new PeripheralCard(this);
|
||||||
Slot1 = emptySlot;
|
Slot1 = emptySlot;
|
||||||
Slot2 = emptySlot;
|
Slot2 = emptySlot;
|
||||||
Slot3 = emptySlot;
|
Slot3 = emptySlot;
|
||||||
Slot4 = emptySlot;
|
Slot4 = emptySlot;
|
||||||
Slot5 = emptySlot;
|
Slot5 = emptySlot;
|
||||||
Slot6 = new DiskIIController(this);
|
Slot6 = new DiskIIController(this);
|
||||||
Slot7 = emptySlot;
|
Slot7 = emptySlot;
|
||||||
|
|
||||||
Slots = new Collection<PeripheralCard> { null, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
|
Slots = new Collection<PeripheralCard> { null, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
|
||||||
Components = new Collection<MachineComponent> { Cpu, Memory, Keyboard, GamePort, Cassette, Speaker, Video, NoSlotClock, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
|
Components = new Collection<MachineComponent> { Cpu, Memory, Keyboard, GamePort, Cassette, Speaker, Video, NoSlotClock, Slot1, Slot2, Slot3, Slot4, Slot5, Slot6, Slot7 };
|
||||||
|
|
||||||
BootDiskII = Slots.OfType<DiskIIController>().Last();
|
BootDiskII = Slots.OfType<DiskIIController>().Last();
|
||||||
|
|
||||||
Thread = new Thread(Run) { Name = "Machine" };
|
Thread = new Thread(Run) { Name = "Machine" };
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_pauseEvent.Close();
|
_pauseEvent.Close();
|
||||||
_unpauseEvent.Close();
|
_unpauseEvent.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
foreach (var component in Components)
|
foreach (var component in Components)
|
||||||
{
|
{
|
||||||
_debugService.WriteMessage("Resetting machine '{0}'", component.GetType().Name);
|
_debugService.WriteMessage("Resetting machine '{0}'", component.GetType().Name);
|
||||||
component.Reset();
|
component.Reset();
|
||||||
//_debugService.WriteMessage("Reset machine '{0}'", component.GetType().Name);
|
//_debugService.WriteMessage("Reset machine '{0}'", component.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
_debugService = Services.GetService<DebugService>();
|
_debugService = Services.GetService<DebugService>();
|
||||||
_storageService = Services.GetService<StorageService>();
|
_storageService = Services.GetService<StorageService>();
|
||||||
|
|
||||||
_debugService.WriteMessage("Starting machine");
|
_debugService.WriteMessage("Starting machine");
|
||||||
State = MachineState.Starting;
|
State = MachineState.Starting;
|
||||||
Thread.Start();
|
Thread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
||||||
public void Pause()
|
public void Pause()
|
||||||
{
|
{
|
||||||
_debugService.WriteMessage("Pausing machine");
|
_debugService.WriteMessage("Pausing machine");
|
||||||
State = MachineState.Pausing;
|
State = MachineState.Pausing;
|
||||||
_pauseEvent.WaitOne();
|
_pauseEvent.WaitOne();
|
||||||
State = MachineState.Paused;
|
State = MachineState.Paused;
|
||||||
_debugService.WriteMessage("Paused machine");
|
_debugService.WriteMessage("Paused machine");
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
||||||
public void Unpause()
|
public void Unpause()
|
||||||
{
|
{
|
||||||
_debugService.WriteMessage("Running machine");
|
_debugService.WriteMessage("Running machine");
|
||||||
State = MachineState.Running;
|
State = MachineState.Running;
|
||||||
_unpauseEvent.Set();
|
_unpauseEvent.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
_debugService.WriteMessage("Stopping machine");
|
_debugService.WriteMessage("Stopping machine");
|
||||||
State = MachineState.Stopping;
|
State = MachineState.Stopping;
|
||||||
_unpauseEvent.Set();
|
_unpauseEvent.Set();
|
||||||
if (Thread.IsAlive)
|
if (Thread.IsAlive)
|
||||||
{
|
{
|
||||||
Thread.Join();
|
Thread.Join();
|
||||||
}
|
}
|
||||||
State = MachineState.Stopped;
|
State = MachineState.Stopped;
|
||||||
_debugService.WriteMessage("Stopped machine");
|
_debugService.WriteMessage("Stopped machine");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
foreach (var component in Components)
|
foreach (var component in Components)
|
||||||
{
|
{
|
||||||
_debugService.WriteMessage("Initializing machine '{0}'", component.GetType().Name);
|
_debugService.WriteMessage("Initializing machine '{0}'", component.GetType().Name);
|
||||||
component.Initialize();
|
component.Initialize();
|
||||||
//_debugService.WriteMessage("Initialized machine '{0}'", component.GetType().Name);
|
//_debugService.WriteMessage("Initialized machine '{0}'", component.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadState()
|
private void LoadState()
|
||||||
{
|
{
|
||||||
#if WINDOWS
|
#if WINDOWS
|
||||||
var args = Environment.GetCommandLineArgs();
|
var args = Environment.GetCommandLineArgs();
|
||||||
if (args.Length > 1)
|
if (args.Length > 1)
|
||||||
{
|
{
|
||||||
string name = args[1];
|
string name = args[1];
|
||||||
Func<string, Action<Stream>, bool> loader = StorageService.LoadFile;
|
Func<string, Action<Stream>, bool> loader = StorageService.LoadFile;
|
||||||
|
|
||||||
if (name.StartsWith("res://", StringComparison.OrdinalIgnoreCase))
|
if (name.StartsWith("res://", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
name = name.Substring(6);
|
name = name.Substring(6);
|
||||||
loader = StorageService.LoadResource;
|
loader = StorageService.LoadResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.EndsWith(".bin", StringComparison.OrdinalIgnoreCase))
|
if (name.EndsWith(".bin", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
loader(name, stream => LoadState(stream));
|
loader(name, stream => LoadState(stream));
|
||||||
}
|
}
|
||||||
else if (name.EndsWith(".prg", StringComparison.OrdinalIgnoreCase))
|
else if (name.EndsWith(".prg", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
loader(name, stream => Memory.LoadPrg(stream));
|
loader(name, stream => Memory.LoadPrg(stream));
|
||||||
}
|
}
|
||||||
else if (name.EndsWith(".xex", StringComparison.OrdinalIgnoreCase))
|
else if (name.EndsWith(".xex", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
loader(name, stream => Memory.LoadXex(stream));
|
loader(name, stream => Memory.LoadXex(stream));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
loader(name, stream => BootDiskII.BootDrive.InsertDisk(name, stream, false));
|
loader(name, stream => BootDiskII.BootDrive.InsertDisk(name, stream, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (!_storageService.Load(Machine.StateFileName, stream => LoadState(stream)))
|
if (!_storageService.Load(Machine.StateFileName, stream => LoadState(stream)))
|
||||||
{
|
{
|
||||||
StorageService.LoadResource("Disks/Default.dsk", stream => BootDiskII.BootDrive.InsertDisk("Default.dsk", stream, false));
|
StorageService.LoadResource("Disks/Default.dsk", stream => BootDiskII.BootDrive.InsertDisk("Default.dsk", stream, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadState(Stream stream)
|
private void LoadState(Stream stream)
|
||||||
{
|
{
|
||||||
using (var reader = new BinaryReader(stream))
|
using (var reader = new BinaryReader(stream))
|
||||||
{
|
{
|
||||||
string signature = reader.ReadString();
|
string signature = reader.ReadString();
|
||||||
var version = new Version(reader.ReadString());
|
var version = new Version(reader.ReadString());
|
||||||
if ((signature != StateSignature) || (version != new Version(Machine.Version))) // avoid state version mismatch (for now)
|
if ((signature != StateSignature) || (version != new Version(Machine.Version))) // avoid state version mismatch (for now)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
foreach (var component in Components)
|
foreach (var component in Components)
|
||||||
{
|
{
|
||||||
_debugService.WriteMessage("Loading machine '{0}'", component.GetType().Name);
|
_debugService.WriteMessage("Loading machine '{0}'", component.GetType().Name);
|
||||||
component.LoadState(reader, version);
|
component.LoadState(reader, version);
|
||||||
//_debugService.WriteMessage("Loaded machine '{0}'", component.GetType().Name);
|
//_debugService.WriteMessage("Loaded machine '{0}'", component.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveState()
|
private void SaveState()
|
||||||
{
|
{
|
||||||
_storageService.Save(Machine.StateFileName, stream => SaveState(stream));
|
_storageService.Save(Machine.StateFileName, stream => SaveState(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveState(Stream stream)
|
private void SaveState(Stream stream)
|
||||||
{
|
{
|
||||||
using (var writer = new BinaryWriter(stream))
|
using (var writer = new BinaryWriter(stream))
|
||||||
{
|
{
|
||||||
writer.Write(StateSignature);
|
writer.Write(StateSignature);
|
||||||
writer.Write(Machine.Version);
|
writer.Write(Machine.Version);
|
||||||
foreach (var component in Components)
|
foreach (var component in Components)
|
||||||
{
|
{
|
||||||
_debugService.WriteMessage("Saving machine '{0}'", component.GetType().Name);
|
_debugService.WriteMessage("Saving machine '{0}'", component.GetType().Name);
|
||||||
component.SaveState(writer);
|
component.SaveState(writer);
|
||||||
//_debugService.WriteMessage("Saved machine '{0}'", component.GetType().Name);
|
//_debugService.WriteMessage("Saved machine '{0}'", component.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Uninitialize()
|
private void Uninitialize()
|
||||||
{
|
{
|
||||||
foreach (var component in Components)
|
foreach (var component in Components)
|
||||||
{
|
{
|
||||||
_debugService.WriteMessage("Uninitializing machine '{0}'", component.GetType().Name);
|
_debugService.WriteMessage("Uninitializing machine '{0}'", component.GetType().Name);
|
||||||
component.Uninitialize();
|
component.Uninitialize();
|
||||||
//_debugService.WriteMessage("Uninitialized machine '{0}'", component.GetType().Name);
|
//_debugService.WriteMessage("Uninitialized machine '{0}'", component.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Jellyfish.Virtu.Services.DebugService.WriteMessage(System.String)")]
|
||||||
private void Run() // machine thread
|
private void Run() // machine thread
|
||||||
{
|
{
|
||||||
Initialize();
|
Initialize();
|
||||||
Reset();
|
Reset();
|
||||||
LoadState();
|
LoadState();
|
||||||
|
|
||||||
_debugService.WriteMessage("Running machine");
|
_debugService.WriteMessage("Running machine");
|
||||||
State = MachineState.Running;
|
State = MachineState.Running;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Events.HandleEvents(Cpu.Execute());
|
Events.HandleEvents(Cpu.Execute());
|
||||||
}
|
}
|
||||||
while (State == MachineState.Running);
|
while (State == MachineState.Running);
|
||||||
|
|
||||||
if (State == MachineState.Pausing)
|
if (State == MachineState.Pausing)
|
||||||
{
|
{
|
||||||
_pauseEvent.Set();
|
_pauseEvent.Set();
|
||||||
_unpauseEvent.WaitOne();
|
_unpauseEvent.WaitOne();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (State != MachineState.Stopping);
|
while (State != MachineState.Stopping);
|
||||||
|
|
||||||
SaveState();
|
SaveState();
|
||||||
Uninitialize();
|
Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public const string Version = "0.9.4.0";
|
public const string Version = "0.9.4.0";
|
||||||
|
|
||||||
public MachineEvents Events { get; private set; }
|
public MachineEvents Events { get; private set; }
|
||||||
public MachineServices Services { get; private set; }
|
public MachineServices Services { get; private set; }
|
||||||
public MachineState State { get { return _state; } private set { _state = value; } }
|
public MachineState State { get { return _state; } private set { _state = value; } }
|
||||||
|
|
||||||
public Cpu Cpu { get; private set; }
|
public Cpu Cpu { get; private set; }
|
||||||
public Memory Memory { get; private set; }
|
public Memory Memory { get; private set; }
|
||||||
public Keyboard Keyboard { get; private set; }
|
public Keyboard Keyboard { get; private set; }
|
||||||
public GamePort GamePort { get; private set; }
|
public GamePort GamePort { get; private set; }
|
||||||
public Cassette Cassette { get; private set; }
|
public Cassette Cassette { get; private set; }
|
||||||
public Speaker Speaker { get; private set; }
|
public Speaker Speaker { get; private set; }
|
||||||
public Video Video { get; private set; }
|
public Video Video { get; private set; }
|
||||||
public NoSlotClock NoSlotClock { get; private set; }
|
public NoSlotClock NoSlotClock { get; private set; }
|
||||||
|
|
||||||
public PeripheralCard Slot1 { get; private set; }
|
public PeripheralCard Slot1 { get; private set; }
|
||||||
public PeripheralCard Slot2 { get; private set; }
|
public PeripheralCard Slot2 { get; private set; }
|
||||||
public PeripheralCard Slot3 { get; private set; }
|
public PeripheralCard Slot3 { get; private set; }
|
||||||
public PeripheralCard Slot4 { get; private set; }
|
public PeripheralCard Slot4 { get; private set; }
|
||||||
public PeripheralCard Slot5 { get; private set; }
|
public PeripheralCard Slot5 { get; private set; }
|
||||||
public PeripheralCard Slot6 { get; private set; }
|
public PeripheralCard Slot6 { get; private set; }
|
||||||
public PeripheralCard Slot7 { get; private set; }
|
public PeripheralCard Slot7 { get; private set; }
|
||||||
|
|
||||||
public Collection<PeripheralCard> Slots { get; private set; }
|
public Collection<PeripheralCard> Slots { get; private set; }
|
||||||
public Collection<MachineComponent> Components { get; private set; }
|
public Collection<MachineComponent> Components { get; private set; }
|
||||||
|
|
||||||
public DiskIIController BootDiskII { get; private set; }
|
public DiskIIController BootDiskII { get; private set; }
|
||||||
|
|
||||||
public Thread Thread { get; private set; }
|
public Thread Thread { get; private set; }
|
||||||
|
|
||||||
private const string StateFileName = "State.bin";
|
private const string StateFileName = "State.bin";
|
||||||
private const string StateSignature = "Virtu";
|
private const string StateSignature = "Virtu";
|
||||||
|
|
||||||
private DebugService _debugService;
|
private DebugService _debugService;
|
||||||
private StorageService _storageService;
|
private StorageService _storageService;
|
||||||
private volatile MachineState _state;
|
private volatile MachineState _state;
|
||||||
|
|
||||||
private AutoResetEvent _pauseEvent = new AutoResetEvent(false);
|
private AutoResetEvent _pauseEvent = new AutoResetEvent(false);
|
||||||
private AutoResetEvent _unpauseEvent = new AutoResetEvent(false);
|
private AutoResetEvent _unpauseEvent = new AutoResetEvent(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,42 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
using Jellyfish.Virtu.Services;
|
using Jellyfish.Virtu.Services;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public abstract class MachineComponent
|
public abstract class MachineComponent
|
||||||
{
|
{
|
||||||
protected MachineComponent(Machine machine)
|
protected MachineComponent(Machine machine)
|
||||||
{
|
{
|
||||||
Machine = machine;
|
Machine = machine;
|
||||||
|
|
||||||
_debugService = new Lazy<DebugService>(() => Machine.Services.GetService<DebugService>());
|
_debugService = new Lazy<DebugService>(() => Machine.Services.GetService<DebugService>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Initialize()
|
public virtual void Initialize()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Reset()
|
public virtual void Reset()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void LoadState(BinaryReader reader, Version version)
|
public virtual void LoadState(BinaryReader reader, Version version)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Uninitialize()
|
public virtual void Uninitialize()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SaveState(BinaryWriter writer)
|
public virtual void SaveState(BinaryWriter writer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Machine Machine { get; private set; }
|
protected Machine Machine { get; private set; }
|
||||||
protected DebugService DebugService { get { return _debugService.Value; } }
|
protected DebugService DebugService { get { return _debugService.Value; } }
|
||||||
|
|
||||||
private Lazy<DebugService> _debugService;
|
private Lazy<DebugService> _debugService;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,107 +1,107 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed class MachineEvent
|
public sealed class MachineEvent
|
||||||
{
|
{
|
||||||
public MachineEvent(int delta, Action action)
|
public MachineEvent(int delta, Action action)
|
||||||
{
|
{
|
||||||
Delta = delta;
|
Delta = delta;
|
||||||
Action = action;
|
Action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Format(CultureInfo.InvariantCulture, "Delta = {0} Action = {{{1}.{2}}}", Delta, Action.Method.DeclaringType.Name, Action.Method.Name);
|
return string.Format(CultureInfo.InvariantCulture, "Delta = {0} Action = {{{1}.{2}}}", Delta, Action.Method.DeclaringType.Name, Action.Method.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Delta { get; set; }
|
public int Delta { get; set; }
|
||||||
public Action Action { get; set; }
|
public Action Action { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class MachineEvents
|
public sealed class MachineEvents
|
||||||
{
|
{
|
||||||
public void AddEvent(int delta, Action action)
|
public void AddEvent(int delta, Action action)
|
||||||
{
|
{
|
||||||
var node = _used.First;
|
var node = _used.First;
|
||||||
for (; node != null; node = node.Next)
|
for (; node != null; node = node.Next)
|
||||||
{
|
{
|
||||||
if (delta < node.Value.Delta)
|
if (delta < node.Value.Delta)
|
||||||
{
|
{
|
||||||
node.Value.Delta -= delta;
|
node.Value.Delta -= delta;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (node.Value.Delta > 0)
|
if (node.Value.Delta > 0)
|
||||||
{
|
{
|
||||||
delta -= node.Value.Delta;
|
delta -= node.Value.Delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newNode = _free.First;
|
var newNode = _free.First;
|
||||||
if (newNode != null)
|
if (newNode != null)
|
||||||
{
|
{
|
||||||
_free.RemoveFirst();
|
_free.RemoveFirst();
|
||||||
newNode.Value.Delta = delta;
|
newNode.Value.Delta = delta;
|
||||||
newNode.Value.Action = action;
|
newNode.Value.Action = action;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newNode = new LinkedListNode<MachineEvent>(new MachineEvent(delta, action));
|
newNode = new LinkedListNode<MachineEvent>(new MachineEvent(delta, action));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node != null)
|
if (node != null)
|
||||||
{
|
{
|
||||||
_used.AddBefore(node, newNode);
|
_used.AddBefore(node, newNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_used.AddLast(newNode);
|
_used.AddLast(newNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int FindEvent(Action action)
|
public int FindEvent(Action action)
|
||||||
{
|
{
|
||||||
int delta = 0;
|
int delta = 0;
|
||||||
|
|
||||||
for (var node = _used.First; node != null; node = node.Next)
|
for (var node = _used.First; node != null; node = node.Next)
|
||||||
{
|
{
|
||||||
delta += node.Value.Delta;
|
delta += node.Value.Delta;
|
||||||
if (object.ReferenceEquals(node.Value.Action, action)) // assumes delegate cached
|
if (object.ReferenceEquals(node.Value.Action, action)) // assumes delegate cached
|
||||||
{
|
{
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleEvents(int delta)
|
public void HandleEvents(int delta)
|
||||||
{
|
{
|
||||||
var node = _used.First;
|
var node = _used.First;
|
||||||
node.Value.Delta -= delta;
|
node.Value.Delta -= delta;
|
||||||
|
|
||||||
while (node.Value.Delta <= 0)
|
while (node.Value.Delta <= 0)
|
||||||
{
|
{
|
||||||
node.Value.Action();
|
node.Value.Action();
|
||||||
RemoveEvent(node);
|
RemoveEvent(node);
|
||||||
node = _used.First;
|
node = _used.First;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveEvent(LinkedListNode<MachineEvent> node)
|
private void RemoveEvent(LinkedListNode<MachineEvent> node)
|
||||||
{
|
{
|
||||||
if (node.Next != null)
|
if (node.Next != null)
|
||||||
{
|
{
|
||||||
node.Next.Value.Delta += node.Value.Delta;
|
node.Next.Value.Delta += node.Value.Delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
_used.Remove(node);
|
_used.Remove(node);
|
||||||
_free.AddFirst(node); // cache node; avoids garbage
|
_free.AddFirst(node); // cache node; avoids garbage
|
||||||
}
|
}
|
||||||
|
|
||||||
private LinkedList<MachineEvent> _used = new LinkedList<MachineEvent>();
|
private LinkedList<MachineEvent> _used = new LinkedList<MachineEvent>();
|
||||||
private LinkedList<MachineEvent> _free = new LinkedList<MachineEvent>();
|
private LinkedList<MachineEvent> _free = new LinkedList<MachineEvent>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3476
Virtu/Memory.cs
3476
Virtu/Memory.cs
File diff suppressed because it is too large
Load Diff
|
@ -1,106 +1,106 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public partial class Memory
|
public partial class Memory
|
||||||
{
|
{
|
||||||
private const int BankCount = 2;
|
private const int BankCount = 2;
|
||||||
|
|
||||||
private const int BankMain = 0;
|
private const int BankMain = 0;
|
||||||
private const int BankAux = 1;
|
private const int BankAux = 1;
|
||||||
|
|
||||||
private const int RegionCount = 12;
|
private const int RegionCount = 12;
|
||||||
|
|
||||||
private const int Region0001 = 0;
|
private const int Region0001 = 0;
|
||||||
private const int Region02BF = 1;
|
private const int Region02BF = 1;
|
||||||
private const int Region0407 = 2;
|
private const int Region0407 = 2;
|
||||||
private const int Region080B = 3;
|
private const int Region080B = 3;
|
||||||
private const int Region203F = 4;
|
private const int Region203F = 4;
|
||||||
private const int Region405F = 5;
|
private const int Region405F = 5;
|
||||||
private const int RegionC0C0 = 6;
|
private const int RegionC0C0 = 6;
|
||||||
private const int RegionC1C7 = 7;
|
private const int RegionC1C7 = 7;
|
||||||
private const int RegionC3C3 = 8;
|
private const int RegionC3C3 = 8;
|
||||||
private const int RegionC8CF = 9;
|
private const int RegionC8CF = 9;
|
||||||
private const int RegionD0DF = 10;
|
private const int RegionD0DF = 10;
|
||||||
private const int RegionE0FF = 11;
|
private const int RegionE0FF = 11;
|
||||||
|
|
||||||
private static readonly int[] RegionBaseAddress = new int[RegionCount]
|
private static readonly int[] RegionBaseAddress = new int[RegionCount]
|
||||||
{
|
{
|
||||||
0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0xC000, 0xC100, 0xC100, 0xC100, 0xD000, 0xE000
|
0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0xC000, 0xC100, 0xC100, 0xC100, 0xD000, 0xE000
|
||||||
};
|
};
|
||||||
|
|
||||||
private const int PageCount = 256;
|
private const int PageCount = 256;
|
||||||
|
|
||||||
private static readonly int[] PageRegion = new int[PageCount]
|
private static readonly int[] PageRegion = new int[PageCount]
|
||||||
{
|
{
|
||||||
Region0001, Region0001, Region02BF, Region02BF, Region0407, Region0407, Region0407, Region0407,
|
Region0001, Region0001, Region02BF, Region02BF, Region0407, Region0407, Region0407, Region0407,
|
||||||
Region080B, Region080B, Region080B, Region080B, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region080B, Region080B, Region080B, Region080B, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F,
|
Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F,
|
||||||
Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F,
|
Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F,
|
||||||
Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F,
|
Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F,
|
||||||
Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F,
|
Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F, Region203F,
|
||||||
Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F,
|
Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F,
|
||||||
Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F,
|
Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F,
|
||||||
Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F,
|
Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F,
|
||||||
Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F,
|
Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F, Region405F,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF, Region02BF,
|
||||||
RegionC0C0, RegionC1C7, RegionC1C7, RegionC3C3, RegionC1C7, RegionC1C7, RegionC1C7, RegionC1C7,
|
RegionC0C0, RegionC1C7, RegionC1C7, RegionC3C3, RegionC1C7, RegionC1C7, RegionC1C7, RegionC1C7,
|
||||||
RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF,
|
RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF, RegionC8CF,
|
||||||
RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF,
|
RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF,
|
||||||
RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF,
|
RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF, RegionD0DF,
|
||||||
RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF,
|
RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF,
|
||||||
RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF,
|
RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF,
|
||||||
RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF,
|
RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF,
|
||||||
RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF
|
RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF, RegionE0FF
|
||||||
};
|
};
|
||||||
|
|
||||||
private const int State80Col = 0x000001;
|
private const int State80Col = 0x000001;
|
||||||
private const int StateText = 0x000002;
|
private const int StateText = 0x000002;
|
||||||
private const int StateMixed = 0x000004;
|
private const int StateMixed = 0x000004;
|
||||||
private const int StateHires = 0x000008;
|
private const int StateHires = 0x000008;
|
||||||
private const int StateDRes = 0x000010;
|
private const int StateDRes = 0x000010;
|
||||||
private const int State80Store = 0x000020;
|
private const int State80Store = 0x000020;
|
||||||
private const int StateAltChrSet = 0x000040;
|
private const int StateAltChrSet = 0x000040;
|
||||||
private const int StateAltZP = 0x000080;
|
private const int StateAltZP = 0x000080;
|
||||||
private const int StateBank1 = 0x000100;
|
private const int StateBank1 = 0x000100;
|
||||||
private const int StateHRamRd = 0x000200;
|
private const int StateHRamRd = 0x000200;
|
||||||
private const int StateHRamPreWrt = 0x000400;
|
private const int StateHRamPreWrt = 0x000400;
|
||||||
private const int StateHRamWrt = 0x000800;
|
private const int StateHRamWrt = 0x000800;
|
||||||
private const int StatePage2 = 0x001000;
|
private const int StatePage2 = 0x001000;
|
||||||
private const int StateRamRd = 0x002000;
|
private const int StateRamRd = 0x002000;
|
||||||
private const int StateRamWrt = 0x004000;
|
private const int StateRamWrt = 0x004000;
|
||||||
private const int StateSlotC3Rom = 0x008000;
|
private const int StateSlotC3Rom = 0x008000;
|
||||||
private const int StateIntC8Rom = 0x010000; // [5-28]
|
private const int StateIntC8Rom = 0x010000; // [5-28]
|
||||||
private const int StateIntCXRom = 0x020000;
|
private const int StateIntCXRom = 0x020000;
|
||||||
private const int StateAn0 = 0x040000;
|
private const int StateAn0 = 0x040000;
|
||||||
private const int StateAn1 = 0x080000;
|
private const int StateAn1 = 0x080000;
|
||||||
private const int StateAn2 = 0x100000;
|
private const int StateAn2 = 0x100000;
|
||||||
private const int StateAn3 = 0x200000;
|
private const int StateAn3 = 0x200000;
|
||||||
private const int StateVideo = State80Col | StateText | StateMixed | StateHires | StateDRes;
|
private const int StateVideo = State80Col | StateText | StateMixed | StateHires | StateDRes;
|
||||||
|
|
||||||
private const int StateVideoModeCount = 32;
|
private const int StateVideoModeCount = 32;
|
||||||
|
|
||||||
private static readonly int[] StateVideoMode = new int[StateVideoModeCount]
|
private static readonly int[] StateVideoMode = new int[StateVideoModeCount]
|
||||||
{
|
{
|
||||||
Video.Mode0, Video.Mode0, Video.Mode1, Video.Mode2, Video.Mode3, Video.Mode4, Video.Mode1, Video.Mode2,
|
Video.Mode0, Video.Mode0, Video.Mode1, Video.Mode2, Video.Mode3, Video.Mode4, Video.Mode1, Video.Mode2,
|
||||||
Video.Mode5, Video.Mode5, Video.Mode1, Video.Mode2, Video.Mode6, Video.Mode7, Video.Mode1, Video.Mode2,
|
Video.Mode5, Video.Mode5, Video.Mode1, Video.Mode2, Video.Mode6, Video.Mode7, Video.Mode1, Video.Mode2,
|
||||||
Video.Mode8, Video.Mode9, Video.Mode1, Video.Mode2, Video.ModeA, Video.ModeB, Video.Mode1, Video.Mode2,
|
Video.Mode8, Video.Mode9, Video.Mode1, Video.Mode2, Video.ModeA, Video.ModeB, Video.Mode1, Video.Mode2,
|
||||||
Video.ModeC, Video.ModeD, Video.Mode1, Video.Mode2, Video.ModeE, Video.ModeF, Video.Mode1, Video.Mode2
|
Video.ModeC, Video.ModeD, Video.Mode1, Video.Mode2, Video.ModeE, Video.ModeF, Video.Mode1, Video.Mode2
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly Action<int, byte>[][][] WriteRamModeBankRegion;
|
private readonly Action<int, byte>[][][] WriteRamModeBankRegion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,228 +1,228 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed class NoSlotClock : MachineComponent
|
public sealed class NoSlotClock : MachineComponent
|
||||||
{
|
{
|
||||||
public NoSlotClock(Machine machine) :
|
public NoSlotClock(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_clockEnabled = false;
|
_clockEnabled = false;
|
||||||
_writeEnabled = true;
|
_writeEnabled = true;
|
||||||
_clockRegister = new RingRegister(0x0, 0x1);
|
_clockRegister = new RingRegister(0x0, 0x1);
|
||||||
_comparisonRegister = new RingRegister(ClockInitSequence, 0x1);
|
_comparisonRegister = new RingRegister(ClockInitSequence, 0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadState(BinaryReader reader, Version version)
|
public override void LoadState(BinaryReader reader, Version version)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
_clockEnabled = reader.ReadBoolean();
|
_clockEnabled = reader.ReadBoolean();
|
||||||
_writeEnabled = reader.ReadBoolean();
|
_writeEnabled = reader.ReadBoolean();
|
||||||
_clockRegister = new RingRegister(reader.ReadUInt64(), reader.ReadUInt64());
|
_clockRegister = new RingRegister(reader.ReadUInt64(), reader.ReadUInt64());
|
||||||
_comparisonRegister = new RingRegister(reader.ReadUInt64(), reader.ReadUInt64());
|
_comparisonRegister = new RingRegister(reader.ReadUInt64(), reader.ReadUInt64());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SaveState(BinaryWriter writer)
|
public override void SaveState(BinaryWriter writer)
|
||||||
{
|
{
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(_clockEnabled);
|
writer.Write(_clockEnabled);
|
||||||
writer.Write(_writeEnabled);
|
writer.Write(_writeEnabled);
|
||||||
writer.Write(_clockRegister.Data);
|
writer.Write(_clockRegister.Data);
|
||||||
writer.Write(_clockRegister.Mask);
|
writer.Write(_clockRegister.Mask);
|
||||||
writer.Write(_comparisonRegister.Data);
|
writer.Write(_comparisonRegister.Data);
|
||||||
writer.Write(_comparisonRegister.Mask);
|
writer.Write(_comparisonRegister.Mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Read(int address, int data)
|
public int Read(int address, int data)
|
||||||
{
|
{
|
||||||
// this may read or write the clock
|
// this may read or write the clock
|
||||||
if ((address & 0x4) != 0)
|
if ((address & 0x4) != 0)
|
||||||
{
|
{
|
||||||
return ReadClock(data);
|
return ReadClock(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteClock(address);
|
WriteClock(address);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(int address)
|
public void Write(int address)
|
||||||
{
|
{
|
||||||
// this may read or write the clock
|
// this may read or write the clock
|
||||||
if ((address & 0x4) != 0)
|
if ((address & 0x4) != 0)
|
||||||
{
|
{
|
||||||
ReadClock(0);
|
ReadClock(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteClock(address);
|
WriteClock(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int ReadClock(int data)
|
private int ReadClock(int data)
|
||||||
{
|
{
|
||||||
// for a ROM, A2 high = read, and data out (if any) is on D0
|
// for a ROM, A2 high = read, and data out (if any) is on D0
|
||||||
if (!_clockEnabled)
|
if (!_clockEnabled)
|
||||||
{
|
{
|
||||||
_comparisonRegister.Reset();
|
_comparisonRegister.Reset();
|
||||||
_writeEnabled = true;
|
_writeEnabled = true;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = _clockRegister.ReadBit(Machine.Video.ReadFloatingBus());
|
data = _clockRegister.ReadBit(Machine.Video.ReadFloatingBus());
|
||||||
if (_clockRegister.NextBit())
|
if (_clockRegister.NextBit())
|
||||||
{
|
{
|
||||||
_clockEnabled = false;
|
_clockEnabled = false;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteClock(int address)
|
private void WriteClock(int address)
|
||||||
{
|
{
|
||||||
// for a ROM, A2 low = write, and data in is on A0
|
// for a ROM, A2 low = write, and data in is on A0
|
||||||
if (!_writeEnabled)
|
if (!_writeEnabled)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_clockEnabled)
|
if (!_clockEnabled)
|
||||||
{
|
{
|
||||||
if ((_comparisonRegister.CompareBit(address)))
|
if ((_comparisonRegister.CompareBit(address)))
|
||||||
{
|
{
|
||||||
if (_comparisonRegister.NextBit())
|
if (_comparisonRegister.NextBit())
|
||||||
{
|
{
|
||||||
_clockEnabled = true;
|
_clockEnabled = true;
|
||||||
PopulateClockRegister();
|
PopulateClockRegister();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// mismatch ignores further writes
|
// mismatch ignores further writes
|
||||||
_writeEnabled = false;
|
_writeEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_clockRegister.NextBit())
|
else if (_clockRegister.NextBit())
|
||||||
{
|
{
|
||||||
// simulate writes, but our clock register is read-only
|
// simulate writes, but our clock register is read-only
|
||||||
_clockEnabled = false;
|
_clockEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateClockRegister()
|
private void PopulateClockRegister()
|
||||||
{
|
{
|
||||||
// all values are in packed BCD format (4 bits per decimal digit)
|
// all values are in packed BCD format (4 bits per decimal digit)
|
||||||
var now = DateTime.Now;
|
var now = DateTime.Now;
|
||||||
|
|
||||||
int centisecond = now.Millisecond / 10; // 00-99
|
int centisecond = now.Millisecond / 10; // 00-99
|
||||||
_clockRegister.WriteNibble(centisecond % 10);
|
_clockRegister.WriteNibble(centisecond % 10);
|
||||||
_clockRegister.WriteNibble(centisecond / 10);
|
_clockRegister.WriteNibble(centisecond / 10);
|
||||||
|
|
||||||
int second = now.Second; // 00-59
|
int second = now.Second; // 00-59
|
||||||
_clockRegister.WriteNibble(second % 10);
|
_clockRegister.WriteNibble(second % 10);
|
||||||
_clockRegister.WriteNibble(second / 10);
|
_clockRegister.WriteNibble(second / 10);
|
||||||
|
|
||||||
int minute = now.Minute; // 00-59
|
int minute = now.Minute; // 00-59
|
||||||
_clockRegister.WriteNibble(minute % 10);
|
_clockRegister.WriteNibble(minute % 10);
|
||||||
_clockRegister.WriteNibble(minute / 10);
|
_clockRegister.WriteNibble(minute / 10);
|
||||||
|
|
||||||
int hour = now.Hour; // 01-23
|
int hour = now.Hour; // 01-23
|
||||||
_clockRegister.WriteNibble(hour % 10);
|
_clockRegister.WriteNibble(hour % 10);
|
||||||
_clockRegister.WriteNibble(hour / 10);
|
_clockRegister.WriteNibble(hour / 10);
|
||||||
|
|
||||||
int day = (int)now.DayOfWeek + 1; // 01-07 (1 = Sunday)
|
int day = (int)now.DayOfWeek + 1; // 01-07 (1 = Sunday)
|
||||||
_clockRegister.WriteNibble(day % 10);
|
_clockRegister.WriteNibble(day % 10);
|
||||||
_clockRegister.WriteNibble(day / 10);
|
_clockRegister.WriteNibble(day / 10);
|
||||||
|
|
||||||
int date = now.Day; // 01-31
|
int date = now.Day; // 01-31
|
||||||
_clockRegister.WriteNibble(date % 10);
|
_clockRegister.WriteNibble(date % 10);
|
||||||
_clockRegister.WriteNibble(date / 10);
|
_clockRegister.WriteNibble(date / 10);
|
||||||
|
|
||||||
int month = now.Month; // 01-12
|
int month = now.Month; // 01-12
|
||||||
_clockRegister.WriteNibble(month % 10);
|
_clockRegister.WriteNibble(month % 10);
|
||||||
_clockRegister.WriteNibble(month / 10);
|
_clockRegister.WriteNibble(month / 10);
|
||||||
|
|
||||||
int year = now.Year % 100; // 00-99
|
int year = now.Year % 100; // 00-99
|
||||||
_clockRegister.WriteNibble(year % 10);
|
_clockRegister.WriteNibble(year % 10);
|
||||||
_clockRegister.WriteNibble(year / 10);
|
_clockRegister.WriteNibble(year / 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const ulong ClockInitSequence = 0x5CA33AC55CA33AC5;
|
private const ulong ClockInitSequence = 0x5CA33AC55CA33AC5;
|
||||||
|
|
||||||
private bool _clockEnabled;
|
private bool _clockEnabled;
|
||||||
private bool _writeEnabled;
|
private bool _writeEnabled;
|
||||||
private RingRegister _clockRegister;
|
private RingRegister _clockRegister;
|
||||||
private RingRegister _comparisonRegister;
|
private RingRegister _comparisonRegister;
|
||||||
|
|
||||||
private struct RingRegister
|
private struct RingRegister
|
||||||
{
|
{
|
||||||
public RingRegister(ulong data, ulong mask)
|
public RingRegister(ulong data, ulong mask)
|
||||||
{
|
{
|
||||||
_data = data;
|
_data = data;
|
||||||
_mask = mask;
|
_mask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
_mask = 0x1;
|
_mask = 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteNibble(int data)
|
public void WriteNibble(int data)
|
||||||
{
|
{
|
||||||
WriteBits(data, 4);
|
WriteBits(data, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteBits(int data, int count)
|
public void WriteBits(int data, int count)
|
||||||
{
|
{
|
||||||
for (int i = 1; i <= count; i++)
|
for (int i = 1; i <= count; i++)
|
||||||
{
|
{
|
||||||
WriteBit(data);
|
WriteBit(data);
|
||||||
NextBit();
|
NextBit();
|
||||||
data >>= 1;
|
data >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteBit(int data)
|
public void WriteBit(int data)
|
||||||
{
|
{
|
||||||
_data = ((data & 0x1) != 0) ? (_data | _mask) : (_data & ~_mask);
|
_data = ((data & 0x1) != 0) ? (_data | _mask) : (_data & ~_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ReadBit(int data)
|
public int ReadBit(int data)
|
||||||
{
|
{
|
||||||
return ((_data & _mask) != 0) ? (data | 0x1) : (data & ~0x1);
|
return ((_data & _mask) != 0) ? (data | 0x1) : (data & ~0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CompareBit(int data)
|
public bool CompareBit(int data)
|
||||||
{
|
{
|
||||||
return (((_data & _mask) != 0) == ((data & 0x1) != 0));
|
return (((_data & _mask) != 0) == ((data & 0x1) != 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool NextBit()
|
public bool NextBit()
|
||||||
{
|
{
|
||||||
if ((_mask <<= 1) == 0)
|
if ((_mask <<= 1) == 0)
|
||||||
{
|
{
|
||||||
_mask = 0x1;
|
_mask = 0x1;
|
||||||
return true; // wrap
|
return true; // wrap
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ulong Data { get { return _data; } } // no auto props
|
public ulong Data { get { return _data; } } // no auto props
|
||||||
public ulong Mask { get { return _mask; } }
|
public ulong Mask { get { return _mask; } }
|
||||||
|
|
||||||
private ulong _data;
|
private ulong _data;
|
||||||
private ulong _mask;
|
private ulong _mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +1,48 @@
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public class PeripheralCard : MachineComponent
|
public class PeripheralCard : MachineComponent
|
||||||
{
|
{
|
||||||
public PeripheralCard(Machine machine) :
|
public PeripheralCard(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int ReadIoRegionC0C0(int address)
|
public virtual int ReadIoRegionC0C0(int address)
|
||||||
{
|
{
|
||||||
// read Device Select' address $C0nX; n = slot number + 8
|
// read Device Select' address $C0nX; n = slot number + 8
|
||||||
return ReadFloatingBus();
|
return ReadFloatingBus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int ReadIoRegionC1C7(int address)
|
public virtual int ReadIoRegionC1C7(int address)
|
||||||
{
|
{
|
||||||
// read I/O Select' address $CsXX; s = slot number
|
// read I/O Select' address $CsXX; s = slot number
|
||||||
return ReadFloatingBus();
|
return ReadFloatingBus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int ReadIoRegionC8CF(int address)
|
public virtual int ReadIoRegionC8CF(int address)
|
||||||
{
|
{
|
||||||
// read I/O Strobe' address $C800-$CFFF
|
// read I/O Strobe' address $C800-$CFFF
|
||||||
return ReadFloatingBus();
|
return ReadFloatingBus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void WriteIoRegionC0C0(int address, int data)
|
public virtual void WriteIoRegionC0C0(int address, int data)
|
||||||
{
|
{
|
||||||
// write Device Select' address $C0nX; n = slot number + 8
|
// write Device Select' address $C0nX; n = slot number + 8
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void WriteIoRegionC1C7(int address, int data)
|
public virtual void WriteIoRegionC1C7(int address, int data)
|
||||||
{
|
{
|
||||||
// write I/O Select' address $CsXX; s = slot number
|
// write I/O Select' address $CsXX; s = slot number
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void WriteIoRegionC8CF(int address, int data)
|
public virtual void WriteIoRegionC8CF(int address, int data)
|
||||||
{
|
{
|
||||||
// write I/O Strobe' address $C800-$CFFF
|
// write I/O Strobe' address $C800-$CFFF
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int ReadFloatingBus()
|
protected int ReadFloatingBus()
|
||||||
{
|
{
|
||||||
return Machine.Video.ReadFloatingBus();
|
return Machine.Video.ReadFloatingBus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,108 +1,108 @@
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// This code was generated by a tool.
|
// This code was generated by a tool.
|
||||||
// Runtime Version:4.0.30319.17626
|
// Runtime Version:4.0.30319.17626
|
||||||
//
|
//
|
||||||
// Changes to this file may cause incorrect behavior and will be lost if
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
// the code is regenerated.
|
// the code is regenerated.
|
||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Properties {
|
namespace Jellyfish.Virtu.Properties {
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
// class via a tool like ResGen or Visual Studio.
|
// class via a tool like ResGen or Visual Studio.
|
||||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
// with the /str option, or rebuild your VS project.
|
// with the /str option, or rebuild your VS project.
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
internal class Strings {
|
internal class Strings {
|
||||||
|
|
||||||
private static global::System.Resources.ResourceManager resourceMan;
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
internal Strings() {
|
internal Strings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the cached ResourceManager instance used by this class.
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
get {
|
get {
|
||||||
if (object.ReferenceEquals(resourceMan, null)) {
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Jellyfish.Virtu.Properties.Strings", typeof(Strings).Assembly);
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Jellyfish.Virtu.Properties.Strings", typeof(Strings).Assembly);
|
||||||
resourceMan = temp;
|
resourceMan = temp;
|
||||||
}
|
}
|
||||||
return resourceMan;
|
return resourceMan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Overrides the current thread's CurrentUICulture property for all
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
/// resource lookups using this strongly typed resource class.
|
/// resource lookups using this strongly typed resource class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
internal static global::System.Globalization.CultureInfo Culture {
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
get {
|
get {
|
||||||
return resourceCulture;
|
return resourceCulture;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
resourceCulture = value;
|
resourceCulture = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Invalid address range ${0:X04}-${1:X04}..
|
/// Looks up a localized string similar to Invalid address range ${0:X04}-${1:X04}..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string InvalidAddressRange {
|
internal static string InvalidAddressRange {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("InvalidAddressRange", resourceCulture);
|
return ResourceManager.GetString("InvalidAddressRange", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Marker ${0:X04} not found..
|
/// Looks up a localized string similar to Marker ${0:X04} not found..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string MarkerNotFound {
|
internal static string MarkerNotFound {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("MarkerNotFound", resourceCulture);
|
return ResourceManager.GetString("MarkerNotFound", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Resource '{0}' not found..
|
/// Looks up a localized string similar to Resource '{0}' not found..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string ResourceNotFound {
|
internal static string ResourceNotFound {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("ResourceNotFound", resourceCulture);
|
return ResourceManager.GetString("ResourceNotFound", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Service type '{0}' already present..
|
/// Looks up a localized string similar to Service type '{0}' already present..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string ServiceAlreadyPresent {
|
internal static string ServiceAlreadyPresent {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("ServiceAlreadyPresent", resourceCulture);
|
return ResourceManager.GetString("ServiceAlreadyPresent", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Service type '{0}' must be assignable from service provider '{1}'..
|
/// Looks up a localized string similar to Service type '{0}' must be assignable from service provider '{1}'..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static string ServiceMustBeAssignable {
|
internal static string ServiceMustBeAssignable {
|
||||||
get {
|
get {
|
||||||
return ResourceManager.GetString("ServiceMustBeAssignable", resourceCulture);
|
return ResourceManager.GetString("ServiceMustBeAssignable", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,135 +1,135 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
|
|
||||||
Version 2.0
|
Version 2.0
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
The primary goals of this format is to allow a simple XML format
|
||||||
that is mostly human readable. The generation and parsing of the
|
that is mostly human readable. The generation and parsing of the
|
||||||
various data types are done through the TypeConverter classes
|
various data types are done through the TypeConverter classes
|
||||||
associated with the data types.
|
associated with the data types.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
... ado.net/XML headers & schema ...
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
<resheader name="version">2.0</resheader>
|
<resheader name="version">2.0</resheader>
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
<comment>This is a comment</comment>
|
<comment>This is a comment</comment>
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
There are any number of "resheader" rows that contain simple
|
||||||
name/value pairs.
|
name/value pairs.
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
Each data row contains a name, and value. The row also contains a
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
text/value conversion through the TypeConverter architecture.
|
text/value conversion through the TypeConverter architecture.
|
||||||
Classes that don't support this are serialized and stored with the
|
Classes that don't support this are serialized and stored with the
|
||||||
mimetype set.
|
mimetype set.
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
The mimetype is used for serialized objects, and tells the
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
read any of the formats listed below.
|
read any of the formats listed below.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
value : The object must be serialized with
|
value : The object must be serialized with
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
value : The object must be serialized into a byte array
|
value : The object must be serialized into a byte array
|
||||||
: using a System.ComponentModel.TypeConverter
|
: using a System.ComponentModel.TypeConverter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
-->
|
-->
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:choice maxOccurs="unbounded">
|
<xsd:choice maxOccurs="unbounded">
|
||||||
<xsd:element name="metadata">
|
<xsd:element name="metadata">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:sequence>
|
<xsd:sequence>
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
<xsd:attribute ref="xml:space" />
|
<xsd:attribute ref="xml:space" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
<xsd:element name="assembly">
|
<xsd:element name="assembly">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
<xsd:element name="data">
|
<xsd:element name="data">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:sequence>
|
<xsd:sequence>
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
<xsd:attribute ref="xml:space" />
|
<xsd:attribute ref="xml:space" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
<xsd:element name="resheader">
|
<xsd:element name="resheader">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:sequence>
|
<xsd:sequence>
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
</xsd:choice>
|
</xsd:choice>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
</xsd:schema>
|
</xsd:schema>
|
||||||
<resheader name="resmimetype">
|
<resheader name="resmimetype">
|
||||||
<value>text/microsoft-resx</value>
|
<value>text/microsoft-resx</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<resheader name="version">
|
<resheader name="version">
|
||||||
<value>2.0</value>
|
<value>2.0</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<resheader name="reader">
|
<resheader name="reader">
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.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>
|
||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.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>
|
</resheader>
|
||||||
<data name="InvalidAddressRange" xml:space="preserve">
|
<data name="InvalidAddressRange" xml:space="preserve">
|
||||||
<value>Invalid address range ${0:X04}-${1:X04}.</value>
|
<value>Invalid address range ${0:X04}-${1:X04}.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MarkerNotFound" xml:space="preserve">
|
<data name="MarkerNotFound" xml:space="preserve">
|
||||||
<value>Marker ${0:X04} not found.</value>
|
<value>Marker ${0:X04} not found.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ResourceNotFound" xml:space="preserve">
|
<data name="ResourceNotFound" xml:space="preserve">
|
||||||
<value>Resource '{0}' not found.</value>
|
<value>Resource '{0}' not found.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ServiceAlreadyPresent" xml:space="preserve">
|
<data name="ServiceAlreadyPresent" xml:space="preserve">
|
||||||
<value>Service type '{0}' already present.</value>
|
<value>Service type '{0}' already present.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ServiceMustBeAssignable" xml:space="preserve">
|
<data name="ServiceMustBeAssignable" xml:space="preserve">
|
||||||
<value>Service type '{0}' must be assignable from service provider '{1}'.</value>
|
<value>Service type '{0}' must be assignable from service provider '{1}'.</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -1,66 +1,66 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public abstract class AudioService : MachineService
|
public abstract class AudioService : MachineService
|
||||||
{
|
{
|
||||||
protected AudioService(Machine machine) :
|
protected AudioService(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Output(int data) // machine thread
|
public void Output(int data) // machine thread
|
||||||
{
|
{
|
||||||
if (BitConverter.IsLittleEndian)
|
if (BitConverter.IsLittleEndian)
|
||||||
{
|
{
|
||||||
_buffer[_index + 0] = (byte)(data & 0xFF);
|
_buffer[_index + 0] = (byte)(data & 0xFF);
|
||||||
_buffer[_index + 1] = (byte)(data >> 8);
|
_buffer[_index + 1] = (byte)(data >> 8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_buffer[_index + 0] = (byte)(data >> 8);
|
_buffer[_index + 0] = (byte)(data >> 8);
|
||||||
_buffer[_index + 1] = (byte)(data & 0xFF);
|
_buffer[_index + 1] = (byte)(data & 0xFF);
|
||||||
}
|
}
|
||||||
_index = (_index + 2) % SampleSize;
|
_index = (_index + 2) % SampleSize;
|
||||||
if (_index == 0)
|
if (_index == 0)
|
||||||
{
|
{
|
||||||
if (Machine.Cpu.IsThrottled)
|
if (Machine.Cpu.IsThrottled)
|
||||||
{
|
{
|
||||||
_writeEvent.WaitOne(SampleLatency * 2); // allow timeout; avoids deadlock
|
_writeEvent.WaitOne(SampleLatency * 2); // allow timeout; avoids deadlock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
Buffer.BlockCopy(SampleZero, 0, _buffer, 0, SampleSize);
|
Buffer.BlockCopy(SampleZero, 0, _buffer, 0, SampleSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void SetVolume(float volume);
|
public abstract void SetVolume(float volume);
|
||||||
|
|
||||||
protected void Update() // audio thread
|
protected void Update() // audio thread
|
||||||
{
|
{
|
||||||
_writeEvent.Set();
|
_writeEvent.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
public const int SampleRate = 44100; // hz
|
public const int SampleRate = 44100; // hz
|
||||||
public const int SampleChannels = 1;
|
public const int SampleChannels = 1;
|
||||||
public const int SampleBits = 16;
|
public const int SampleBits = 16;
|
||||||
public const int SampleLatency = 40; // ms
|
public const int SampleLatency = 40; // ms
|
||||||
public const int SampleSize = (SampleRate * SampleLatency / 1000) * SampleChannels * (SampleBits / 8);
|
public const int SampleSize = (SampleRate * SampleLatency / 1000) * SampleChannels * (SampleBits / 8);
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Security", "CA2105:ArrayFieldsShouldNotBeReadOnly")]
|
[SuppressMessage("Microsoft.Security", "CA2105:ArrayFieldsShouldNotBeReadOnly")]
|
||||||
protected static readonly byte[] SampleZero = new byte[SampleSize];
|
protected static readonly byte[] SampleZero = new byte[SampleSize];
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
||||||
protected byte[] Source { get { return _buffer; } }
|
protected byte[] Source { get { return _buffer; } }
|
||||||
|
|
||||||
private byte[] _buffer = new byte[SampleSize];
|
private byte[] _buffer = new byte[SampleSize];
|
||||||
private int _index;
|
private int _index;
|
||||||
|
|
||||||
private AutoResetEvent _writeEvent = new AutoResetEvent(false);
|
private AutoResetEvent _writeEvent = new AutoResetEvent(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +1,63 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public class DebugService : MachineService
|
public class DebugService : MachineService
|
||||||
{
|
{
|
||||||
public DebugService(Machine machine) :
|
public DebugService(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteMessage(string message)
|
public void WriteMessage(string message)
|
||||||
{
|
{
|
||||||
OnWriteMessage(FormatMessage(message));
|
OnWriteMessage(FormatMessage(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteMessage(string format, params object[] args)
|
public void WriteMessage(string format, params object[] args)
|
||||||
{
|
{
|
||||||
OnWriteMessage(FormatMessage(format, args));
|
OnWriteMessage(FormatMessage(format, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnWriteMessage(string message)
|
protected virtual void OnWriteMessage(string message)
|
||||||
{
|
{
|
||||||
#if SILVERLIGHT
|
#if SILVERLIGHT
|
||||||
Debug.WriteLine(message);
|
Debug.WriteLine(message);
|
||||||
#else
|
#else
|
||||||
Trace.WriteLine(message);
|
Trace.WriteLine(message);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FormatMessage(string format, params object[] args)
|
private string FormatMessage(string format, params object[] args)
|
||||||
{
|
{
|
||||||
var message = new StringBuilder(256);
|
var message = new StringBuilder(256);
|
||||||
message.AppendFormat(CultureInfo.InvariantCulture, "[{0} T{1:X3} Virtu] ", DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture), Thread.CurrentThread.ManagedThreadId);
|
message.AppendFormat(CultureInfo.InvariantCulture, "[{0} T{1:X3} Virtu] ", DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture), Thread.CurrentThread.ManagedThreadId);
|
||||||
if (args.Length > 0)
|
if (args.Length > 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
message.AppendFormat(CultureInfo.InvariantCulture, format, args);
|
message.AppendFormat(CultureInfo.InvariantCulture, format, args);
|
||||||
}
|
}
|
||||||
catch (FormatException ex)
|
catch (FormatException ex)
|
||||||
{
|
{
|
||||||
WriteMessage("[DebugService.FormatMessage] format: {0}; args: {1}; exception: {2}", format, string.Join(", ", args), ex.Message);
|
WriteMessage("[DebugService.FormatMessage] format: {0}; args: {1}; exception: {2}", format, string.Join(", ", args), ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
message.Append(format);
|
message.Append(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
return message.ToString();
|
return message.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DebugService Default { get { return _default.Value; } }
|
public static DebugService Default { get { return _default.Value; } }
|
||||||
|
|
||||||
private static readonly Lazy<DebugService> _default = new Lazy<DebugService>(() => new DebugService(null));
|
private static readonly Lazy<DebugService> _default = new Lazy<DebugService>(() => new DebugService(null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,139 +1,139 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public class GamePortService : MachineService
|
public class GamePortService : MachineService
|
||||||
{
|
{
|
||||||
public GamePortService(Machine machine) :
|
public GamePortService(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
Paddle0 = Paddle1 = Paddle2 = Paddle3 = 255; // not connected
|
Paddle0 = Paddle1 = Paddle2 = Paddle3 = 255; // not connected
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Update() // main thread
|
public virtual void Update() // main thread
|
||||||
{
|
{
|
||||||
var keyboard = Machine.Keyboard;
|
var keyboard = Machine.Keyboard;
|
||||||
|
|
||||||
if (keyboard.UseGamePort)
|
if (keyboard.UseGamePort)
|
||||||
{
|
{
|
||||||
UpdateKey(keyboard.Joystick0UpKey, IsJoystick0Up, ref _isJoystick0UpKeyDown, ref _wasJoystick0UpKeyDown);
|
UpdateKey(keyboard.Joystick0UpKey, IsJoystick0Up, ref _isJoystick0UpKeyDown, ref _wasJoystick0UpKeyDown);
|
||||||
UpdateKey(keyboard.Joystick0LeftKey, IsJoystick0Left, ref _isJoystick0LeftKeyDown, ref _wasJoystick0LeftKeyDown);
|
UpdateKey(keyboard.Joystick0LeftKey, IsJoystick0Left, ref _isJoystick0LeftKeyDown, ref _wasJoystick0LeftKeyDown);
|
||||||
UpdateKey(keyboard.Joystick0RightKey, IsJoystick0Right, ref _isJoystick0RightKeyDown, ref _wasJoystick0RightKeyDown);
|
UpdateKey(keyboard.Joystick0RightKey, IsJoystick0Right, ref _isJoystick0RightKeyDown, ref _wasJoystick0RightKeyDown);
|
||||||
UpdateKey(keyboard.Joystick0DownKey, IsJoystick0Down, ref _isJoystick0DownKeyDown, ref _wasJoystick0DownKeyDown);
|
UpdateKey(keyboard.Joystick0DownKey, IsJoystick0Down, ref _isJoystick0DownKeyDown, ref _wasJoystick0DownKeyDown);
|
||||||
UpdateKey(keyboard.Joystick0UpLeftKey, IsJoystick0Up && IsJoystick0Left, ref _isJoystick0UpLeftKeyDown, ref _wasJoystick0UpLeftKeyDown);
|
UpdateKey(keyboard.Joystick0UpLeftKey, IsJoystick0Up && IsJoystick0Left, ref _isJoystick0UpLeftKeyDown, ref _wasJoystick0UpLeftKeyDown);
|
||||||
UpdateKey(keyboard.Joystick0UpRightKey, IsJoystick0Up && IsJoystick0Right, ref _isJoystick0UpRightKeyDown, ref _wasJoystick0UpRightKeyDown);
|
UpdateKey(keyboard.Joystick0UpRightKey, IsJoystick0Up && IsJoystick0Right, ref _isJoystick0UpRightKeyDown, ref _wasJoystick0UpRightKeyDown);
|
||||||
UpdateKey(keyboard.Joystick0DownLeftKey, IsJoystick0Down && IsJoystick0Left, ref _isJoystick0DownLeftKeyDown, ref _wasJoystick0DownLeftKeyDown);
|
UpdateKey(keyboard.Joystick0DownLeftKey, IsJoystick0Down && IsJoystick0Left, ref _isJoystick0DownLeftKeyDown, ref _wasJoystick0DownLeftKeyDown);
|
||||||
UpdateKey(keyboard.Joystick0DownRightKey, IsJoystick0Down && IsJoystick0Right, ref _isJoystick0DownRightKeyDown, ref _wasJoystick0DownRightKeyDown);
|
UpdateKey(keyboard.Joystick0DownRightKey, IsJoystick0Down && IsJoystick0Right, ref _isJoystick0DownRightKeyDown, ref _wasJoystick0DownRightKeyDown);
|
||||||
UpdateKey(keyboard.Joystick1UpKey, IsJoystick1Up, ref _isJoystick1UpKeyDown, ref _wasJoystick1UpKeyDown);
|
UpdateKey(keyboard.Joystick1UpKey, IsJoystick1Up, ref _isJoystick1UpKeyDown, ref _wasJoystick1UpKeyDown);
|
||||||
UpdateKey(keyboard.Joystick1LeftKey, IsJoystick1Left, ref _isJoystick1LeftKeyDown, ref _wasJoystick1LeftKeyDown);
|
UpdateKey(keyboard.Joystick1LeftKey, IsJoystick1Left, ref _isJoystick1LeftKeyDown, ref _wasJoystick1LeftKeyDown);
|
||||||
UpdateKey(keyboard.Joystick1RightKey, IsJoystick1Right, ref _isJoystick1RightKeyDown, ref _wasJoystick1RightKeyDown);
|
UpdateKey(keyboard.Joystick1RightKey, IsJoystick1Right, ref _isJoystick1RightKeyDown, ref _wasJoystick1RightKeyDown);
|
||||||
UpdateKey(keyboard.Joystick1DownKey, IsJoystick1Down, ref _isJoystick1DownKeyDown, ref _wasJoystick1DownKeyDown);
|
UpdateKey(keyboard.Joystick1DownKey, IsJoystick1Down, ref _isJoystick1DownKeyDown, ref _wasJoystick1DownKeyDown);
|
||||||
UpdateKey(keyboard.Joystick1UpLeftKey, IsJoystick1Up && IsJoystick1Left, ref _isJoystick1UpLeftKeyDown, ref _wasJoystick1UpLeftKeyDown);
|
UpdateKey(keyboard.Joystick1UpLeftKey, IsJoystick1Up && IsJoystick1Left, ref _isJoystick1UpLeftKeyDown, ref _wasJoystick1UpLeftKeyDown);
|
||||||
UpdateKey(keyboard.Joystick1UpRightKey, IsJoystick1Up && IsJoystick1Right, ref _isJoystick1UpRightKeyDown, ref _wasJoystick1UpRightKeyDown);
|
UpdateKey(keyboard.Joystick1UpRightKey, IsJoystick1Up && IsJoystick1Right, ref _isJoystick1UpRightKeyDown, ref _wasJoystick1UpRightKeyDown);
|
||||||
UpdateKey(keyboard.Joystick1DownLeftKey, IsJoystick1Down && IsJoystick1Left, ref _isJoystick1DownLeftKeyDown, ref _wasJoystick1DownLeftKeyDown);
|
UpdateKey(keyboard.Joystick1DownLeftKey, IsJoystick1Down && IsJoystick1Left, ref _isJoystick1DownLeftKeyDown, ref _wasJoystick1DownLeftKeyDown);
|
||||||
UpdateKey(keyboard.Joystick1DownRightKey, IsJoystick1Down && IsJoystick1Right, ref _isJoystick1DownRightKeyDown, ref _wasJoystick1DownRightKeyDown);
|
UpdateKey(keyboard.Joystick1DownRightKey, IsJoystick1Down && IsJoystick1Right, ref _isJoystick1DownRightKeyDown, ref _wasJoystick1DownRightKeyDown);
|
||||||
UpdateKey(keyboard.Button0Key, IsButton0Down, ref _isButton0KeyDown, ref _wasButton0KeyDown);
|
UpdateKey(keyboard.Button0Key, IsButton0Down, ref _isButton0KeyDown, ref _wasButton0KeyDown);
|
||||||
UpdateKey(keyboard.Button1Key, IsButton1Down, ref _isButton1KeyDown, ref _wasButton1KeyDown);
|
UpdateKey(keyboard.Button1Key, IsButton1Down, ref _isButton1KeyDown, ref _wasButton1KeyDown);
|
||||||
UpdateKey(keyboard.Button2Key, IsButton2Down, ref _isButton2KeyDown, ref _wasButton2KeyDown);
|
UpdateKey(keyboard.Button2Key, IsButton2Down, ref _isButton2KeyDown, ref _wasButton2KeyDown);
|
||||||
|
|
||||||
if (_lastKey > 0) // repeat last key
|
if (_lastKey > 0) // repeat last key
|
||||||
{
|
{
|
||||||
long time = DateTime.UtcNow.Ticks;
|
long time = DateTime.UtcNow.Ticks;
|
||||||
if (time - _lastTime >= _repeatTime)
|
if (time - _lastTime >= _repeatTime)
|
||||||
{
|
{
|
||||||
_lastTime = time;
|
_lastTime = time;
|
||||||
_repeatTime = RepeatSpeed;
|
_repeatTime = RepeatSpeed;
|
||||||
keyboard.Latch = _lastKey;
|
keyboard.Latch = _lastKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateKey(int key, bool isActive, ref bool isKeyDown, ref bool wasKeyDown)
|
private void UpdateKey(int key, bool isActive, ref bool isKeyDown, ref bool wasKeyDown)
|
||||||
{
|
{
|
||||||
wasKeyDown = isKeyDown;
|
wasKeyDown = isKeyDown;
|
||||||
isKeyDown = (key > 0) && isActive;
|
isKeyDown = (key > 0) && isActive;
|
||||||
|
|
||||||
if (isKeyDown != wasKeyDown)
|
if (isKeyDown != wasKeyDown)
|
||||||
{
|
{
|
||||||
if (isKeyDown)
|
if (isKeyDown)
|
||||||
{
|
{
|
||||||
_lastKey = key;
|
_lastKey = key;
|
||||||
_lastTime = DateTime.UtcNow.Ticks;
|
_lastTime = DateTime.UtcNow.Ticks;
|
||||||
_repeatTime = RepeatDelay;
|
_repeatTime = RepeatDelay;
|
||||||
Machine.Keyboard.Latch = key;
|
Machine.Keyboard.Latch = key;
|
||||||
}
|
}
|
||||||
else if (key == _lastKey)
|
else if (key == _lastKey)
|
||||||
{
|
{
|
||||||
_lastKey = 0;
|
_lastKey = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Paddle0 { get; protected set; }
|
public int Paddle0 { get; protected set; }
|
||||||
public int Paddle1 { get; protected set; }
|
public int Paddle1 { get; protected set; }
|
||||||
public int Paddle2 { get; protected set; }
|
public int Paddle2 { get; protected set; }
|
||||||
public int Paddle3 { get; protected set; }
|
public int Paddle3 { get; protected set; }
|
||||||
|
|
||||||
public bool IsJoystick0Up { get; protected set; }
|
public bool IsJoystick0Up { get; protected set; }
|
||||||
public bool IsJoystick0Left { get; protected set; }
|
public bool IsJoystick0Left { get; protected set; }
|
||||||
public bool IsJoystick0Right { get; protected set; }
|
public bool IsJoystick0Right { get; protected set; }
|
||||||
public bool IsJoystick0Down { get; protected set; }
|
public bool IsJoystick0Down { get; protected set; }
|
||||||
|
|
||||||
public bool IsJoystick1Up { get; protected set; }
|
public bool IsJoystick1Up { get; protected set; }
|
||||||
public bool IsJoystick1Left { get; protected set; }
|
public bool IsJoystick1Left { get; protected set; }
|
||||||
public bool IsJoystick1Right { get; protected set; }
|
public bool IsJoystick1Right { get; protected set; }
|
||||||
public bool IsJoystick1Down { get; protected set; }
|
public bool IsJoystick1Down { get; protected set; }
|
||||||
|
|
||||||
public bool IsButton0Down { get; protected set; }
|
public bool IsButton0Down { get; protected set; }
|
||||||
public bool IsButton1Down { get; protected set; }
|
public bool IsButton1Down { get; protected set; }
|
||||||
public bool IsButton2Down { get; protected set; }
|
public bool IsButton2Down { get; protected set; }
|
||||||
|
|
||||||
private static readonly long RepeatDelay = TimeSpan.FromMilliseconds(500).Ticks;
|
private static readonly long RepeatDelay = TimeSpan.FromMilliseconds(500).Ticks;
|
||||||
private static readonly long RepeatSpeed = TimeSpan.FromMilliseconds(32).Ticks;
|
private static readonly long RepeatSpeed = TimeSpan.FromMilliseconds(32).Ticks;
|
||||||
|
|
||||||
private bool _isJoystick0UpLeftKeyDown;
|
private bool _isJoystick0UpLeftKeyDown;
|
||||||
private bool _isJoystick0UpKeyDown;
|
private bool _isJoystick0UpKeyDown;
|
||||||
private bool _isJoystick0UpRightKeyDown;
|
private bool _isJoystick0UpRightKeyDown;
|
||||||
private bool _isJoystick0LeftKeyDown;
|
private bool _isJoystick0LeftKeyDown;
|
||||||
private bool _isJoystick0RightKeyDown;
|
private bool _isJoystick0RightKeyDown;
|
||||||
private bool _isJoystick0DownLeftKeyDown;
|
private bool _isJoystick0DownLeftKeyDown;
|
||||||
private bool _isJoystick0DownKeyDown;
|
private bool _isJoystick0DownKeyDown;
|
||||||
private bool _isJoystick0DownRightKeyDown;
|
private bool _isJoystick0DownRightKeyDown;
|
||||||
private bool _isJoystick1UpLeftKeyDown;
|
private bool _isJoystick1UpLeftKeyDown;
|
||||||
private bool _isJoystick1UpKeyDown;
|
private bool _isJoystick1UpKeyDown;
|
||||||
private bool _isJoystick1UpRightKeyDown;
|
private bool _isJoystick1UpRightKeyDown;
|
||||||
private bool _isJoystick1LeftKeyDown;
|
private bool _isJoystick1LeftKeyDown;
|
||||||
private bool _isJoystick1RightKeyDown;
|
private bool _isJoystick1RightKeyDown;
|
||||||
private bool _isJoystick1DownLeftKeyDown;
|
private bool _isJoystick1DownLeftKeyDown;
|
||||||
private bool _isJoystick1DownKeyDown;
|
private bool _isJoystick1DownKeyDown;
|
||||||
private bool _isJoystick1DownRightKeyDown;
|
private bool _isJoystick1DownRightKeyDown;
|
||||||
private bool _isButton0KeyDown;
|
private bool _isButton0KeyDown;
|
||||||
private bool _isButton1KeyDown;
|
private bool _isButton1KeyDown;
|
||||||
private bool _isButton2KeyDown;
|
private bool _isButton2KeyDown;
|
||||||
|
|
||||||
private bool _wasJoystick0UpLeftKeyDown;
|
private bool _wasJoystick0UpLeftKeyDown;
|
||||||
private bool _wasJoystick0UpKeyDown;
|
private bool _wasJoystick0UpKeyDown;
|
||||||
private bool _wasJoystick0UpRightKeyDown;
|
private bool _wasJoystick0UpRightKeyDown;
|
||||||
private bool _wasJoystick0LeftKeyDown;
|
private bool _wasJoystick0LeftKeyDown;
|
||||||
private bool _wasJoystick0RightKeyDown;
|
private bool _wasJoystick0RightKeyDown;
|
||||||
private bool _wasJoystick0DownLeftKeyDown;
|
private bool _wasJoystick0DownLeftKeyDown;
|
||||||
private bool _wasJoystick0DownKeyDown;
|
private bool _wasJoystick0DownKeyDown;
|
||||||
private bool _wasJoystick0DownRightKeyDown;
|
private bool _wasJoystick0DownRightKeyDown;
|
||||||
private bool _wasJoystick1UpLeftKeyDown;
|
private bool _wasJoystick1UpLeftKeyDown;
|
||||||
private bool _wasJoystick1UpKeyDown;
|
private bool _wasJoystick1UpKeyDown;
|
||||||
private bool _wasJoystick1UpRightKeyDown;
|
private bool _wasJoystick1UpRightKeyDown;
|
||||||
private bool _wasJoystick1LeftKeyDown;
|
private bool _wasJoystick1LeftKeyDown;
|
||||||
private bool _wasJoystick1RightKeyDown;
|
private bool _wasJoystick1RightKeyDown;
|
||||||
private bool _wasJoystick1DownLeftKeyDown;
|
private bool _wasJoystick1DownLeftKeyDown;
|
||||||
private bool _wasJoystick1DownKeyDown;
|
private bool _wasJoystick1DownKeyDown;
|
||||||
private bool _wasJoystick1DownRightKeyDown;
|
private bool _wasJoystick1DownRightKeyDown;
|
||||||
private bool _wasButton0KeyDown;
|
private bool _wasButton0KeyDown;
|
||||||
private bool _wasButton1KeyDown;
|
private bool _wasButton1KeyDown;
|
||||||
private bool _wasButton2KeyDown;
|
private bool _wasButton2KeyDown;
|
||||||
|
|
||||||
private int _lastKey;
|
private int _lastKey;
|
||||||
private long _lastTime;
|
private long _lastTime;
|
||||||
private long _repeatTime;
|
private long _repeatTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,53 +1,53 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.IsolatedStorage;
|
using System.IO.IsolatedStorage;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public class IsolatedStorageService : StorageService
|
public class IsolatedStorageService : StorageService
|
||||||
{
|
{
|
||||||
public IsolatedStorageService(Machine machine) :
|
public IsolatedStorageService(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnLoad(string fileName, Action<Stream> reader)
|
protected override void OnLoad(string fileName, Action<Stream> reader)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var store = GetStore())
|
using (var store = GetStore())
|
||||||
{
|
{
|
||||||
using (var stream = store.OpenFile(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
using (var stream = store.OpenFile(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
{
|
{
|
||||||
reader(stream);
|
reader(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnSave(string fileName, Action<Stream> writer)
|
protected override void OnSave(string fileName, Action<Stream> writer)
|
||||||
{
|
{
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var store = GetStore())
|
using (var store = GetStore())
|
||||||
{
|
{
|
||||||
using (var stream = store.OpenFile(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
using (var stream = store.OpenFile(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||||
{
|
{
|
||||||
writer(stream);
|
writer(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
|
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
|
||||||
protected virtual IsolatedStorageFile GetStore()
|
protected virtual IsolatedStorageFile GetStore()
|
||||||
{
|
{
|
||||||
return IsolatedStorageFile.GetUserStoreForApplication();
|
return IsolatedStorageFile.GetUserStoreForApplication();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public abstract class KeyboardService : MachineService
|
public abstract class KeyboardService : MachineService
|
||||||
{
|
{
|
||||||
protected KeyboardService(Machine machine) :
|
protected KeyboardService(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract bool IsKeyDown(int key);
|
public abstract bool IsKeyDown(int key);
|
||||||
|
|
||||||
public virtual void Update() // main thread
|
public virtual void Update() // main thread
|
||||||
{
|
{
|
||||||
var keyboard = Machine.Keyboard;
|
var keyboard = Machine.Keyboard;
|
||||||
|
|
||||||
if (IsResetKeyDown && !keyboard.DisableResetKey)
|
if (IsResetKeyDown && !keyboard.DisableResetKey)
|
||||||
{
|
{
|
||||||
if (!_resetKeyDown)
|
if (!_resetKeyDown)
|
||||||
{
|
{
|
||||||
_resetKeyDown = true; // entering reset; pause until key released
|
_resetKeyDown = true; // entering reset; pause until key released
|
||||||
Machine.Pause();
|
Machine.Pause();
|
||||||
Machine.Reset();
|
Machine.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_resetKeyDown)
|
else if (_resetKeyDown)
|
||||||
{
|
{
|
||||||
_resetKeyDown = false; // leaving reset
|
_resetKeyDown = false; // leaving reset
|
||||||
Machine.Unpause();
|
Machine.Unpause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAnyKeyDown { get; protected set; }
|
public bool IsAnyKeyDown { get; protected set; }
|
||||||
public bool IsControlKeyDown { get; protected set; }
|
public bool IsControlKeyDown { get; protected set; }
|
||||||
public bool IsShiftKeyDown { get; protected set; }
|
public bool IsShiftKeyDown { get; protected set; }
|
||||||
|
|
||||||
public bool IsOpenAppleKeyDown { get; protected set; }
|
public bool IsOpenAppleKeyDown { get; protected set; }
|
||||||
public bool IsCloseAppleKeyDown { get; protected set; }
|
public bool IsCloseAppleKeyDown { get; protected set; }
|
||||||
|
|
||||||
protected bool IsResetKeyDown { get; set; }
|
protected bool IsResetKeyDown { get; set; }
|
||||||
|
|
||||||
private bool _resetKeyDown;
|
private bool _resetKeyDown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
using System;
|
using System;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public abstract class MachineService : DisposableBase
|
public abstract class MachineService : DisposableBase
|
||||||
{
|
{
|
||||||
protected MachineService(Machine machine)
|
protected MachineService(Machine machine)
|
||||||
{
|
{
|
||||||
Machine = machine;
|
Machine = machine;
|
||||||
|
|
||||||
_debugService = new Lazy<DebugService>(() => Machine.Services.GetService<DebugService>());
|
_debugService = new Lazy<DebugService>(() => Machine.Services.GetService<DebugService>());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Machine Machine { get; private set; }
|
protected Machine Machine { get; private set; }
|
||||||
protected DebugService DebugService { get { return _debugService.Value; } }
|
protected DebugService DebugService { get { return _debugService.Value; } }
|
||||||
|
|
||||||
private Lazy<DebugService> _debugService;
|
private Lazy<DebugService> _debugService;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +1,51 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Jellyfish.Virtu.Properties;
|
using Jellyfish.Virtu.Properties;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class MachineServices : IServiceProvider
|
public sealed class MachineServices : IServiceProvider
|
||||||
{
|
{
|
||||||
public void AddService(Type serviceType, MachineService serviceProvider)
|
public void AddService(Type serviceType, MachineService serviceProvider)
|
||||||
{
|
{
|
||||||
if (serviceType == null)
|
if (serviceType == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("serviceType");
|
throw new ArgumentNullException("serviceType");
|
||||||
}
|
}
|
||||||
if (_serviceProviders.ContainsKey(serviceType))
|
if (_serviceProviders.ContainsKey(serviceType))
|
||||||
{
|
{
|
||||||
throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, Strings.ServiceAlreadyPresent, serviceType.FullName), "serviceType");
|
throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, Strings.ServiceAlreadyPresent, serviceType.FullName), "serviceType");
|
||||||
}
|
}
|
||||||
if (serviceProvider == null)
|
if (serviceProvider == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("serviceProvider");
|
throw new ArgumentNullException("serviceProvider");
|
||||||
}
|
}
|
||||||
if (!serviceType.IsAssignableFrom(serviceProvider.GetType()))
|
if (!serviceType.IsAssignableFrom(serviceProvider.GetType()))
|
||||||
{
|
{
|
||||||
throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, Strings.ServiceMustBeAssignable, serviceType.FullName, serviceProvider.GetType().FullName));
|
throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, Strings.ServiceMustBeAssignable, serviceType.FullName, serviceProvider.GetType().FullName));
|
||||||
}
|
}
|
||||||
|
|
||||||
_serviceProviders.Add(serviceType, serviceProvider);
|
_serviceProviders.Add(serviceType, serviceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
|
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
|
||||||
public T GetService<T>()
|
public T GetService<T>()
|
||||||
{
|
{
|
||||||
return (T)((IServiceProvider)this).GetService(typeof(T));
|
return (T)((IServiceProvider)this).GetService(typeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveService(Type serviceType)
|
public void RemoveService(Type serviceType)
|
||||||
{
|
{
|
||||||
_serviceProviders.Remove(serviceType);
|
_serviceProviders.Remove(serviceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
object IServiceProvider.GetService(Type serviceType)
|
object IServiceProvider.GetService(Type serviceType)
|
||||||
{
|
{
|
||||||
return _serviceProviders.ContainsKey(serviceType) ? _serviceProviders[serviceType] : null;
|
return _serviceProviders.ContainsKey(serviceType) ? _serviceProviders[serviceType] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<Type, MachineService> _serviceProviders = new Dictionary<Type, MachineService>();
|
private Dictionary<Type, MachineService> _serviceProviders = new Dictionary<Type, MachineService>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,213 +1,213 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using Jellyfish.Virtu.Properties;
|
using Jellyfish.Virtu.Properties;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public abstract class StorageService : MachineService
|
public abstract class StorageService : MachineService
|
||||||
{
|
{
|
||||||
protected StorageService(Machine machine) :
|
protected StorageService(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||||
public bool Load(string fileName, Action<Stream> reader)
|
public bool Load(string fileName, Action<Stream> reader)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage("Loading file '{0}'", fileName);
|
DebugService.WriteMessage("Loading file '{0}'", fileName);
|
||||||
OnLoad(fileName, reader);
|
OnLoad(fileName, reader);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage(ex.ToString());
|
DebugService.WriteMessage(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WINDOWS
|
#if !WINDOWS
|
||||||
[SecuritySafeCritical]
|
[SecuritySafeCritical]
|
||||||
#endif
|
#endif
|
||||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||||
public static bool LoadFile(string fileName, Action<Stream> reader)
|
public static bool LoadFile(string fileName, Action<Stream> reader)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage("Loading file '{0}'", fileName);
|
DebugService.Default.WriteMessage("Loading file '{0}'", fileName);
|
||||||
using (var stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
using (var stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
{
|
{
|
||||||
reader(stream);
|
reader(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage(ex.ToString());
|
DebugService.Default.WriteMessage(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WINDOWS
|
#if !WINDOWS
|
||||||
[SecuritySafeCritical]
|
[SecuritySafeCritical]
|
||||||
#endif
|
#endif
|
||||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||||
public static bool LoadFile(FileInfo fileInfo, Action<Stream> reader)
|
public static bool LoadFile(FileInfo fileInfo, Action<Stream> reader)
|
||||||
{
|
{
|
||||||
if (fileInfo == null)
|
if (fileInfo == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("fileInfo");
|
throw new ArgumentNullException("fileInfo");
|
||||||
}
|
}
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage("Loading file '{0}'", fileInfo.Name);
|
DebugService.Default.WriteMessage("Loading file '{0}'", fileInfo.Name);
|
||||||
using (var stream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
|
using (var stream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
{
|
{
|
||||||
reader(stream);
|
reader(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage(ex.ToString());
|
DebugService.Default.WriteMessage(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||||
public static bool LoadResource(string resourceName, Action<Stream> reader)
|
public static bool LoadResource(string resourceName, Action<Stream> reader)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage("Loading resource '{0}'", resourceName);
|
DebugService.Default.WriteMessage("Loading resource '{0}'", resourceName);
|
||||||
using (var stream = GetResourceStream(resourceName))
|
using (var stream = GetResourceStream(resourceName))
|
||||||
{
|
{
|
||||||
reader(stream);
|
reader(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage(ex.ToString());
|
DebugService.Default.WriteMessage(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||||
public bool Save(string fileName, Action<Stream> writer)
|
public bool Save(string fileName, Action<Stream> writer)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage("Saving file '{0}'", fileName);
|
DebugService.WriteMessage("Saving file '{0}'", fileName);
|
||||||
OnSave(fileName, writer);
|
OnSave(fileName, writer);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
DebugService.WriteMessage(ex.ToString());
|
DebugService.WriteMessage(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WINDOWS
|
#if !WINDOWS
|
||||||
[SecuritySafeCritical]
|
[SecuritySafeCritical]
|
||||||
#endif
|
#endif
|
||||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||||
public static bool SaveFile(string fileName, Action<Stream> writer)
|
public static bool SaveFile(string fileName, Action<Stream> writer)
|
||||||
{
|
{
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage("Saving file '{0}'", fileName);
|
DebugService.Default.WriteMessage("Saving file '{0}'", fileName);
|
||||||
using (var stream = File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
using (var stream = File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||||
{
|
{
|
||||||
writer(stream);
|
writer(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage(ex.ToString());
|
DebugService.Default.WriteMessage(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !WINDOWS
|
#if !WINDOWS
|
||||||
[SecuritySafeCritical]
|
[SecuritySafeCritical]
|
||||||
#endif
|
#endif
|
||||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||||
public static bool SaveFile(FileInfo fileInfo, Action<Stream> writer)
|
public static bool SaveFile(FileInfo fileInfo, Action<Stream> writer)
|
||||||
{
|
{
|
||||||
if (fileInfo == null)
|
if (fileInfo == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("fileInfo");
|
throw new ArgumentNullException("fileInfo");
|
||||||
}
|
}
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage("Saving file '{0}'", fileInfo.Name);
|
DebugService.Default.WriteMessage("Saving file '{0}'", fileInfo.Name);
|
||||||
using (var stream = fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.None))
|
using (var stream = fileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.None))
|
||||||
{
|
{
|
||||||
writer(stream);
|
writer(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
DebugService.Default.WriteMessage(ex.ToString());
|
DebugService.Default.WriteMessage(ex.ToString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void OnLoad(string fileName, Action<Stream> reader);
|
protected abstract void OnLoad(string fileName, Action<Stream> reader);
|
||||||
|
|
||||||
protected abstract void OnSave(string fileName, Action<Stream> writer);
|
protected abstract void OnSave(string fileName, Action<Stream> writer);
|
||||||
|
|
||||||
private static Stream GetResourceStream(string resourceName)
|
private static Stream GetResourceStream(string resourceName)
|
||||||
{
|
{
|
||||||
resourceName = "Jellyfish.Virtu." + resourceName.Replace('/', '.');
|
resourceName = "Jellyfish.Virtu." + resourceName.Replace('/', '.');
|
||||||
var resourceStream = typeof(StorageService).Assembly.GetManifestResourceStream(resourceName);
|
var resourceStream = typeof(StorageService).Assembly.GetManifestResourceStream(resourceName);
|
||||||
if (resourceStream == null)
|
if (resourceStream == null)
|
||||||
{
|
{
|
||||||
throw new FileNotFoundException(string.Format(CultureInfo.CurrentUICulture, Strings.ResourceNotFound, resourceName));
|
throw new FileNotFoundException(string.Format(CultureInfo.CurrentUICulture, Strings.ResourceNotFound, resourceName));
|
||||||
}
|
}
|
||||||
|
|
||||||
return resourceStream;
|
return resourceStream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public abstract class VideoService : MachineService
|
public abstract class VideoService : MachineService
|
||||||
{
|
{
|
||||||
protected VideoService(Machine machine) :
|
protected VideoService(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SetFullScreen(bool isFullScreen)
|
public virtual void SetFullScreen(bool isFullScreen)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void SetPixel(int x, int y, uint color);
|
public abstract void SetPixel(int x, int y, uint color);
|
||||||
public abstract void Update(); // main thread
|
public abstract void Update(); // main thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,270 +1,270 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProductVersion>8.0.50727</ProductVersion>
|
<ProductVersion>8.0.50727</ProductVersion>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<ProjectGuid>{F8DB6D3A-807D-4E2D-92D5-469273E088DA}</ProjectGuid>
|
<ProjectGuid>{F8DB6D3A-807D-4E2D-92D5-469273E088DA}</ProjectGuid>
|
||||||
<ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
<ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>Jellyfish.Virtu</RootNamespace>
|
<RootNamespace>Jellyfish.Virtu</RootNamespace>
|
||||||
<AssemblyName>Jellyfish.Virtu</AssemblyName>
|
<AssemblyName>Jellyfish.Virtu</AssemblyName>
|
||||||
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
|
<TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
|
||||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||||
<TargetFrameworkProfile />
|
<TargetFrameworkProfile />
|
||||||
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
|
<SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
|
||||||
<SilverlightApplication>true</SilverlightApplication>
|
<SilverlightApplication>true</SilverlightApplication>
|
||||||
<SupportedCultures>
|
<SupportedCultures>
|
||||||
</SupportedCultures>
|
</SupportedCultures>
|
||||||
<XapOutputs>true</XapOutputs>
|
<XapOutputs>true</XapOutputs>
|
||||||
<GenerateSilverlightManifest>true</GenerateSilverlightManifest>
|
<GenerateSilverlightManifest>true</GenerateSilverlightManifest>
|
||||||
<XapFilename>Jellyfish.Virtu.xap</XapFilename>
|
<XapFilename>Jellyfish.Virtu.xap</XapFilename>
|
||||||
<SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate>
|
<SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate>
|
||||||
<SilverlightAppEntry>Jellyfish.Virtu.MainApp</SilverlightAppEntry>
|
<SilverlightAppEntry>Jellyfish.Virtu.MainApp</SilverlightAppEntry>
|
||||||
<TestPageFileName>Jellyfish.Virtu.html</TestPageFileName>
|
<TestPageFileName>Jellyfish.Virtu.html</TestPageFileName>
|
||||||
<CreateTestPage>true</CreateTestPage>
|
<CreateTestPage>true</CreateTestPage>
|
||||||
<ValidateXaml>true</ValidateXaml>
|
<ValidateXaml>true</ValidateXaml>
|
||||||
<EnableOutOfBrowser>true</EnableOutOfBrowser>
|
<EnableOutOfBrowser>true</EnableOutOfBrowser>
|
||||||
<OutOfBrowserSettingsFile>Properties\OutOfBrowserSettings.xml</OutOfBrowserSettingsFile>
|
<OutOfBrowserSettingsFile>Properties\OutOfBrowserSettings.xml</OutOfBrowserSettingsFile>
|
||||||
<UsePlatformExtensions>false</UsePlatformExtensions>
|
<UsePlatformExtensions>false</UsePlatformExtensions>
|
||||||
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
|
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
|
||||||
<LinkedServerProject>
|
<LinkedServerProject>
|
||||||
</LinkedServerProject>
|
</LinkedServerProject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- This property group is only here to support building this project using the
|
<!-- This property group is only here to support building this project using the
|
||||||
MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs
|
MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs
|
||||||
to set the TargetFrameworkVersion to v3.5 -->
|
to set the TargetFrameworkVersion to v3.5 -->
|
||||||
<PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
|
<PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>bin\</OutputPath>
|
<OutputPath>bin\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE;SILVERLIGHT;CODE_ANALYSIS</DefineConstants>
|
<DefineConstants>DEBUG;TRACE;SILVERLIGHT;CODE_ANALYSIS</DefineConstants>
|
||||||
<NoStdLib>true</NoStdLib>
|
<NoStdLib>true</NoStdLib>
|
||||||
<NoConfig>true</NoConfig>
|
<NoConfig>true</NoConfig>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<OutputPath>bin\</OutputPath>
|
<OutputPath>bin\</OutputPath>
|
||||||
<DefineConstants>TRACE;SILVERLIGHT;CODE_ANALYSIS</DefineConstants>
|
<DefineConstants>TRACE;SILVERLIGHT;CODE_ANALYSIS</DefineConstants>
|
||||||
<NoStdLib>true</NoStdLib>
|
<NoStdLib>true</NoStdLib>
|
||||||
<NoConfig>true</NoConfig>
|
<NoConfig>true</NoConfig>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SignAssembly>false</SignAssembly>
|
<SignAssembly>false</SignAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyOriginatorKeyFile>..\..\..\Jellyfish\StrongName.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>..\..\..\Jellyfish\StrongName.snk</AssemblyOriginatorKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SignManifests>false</SignManifests>
|
<SignManifests>false</SignManifests>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ManifestTimestampUrl>http://timestamp.verisign.com/scripts/timestamp.dll</ManifestTimestampUrl>
|
<ManifestTimestampUrl>http://timestamp.verisign.com/scripts/timestamp.dll</ManifestTimestampUrl>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ManifestCertificateThumbprint>7E57BBFFA7D9A57530AC8A09E5236FE0AAB041C2</ManifestCertificateThumbprint>
|
<ManifestCertificateThumbprint>7E57BBFFA7D9A57530AC8A09E5236FE0AAB041C2</ManifestCertificateThumbprint>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ManifestKeyFile>..\..\..\Jellyfish\CodeSign.pfx</ManifestKeyFile>
|
<ManifestKeyFile>..\..\..\Jellyfish\CodeSign.pfx</ManifestKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="mscorlib" />
|
<Reference Include="mscorlib" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Net" />
|
<Reference Include="System.Net" />
|
||||||
<Reference Include="System.Windows" />
|
<Reference Include="System.Windows" />
|
||||||
<Reference Include="System.Windows.Browser" />
|
<Reference Include="System.Windows.Browser" />
|
||||||
<Reference Include="System.Windows.Controls" />
|
<Reference Include="System.Windows.Controls" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ApplicationDefinition Include="MainApp.xaml">
|
<ApplicationDefinition Include="MainApp.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
<Page Include="MainPage.xaml">
|
<Page Include="MainPage.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
<Compile Include="MainApp.xaml.cs">
|
<Compile Include="MainApp.xaml.cs">
|
||||||
<DependentUpon>MainApp.xaml</DependentUpon>
|
<DependentUpon>MainApp.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="MainPage.xaml.cs">
|
<Compile Include="MainPage.xaml.cs">
|
||||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\Cassette.cs">
|
<Compile Include="..\Cassette.cs">
|
||||||
<Link>Core\Cassette.cs</Link>
|
<Link>Core\Cassette.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Cpu.cs">
|
<Compile Include="..\Cpu.cs">
|
||||||
<Link>Core\Cpu.cs</Link>
|
<Link>Core\Cpu.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\CpuData.cs">
|
<Compile Include="..\CpuData.cs">
|
||||||
<Link>Core\CpuData.cs</Link>
|
<Link>Core\CpuData.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Disk525.cs">
|
<Compile Include="..\Disk525.cs">
|
||||||
<Link>Core\Disk525.cs</Link>
|
<Link>Core\Disk525.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskDsk.cs">
|
<Compile Include="..\DiskDsk.cs">
|
||||||
<Link>Core\DiskDsk.cs</Link>
|
<Link>Core\DiskDsk.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskIIController.cs">
|
<Compile Include="..\DiskIIController.cs">
|
||||||
<Link>Core\DiskIIController.cs</Link>
|
<Link>Core\DiskIIController.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskIIDrive.cs">
|
<Compile Include="..\DiskIIDrive.cs">
|
||||||
<Link>Core\DiskIIDrive.cs</Link>
|
<Link>Core\DiskIIDrive.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskNib.cs">
|
<Compile Include="..\DiskNib.cs">
|
||||||
<Link>Core\DiskNib.cs</Link>
|
<Link>Core\DiskNib.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\GamePort.cs">
|
<Compile Include="..\GamePort.cs">
|
||||||
<Link>Core\GamePort.cs</Link>
|
<Link>Core\GamePort.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\GlobalSuppressions.cs">
|
<Compile Include="..\GlobalSuppressions.cs">
|
||||||
<Link>GlobalSuppressions.cs</Link>
|
<Link>GlobalSuppressions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Keyboard.cs">
|
<Compile Include="..\Keyboard.cs">
|
||||||
<Link>Core\Keyboard.cs</Link>
|
<Link>Core\Keyboard.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Machine.cs">
|
<Compile Include="..\Machine.cs">
|
||||||
<Link>Core\Machine.cs</Link>
|
<Link>Core\Machine.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MachineComponent.cs">
|
<Compile Include="..\MachineComponent.cs">
|
||||||
<Link>Core\MachineComponent.cs</Link>
|
<Link>Core\MachineComponent.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MachineEvents.cs">
|
<Compile Include="..\MachineEvents.cs">
|
||||||
<Link>Core\MachineEvents.cs</Link>
|
<Link>Core\MachineEvents.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Memory.cs">
|
<Compile Include="..\Memory.cs">
|
||||||
<Link>Core\Memory.cs</Link>
|
<Link>Core\Memory.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MemoryData.cs">
|
<Compile Include="..\MemoryData.cs">
|
||||||
<Link>Core\MemoryData.cs</Link>
|
<Link>Core\MemoryData.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\NoSlotClock.cs">
|
<Compile Include="..\NoSlotClock.cs">
|
||||||
<Link>Core\NoSlotClock.cs</Link>
|
<Link>Core\NoSlotClock.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\PeripheralCard.cs">
|
<Compile Include="..\PeripheralCard.cs">
|
||||||
<Link>Core\PeripheralCard.cs</Link>
|
<Link>Core\PeripheralCard.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Properties\Strings.Designer.cs">
|
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||||
<Link>Properties\Strings.Designer.cs</Link>
|
<Link>Properties\Strings.Designer.cs</Link>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Strings.resx</DependentUpon>
|
<DependentUpon>Strings.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\AudioService.cs">
|
<Compile Include="..\Services\AudioService.cs">
|
||||||
<Link>Services\AudioService.cs</Link>
|
<Link>Services\AudioService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\DebugService.cs">
|
<Compile Include="..\Services\DebugService.cs">
|
||||||
<Link>Services\DebugService.cs</Link>
|
<Link>Services\DebugService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\GamePortService.cs">
|
<Compile Include="..\Services\GamePortService.cs">
|
||||||
<Link>Services\GamePortService.cs</Link>
|
<Link>Services\GamePortService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\IsolatedStorageService.cs">
|
<Compile Include="..\Services\IsolatedStorageService.cs">
|
||||||
<Link>Services\IsolatedStorageService.cs</Link>
|
<Link>Services\IsolatedStorageService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\KeyboardService.cs">
|
<Compile Include="..\Services\KeyboardService.cs">
|
||||||
<Link>Services\KeyboardService.cs</Link>
|
<Link>Services\KeyboardService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\MachineService.cs">
|
<Compile Include="..\Services\MachineService.cs">
|
||||||
<Link>Services\MachineService.cs</Link>
|
<Link>Services\MachineService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\MachineServices.cs">
|
<Compile Include="..\Services\MachineServices.cs">
|
||||||
<Link>Services\MachineServices.cs</Link>
|
<Link>Services\MachineServices.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\StorageService.cs">
|
<Compile Include="..\Services\StorageService.cs">
|
||||||
<Link>Services\StorageService.cs</Link>
|
<Link>Services\StorageService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\VideoService.cs">
|
<Compile Include="..\Services\VideoService.cs">
|
||||||
<Link>Services\VideoService.cs</Link>
|
<Link>Services\VideoService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Speaker.cs">
|
<Compile Include="..\Speaker.cs">
|
||||||
<Link>Core\Speaker.cs</Link>
|
<Link>Core\Speaker.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Video.cs">
|
<Compile Include="..\Video.cs">
|
||||||
<Link>Core\Video.cs</Link>
|
<Link>Core\Video.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\VideoData.cs">
|
<Compile Include="..\VideoData.cs">
|
||||||
<Link>Core\VideoData.cs</Link>
|
<Link>Core\VideoData.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Services\SilverlightAudioService.cs" />
|
<Compile Include="Services\SilverlightAudioService.cs" />
|
||||||
<Compile Include="Services\SilverlightDebugService.cs" />
|
<Compile Include="Services\SilverlightDebugService.cs" />
|
||||||
<Compile Include="Services\SilverlightKeyboardService.cs" />
|
<Compile Include="Services\SilverlightKeyboardService.cs" />
|
||||||
<Compile Include="Services\SilverlightVideoService.cs" />
|
<Compile Include="Services\SilverlightVideoService.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Properties\AppManifest.xml" />
|
<None Include="Properties\AppManifest.xml" />
|
||||||
<None Include="Properties\OutOfBrowserSettings.xml" />
|
<None Include="Properties\OutOfBrowserSettings.xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="AppIcon16.png" />
|
<Content Include="AppIcon16.png" />
|
||||||
<Content Include="AppIcon32.png" />
|
<Content Include="AppIcon32.png" />
|
||||||
<Content Include="AppIcon48.png" />
|
<Content Include="AppIcon48.png" />
|
||||||
<Content Include="AppIcon128.png" />
|
<Content Include="AppIcon128.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="..\Properties\Strings.resx">
|
<EmbeddedResource Include="..\Properties\Strings.resx">
|
||||||
<Link>Properties\Strings.resx</Link>
|
<Link>Properties\Strings.resx</Link>
|
||||||
<Generator>ResXFileCodeGenerator</Generator>
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="..\Disks\Default.dsk">
|
<EmbeddedResource Include="..\Disks\Default.dsk">
|
||||||
<Link>Disks\Default.dsk</Link>
|
<Link>Disks\Default.dsk</Link>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="..\Roms\AppleIIe.rom">
|
<EmbeddedResource Include="..\Roms\AppleIIe.rom">
|
||||||
<Link>Roms\AppleIIe.rom</Link>
|
<Link>Roms\AppleIIe.rom</Link>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="..\Roms\DiskII.rom">
|
<EmbeddedResource Include="..\Roms\DiskII.rom">
|
||||||
<Link>Roms\DiskII.rom</Link>
|
<Link>Roms\DiskII.rom</Link>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
|
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
|
||||||
<Link>CustomDictionary.xml</Link>
|
<Link>CustomDictionary.xml</Link>
|
||||||
</CodeAnalysisDictionary>
|
</CodeAnalysisDictionary>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj">
|
<ProjectReference Include="..\..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj">
|
||||||
<Project>{99CA7796-B72A-4F8C-BCDB-0D688220A331}</Project>
|
<Project>{99CA7796-B72A-4F8C-BCDB-0D688220A331}</Project>
|
||||||
<Name>Jellyfish.Library.Silverlight</Name>
|
<Name>Jellyfish.Library.Silverlight</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio>
|
<VisualStudio>
|
||||||
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
|
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
|
||||||
<SilverlightProjectProperties />
|
<SilverlightProjectProperties />
|
||||||
</FlavorProperties>
|
</FlavorProperties>
|
||||||
</VisualStudio>
|
</VisualStudio>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
</Project>
|
</Project>
|
|
@ -1,26 +1,26 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2012
|
# Visual Studio 2012
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "..\..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Silverlight", "..\..\Library\Silverlight\Jellyfish.Library.Silverlight.csproj", "{99CA7796-B72A-4F8C-BCDB-0D688220A331}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Silverlight", "Jellyfish.Virtu.Silverlight.csproj", "{F8DB6D3A-807D-4E2D-92D5-469273E088DA}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Silverlight", "Jellyfish.Virtu.Silverlight.csproj", "{F8DB6D3A-807D-4E2D-92D5-469273E088DA}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
|
{99CA7796-B72A-4F8C-BCDB-0D688220A331}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.Build.0 = Release|Any CPU
|
{F8DB6D3A-807D-4E2D-92D5-469273E088DA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<jl:ApplicationBase x:Class="Jellyfish.Virtu.MainApp"
|
<jl:ApplicationBase x:Class="Jellyfish.Virtu.MainApp"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
||||||
xmlns:jv="clr-namespace:Jellyfish.Virtu;assembly=Jellyfish.Virtu">
|
xmlns:jv="clr-namespace:Jellyfish.Virtu;assembly=Jellyfish.Virtu">
|
||||||
<Application.RootVisual>
|
<Application.RootVisual>
|
||||||
<jv:MainPage />
|
<jv:MainPage />
|
||||||
</Application.RootVisual>
|
</Application.RootVisual>
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</jl:ApplicationBase>
|
</jl:ApplicationBase>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed partial class MainApp : ApplicationBase
|
public sealed partial class MainApp : ApplicationBase
|
||||||
{
|
{
|
||||||
public MainApp() :
|
public MainApp() :
|
||||||
base("Virtu")
|
base("Virtu")
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeOutOfBrowserUpdate();
|
InitializeOutOfBrowserUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
<UserControl x:Class="Jellyfish.Virtu.MainPage"
|
<UserControl x:Class="Jellyfish.Virtu.MainPage"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library">
|
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library">
|
||||||
<Grid Background="Black">
|
<Grid Background="Black">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition />
|
<RowDefinition />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button x:Name="_disk1Button" Content="Disk 1" IsTabStop="False" Margin="4,4,0,4" />
|
<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" />
|
<Button x:Name="_disk2Button" Content="Disk 2" IsTabStop="False" Margin="4,4,0,4" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<jl:FrameRateCounter Margin="0,0,4,0" HorizontalAlignment="Right" VerticalAlignment="Center" />
|
<jl:FrameRateCounter Margin="0,0,4,0" HorizontalAlignment="Right" VerticalAlignment="Center" />
|
||||||
<Grid Grid.Row="1">
|
<Grid Grid.Row="1">
|
||||||
<Image x:Name="_image" MinWidth="560" MinHeight="384" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
<Image x:Name="_image" MinWidth="560" MinHeight="384" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||||
<MediaElement x:Name="_media" />
|
<MediaElement x:Name="_media" />
|
||||||
<ScrollViewer x:Name="_debugScrollViewer" BorderThickness="0" IsTabStop="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
<ScrollViewer x:Name="_debugScrollViewer" BorderThickness="0" IsTabStop="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
||||||
<TextBlock x:Name="_debugText" FontFamily="Consolas" FontSize="12" Foreground="White" />
|
<TextBlock x:Name="_debugText" FontFamily="Consolas" FontSize="12" Foreground="White" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
@ -1,87 +1,87 @@
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using Jellyfish.Virtu.Services;
|
using Jellyfish.Virtu.Services;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed partial class MainPage : UserControl, IDisposable
|
public sealed partial class MainPage : UserControl, IDisposable
|
||||||
{
|
{
|
||||||
public MainPage()
|
public MainPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
if (!DesignerProperties.IsInDesignTool)
|
if (!DesignerProperties.IsInDesignTool)
|
||||||
{
|
{
|
||||||
_debugService = DebugService.Default;
|
_debugService = DebugService.Default;
|
||||||
_storageService = new IsolatedStorageService(_machine);
|
_storageService = new IsolatedStorageService(_machine);
|
||||||
_keyboardService = new SilverlightKeyboardService(_machine, this);
|
_keyboardService = new SilverlightKeyboardService(_machine, this);
|
||||||
_gamePortService = new GamePortService(_machine); // not connected
|
_gamePortService = new GamePortService(_machine); // not connected
|
||||||
_audioService = new SilverlightAudioService(_machine, this, _media);
|
_audioService = new SilverlightAudioService(_machine, this, _media);
|
||||||
_videoService = new SilverlightVideoService(_machine, this, _image);
|
_videoService = new SilverlightVideoService(_machine, this, _image);
|
||||||
|
|
||||||
_machine.Services.AddService(typeof(DebugService), _debugService);
|
_machine.Services.AddService(typeof(DebugService), _debugService);
|
||||||
_machine.Services.AddService(typeof(StorageService), _storageService);
|
_machine.Services.AddService(typeof(StorageService), _storageService);
|
||||||
_machine.Services.AddService(typeof(KeyboardService), _keyboardService);
|
_machine.Services.AddService(typeof(KeyboardService), _keyboardService);
|
||||||
_machine.Services.AddService(typeof(GamePortService), _gamePortService);
|
_machine.Services.AddService(typeof(GamePortService), _gamePortService);
|
||||||
_machine.Services.AddService(typeof(AudioService), _audioService);
|
_machine.Services.AddService(typeof(AudioService), _audioService);
|
||||||
_machine.Services.AddService(typeof(VideoService), _videoService);
|
_machine.Services.AddService(typeof(VideoService), _videoService);
|
||||||
|
|
||||||
Loaded += (sender, e) => _machine.Start();
|
Loaded += (sender, e) => _machine.Start();
|
||||||
CompositionTarget.Rendering += OnCompositionTargetRendering;
|
CompositionTarget.Rendering += OnCompositionTargetRendering;
|
||||||
Application.Current.Exit += (sender, e) => _machine.Stop();
|
Application.Current.Exit += (sender, e) => _machine.Stop();
|
||||||
|
|
||||||
_disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
|
_disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
|
||||||
_disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
|
_disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_machine.Dispose();
|
_machine.Dispose();
|
||||||
_debugService.Dispose();
|
_debugService.Dispose();
|
||||||
_storageService.Dispose();
|
_storageService.Dispose();
|
||||||
_keyboardService.Dispose();
|
_keyboardService.Dispose();
|
||||||
_gamePortService.Dispose();
|
_gamePortService.Dispose();
|
||||||
_audioService.Dispose();
|
_audioService.Dispose();
|
||||||
_videoService.Dispose();
|
_videoService.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteMessage(string message)
|
public void WriteMessage(string message)
|
||||||
{
|
{
|
||||||
_debugText.Text += message + Environment.NewLine;
|
_debugText.Text += message + Environment.NewLine;
|
||||||
_debugScrollViewer.UpdateLayout();
|
_debugScrollViewer.UpdateLayout();
|
||||||
_debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
|
_debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
_keyboardService.Update();
|
_keyboardService.Update();
|
||||||
_gamePortService.Update();
|
_gamePortService.Update();
|
||||||
_videoService.Update();
|
_videoService.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDiskButtonClick(int drive)
|
private void OnDiskButtonClick(int drive)
|
||||||
{
|
{
|
||||||
var dialog = new OpenFileDialog() { Filter = "Disk Files (*.do;*.dsk;*.nib;*.po)|*.do;*.dsk;*.nib;*.po|All Files (*.*)|*.*" };
|
var dialog = new OpenFileDialog() { Filter = "Disk Files (*.do;*.dsk;*.nib;*.po)|*.do;*.dsk;*.nib;*.po|All Files (*.*)|*.*" };
|
||||||
bool? result = dialog.ShowDialog();
|
bool? result = dialog.ShowDialog();
|
||||||
if (result.HasValue && result.Value)
|
if (result.HasValue && result.Value)
|
||||||
{
|
{
|
||||||
_machine.Pause();
|
_machine.Pause();
|
||||||
StorageService.LoadFile(dialog.File, stream => _machine.BootDiskII.Drives[drive].InsertDisk(dialog.File.Name, stream, false));
|
StorageService.LoadFile(dialog.File, stream => _machine.BootDiskII.Drives[drive].InsertDisk(dialog.File.Name, stream, false));
|
||||||
_machine.Unpause();
|
_machine.Unpause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Machine _machine = new Machine();
|
private Machine _machine = new Machine();
|
||||||
|
|
||||||
private DebugService _debugService;
|
private DebugService _debugService;
|
||||||
private StorageService _storageService;
|
private StorageService _storageService;
|
||||||
private KeyboardService _keyboardService;
|
private KeyboardService _keyboardService;
|
||||||
private GamePortService _gamePortService;
|
private GamePortService _gamePortService;
|
||||||
private AudioService _audioService;
|
private AudioService _audioService;
|
||||||
private VideoService _videoService;
|
private VideoService _videoService;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
|
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<Deployment.Parts>
|
<Deployment.Parts>
|
||||||
</Deployment.Parts>
|
</Deployment.Parts>
|
||||||
</Deployment>
|
</Deployment>
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Resources;
|
using System.Resources;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
using Jellyfish.Virtu;
|
using Jellyfish.Virtu;
|
||||||
|
|
||||||
[assembly: AssemblyTitle("Virtu")]
|
[assembly: AssemblyTitle("Virtu")]
|
||||||
[assembly: AssemblyDescription("Apple IIe Emulator")]
|
[assembly: AssemblyDescription("Apple IIe Emulator")]
|
||||||
[assembly: AssemblyProduct("Jellyfish.Virtu.Silverlight")]
|
[assembly: AssemblyProduct("Jellyfish.Virtu.Silverlight")]
|
||||||
[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
|
[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")]
|
[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")]
|
||||||
[assembly: AssemblyMetadata("Developers", "Sean Fausett & Nick Westgate")]
|
[assembly: AssemblyMetadata("Developers", "Sean Fausett & Nick Westgate")]
|
||||||
|
|
||||||
[assembly: AssemblyVersion(Machine.Version)]
|
[assembly: AssemblyVersion(Machine.Version)]
|
||||||
[assembly: AssemblyFileVersion(Machine.Version)]
|
[assembly: AssemblyFileVersion(Machine.Version)]
|
||||||
[assembly: AssemblyInformationalVersion(Machine.Version)]
|
[assembly: AssemblyInformationalVersion(Machine.Version)]
|
||||||
|
|
||||||
[assembly: CLSCompliant(false)]
|
[assembly: CLSCompliant(false)]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
[assembly: Guid("89a50370-1ed9-4cf1-ad08-043b6e6f3c90")]
|
[assembly: Guid("89a50370-1ed9-4cf1-ad08-043b6e6f3c90")]
|
||||||
|
|
||||||
[assembly: NeutralResourcesLanguage("en")]
|
[assembly: NeutralResourcesLanguage("en")]
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<OutOfBrowserSettings ShortName="Virtu" EnableGPUAcceleration="False" ShowInstallMenuItem="True">
|
<OutOfBrowserSettings ShortName="Virtu" EnableGPUAcceleration="False" ShowInstallMenuItem="True">
|
||||||
<OutOfBrowserSettings.Blurb>Apple IIe Emulator</OutOfBrowserSettings.Blurb>
|
<OutOfBrowserSettings.Blurb>Apple IIe Emulator</OutOfBrowserSettings.Blurb>
|
||||||
<OutOfBrowserSettings.WindowSettings>
|
<OutOfBrowserSettings.WindowSettings>
|
||||||
<WindowSettings Title="Virtu" />
|
<WindowSettings Title="Virtu" />
|
||||||
</OutOfBrowserSettings.WindowSettings>
|
</OutOfBrowserSettings.WindowSettings>
|
||||||
<OutOfBrowserSettings.SecuritySettings>
|
<OutOfBrowserSettings.SecuritySettings>
|
||||||
<SecuritySettings ElevatedPermissions="Required" />
|
<SecuritySettings ElevatedPermissions="Required" />
|
||||||
</OutOfBrowserSettings.SecuritySettings>
|
</OutOfBrowserSettings.SecuritySettings>
|
||||||
<OutOfBrowserSettings.Icons>
|
<OutOfBrowserSettings.Icons>
|
||||||
<Icon Size="16,16">AppIcon16.png</Icon>
|
<Icon Size="16,16">AppIcon16.png</Icon>
|
||||||
<Icon Size="32,32">AppIcon32.png</Icon>
|
<Icon Size="32,32">AppIcon32.png</Icon>
|
||||||
<Icon Size="48,48">AppIcon48.png</Icon>
|
<Icon Size="48,48">AppIcon48.png</Icon>
|
||||||
<Icon Size="128,128">AppIcon128.png</Icon>
|
<Icon Size="128,128">AppIcon128.png</Icon>
|
||||||
</OutOfBrowserSettings.Icons>
|
</OutOfBrowserSettings.Icons>
|
||||||
</OutOfBrowserSettings>
|
</OutOfBrowserSettings>
|
|
@ -1,59 +1,59 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class SilverlightAudioService : AudioService
|
public sealed class SilverlightAudioService : AudioService
|
||||||
{
|
{
|
||||||
public SilverlightAudioService(Machine machine, UserControl page, MediaElement media) :
|
public SilverlightAudioService(Machine machine, UserControl page, MediaElement media) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("page");
|
throw new ArgumentNullException("page");
|
||||||
}
|
}
|
||||||
if (media == null)
|
if (media == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("media");
|
throw new ArgumentNullException("media");
|
||||||
}
|
}
|
||||||
|
|
||||||
_media = media;
|
_media = media;
|
||||||
_mediaSource = new WaveMediaStreamSource(SampleRate, SampleChannels, SampleBits, SampleSize, SampleLatency, OnMediaSourceUpdate);
|
_mediaSource = new WaveMediaStreamSource(SampleRate, SampleChannels, SampleBits, SampleSize, SampleLatency, OnMediaSourceUpdate);
|
||||||
_media.SetSource(_mediaSource);
|
_media.SetSource(_mediaSource);
|
||||||
|
|
||||||
page.Loaded += (sender, e) => _media.Play();
|
page.Loaded += (sender, e) => _media.Play();
|
||||||
page.Unloaded += (sender, e) => _media.Stop();
|
page.Unloaded += (sender, e) => _media.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetVolume(float volume)
|
public override void SetVolume(float volume)
|
||||||
{
|
{
|
||||||
_media.Dispatcher.Send(() => _media.Volume = volume);
|
_media.Dispatcher.Send(() => _media.Volume = volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
_mediaSource.Dispose();
|
_mediaSource.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMediaSourceUpdate(byte[] buffer, int bufferSize) // audio thread
|
private void OnMediaSourceUpdate(byte[] buffer, int bufferSize) // audio thread
|
||||||
{
|
{
|
||||||
//if (_count++ % (1000 / SampleLatency) == 0)
|
//if (_count++ % (1000 / SampleLatency) == 0)
|
||||||
//{
|
//{
|
||||||
// DebugService.WriteLine("OnMediaSourceUpdate");
|
// DebugService.WriteLine("OnMediaSourceUpdate");
|
||||||
//}
|
//}
|
||||||
|
|
||||||
Buffer.BlockCopy(Source, 0, buffer, 0, bufferSize);
|
Buffer.BlockCopy(Source, 0, buffer, 0, bufferSize);
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private MediaElement _media;
|
private MediaElement _media;
|
||||||
private WaveMediaStreamSource _mediaSource;
|
private WaveMediaStreamSource _mediaSource;
|
||||||
//private int _count;
|
//private int _count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
using System;
|
using System;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class SilverlightDebugService : DebugService
|
public sealed class SilverlightDebugService : DebugService
|
||||||
{
|
{
|
||||||
public SilverlightDebugService(Machine machine, MainPage page) :
|
public SilverlightDebugService(Machine machine, MainPage page) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("page");
|
throw new ArgumentNullException("page");
|
||||||
}
|
}
|
||||||
|
|
||||||
_page = page;
|
_page = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnWriteMessage(string message)
|
protected override void OnWriteMessage(string message)
|
||||||
{
|
{
|
||||||
_page.Dispatcher.Post(() => _page.WriteMessage(message));
|
_page.Dispatcher.Post(() => _page.WriteMessage(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private MainPage _page;
|
private MainPage _page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,401 +1,401 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class SilverlightKeyboardService : KeyboardService
|
public sealed class SilverlightKeyboardService : KeyboardService
|
||||||
{
|
{
|
||||||
public SilverlightKeyboardService(Machine machine, UserControl page) :
|
public SilverlightKeyboardService(Machine machine, UserControl page) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("page");
|
throw new ArgumentNullException("page");
|
||||||
}
|
}
|
||||||
|
|
||||||
page.KeyDown += OnPageKeyDown;
|
page.KeyDown += OnPageKeyDown;
|
||||||
page.KeyUp += OnPageKeyUp;
|
page.KeyUp += OnPageKeyUp;
|
||||||
page.LostFocus += OnPageLostFocus;
|
page.LostFocus += OnPageLostFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsKeyDown(int key)
|
public override bool IsKeyDown(int key)
|
||||||
{
|
{
|
||||||
return IsKeyDown((Key)key);
|
return IsKeyDown((Key)key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update() // main thread
|
public override void Update() // main thread
|
||||||
{
|
{
|
||||||
if (_updateAnyKeyDown) // SL is missing access to keyboard state; could lose track of keyboard state after Alt+Tab
|
if (_updateAnyKeyDown) // SL is missing access to keyboard state; could lose track of keyboard state after Alt+Tab
|
||||||
{
|
{
|
||||||
_updateAnyKeyDown = false;
|
_updateAnyKeyDown = false;
|
||||||
IsAnyKeyDown = false;
|
IsAnyKeyDown = false;
|
||||||
for (int i = 0; i < KeyValues.Length; i++)
|
for (int i = 0; i < KeyValues.Length; i++)
|
||||||
{
|
{
|
||||||
if (IsKeyDown(KeyValues[i]))
|
if (IsKeyDown(KeyValues[i]))
|
||||||
{
|
{
|
||||||
IsAnyKeyDown = true;
|
IsAnyKeyDown = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var modifiers = System.Windows.Input.Keyboard.Modifiers;
|
var modifiers = System.Windows.Input.Keyboard.Modifiers;
|
||||||
IsControlKeyDown = ((modifiers & ModifierKeys.Control) != 0);
|
IsControlKeyDown = ((modifiers & ModifierKeys.Control) != 0);
|
||||||
IsShiftKeyDown = ((modifiers & ModifierKeys.Shift) != 0);
|
IsShiftKeyDown = ((modifiers & ModifierKeys.Shift) != 0);
|
||||||
|
|
||||||
IsOpenAppleKeyDown = ((modifiers & ModifierKeys.Alt) != 0) || IsKeyDown(Key.NumPad0);
|
IsOpenAppleKeyDown = ((modifiers & ModifierKeys.Alt) != 0) || IsKeyDown(Key.NumPad0);
|
||||||
IsCloseAppleKeyDown = ((modifiers & ModifierKeys.Windows) != 0) || IsKeyDown(Key.Decimal);
|
IsCloseAppleKeyDown = ((modifiers & ModifierKeys.Windows) != 0) || IsKeyDown(Key.Decimal);
|
||||||
IsResetKeyDown = IsControlKeyDown && IsKeyDown(Key.Back);
|
IsResetKeyDown = IsControlKeyDown && IsKeyDown(Key.Back);
|
||||||
|
|
||||||
base.Update();
|
base.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsKeyDown(Key key)
|
private bool IsKeyDown(Key key)
|
||||||
{
|
{
|
||||||
return _states[(int)key];
|
return _states[(int)key];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPageKeyDown(object sender, KeyEventArgs e)
|
private void OnPageKeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
//DebugService.WriteLine(string.Concat("OnPageKeyDn: Key=", e.Key, " PlatformKeyCode=", e.PlatformKeyCode));
|
//DebugService.WriteLine(string.Concat("OnPageKeyDn: Key=", e.Key, " PlatformKeyCode=", e.PlatformKeyCode));
|
||||||
|
|
||||||
_states[(int)e.Key] = true;
|
_states[(int)e.Key] = true;
|
||||||
_updateAnyKeyDown = false;
|
_updateAnyKeyDown = false;
|
||||||
IsAnyKeyDown = true;
|
IsAnyKeyDown = true;
|
||||||
|
|
||||||
int asciiKey = GetAsciiKey(e.Key, e.PlatformKeyCode);
|
int asciiKey = GetAsciiKey(e.Key, e.PlatformKeyCode);
|
||||||
if (asciiKey >= 0)
|
if (asciiKey >= 0)
|
||||||
{
|
{
|
||||||
Machine.Keyboard.Latch = asciiKey;
|
Machine.Keyboard.Latch = asciiKey;
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPageKeyUp(object sender, KeyEventArgs e)
|
private void OnPageKeyUp(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
//DebugService.WriteLine(string.Concat("OnPageKeyUp: Key=", e.Key, " PlatformKeyCode=", e.PlatformKeyCode));
|
//DebugService.WriteLine(string.Concat("OnPageKeyUp: Key=", e.Key, " PlatformKeyCode=", e.PlatformKeyCode));
|
||||||
|
|
||||||
_states[(int)e.Key] = false;
|
_states[(int)e.Key] = false;
|
||||||
_updateAnyKeyDown = true;
|
_updateAnyKeyDown = true;
|
||||||
|
|
||||||
var modifiers = System.Windows.Input.Keyboard.Modifiers;
|
var modifiers = System.Windows.Input.Keyboard.Modifiers;
|
||||||
bool control = ((modifiers & ModifierKeys.Control) != 0);
|
bool control = ((modifiers & ModifierKeys.Control) != 0);
|
||||||
|
|
||||||
if (e.Key == Key.CapsLock)
|
if (e.Key == Key.CapsLock)
|
||||||
{
|
{
|
||||||
_capsLock ^= true; // SL is missing caps lock support; try to track manually
|
_capsLock ^= true; // SL is missing caps lock support; try to track manually
|
||||||
}
|
}
|
||||||
else if (control && (e.Key == Key.Divide))
|
else if (control && (e.Key == Key.Divide))
|
||||||
{
|
{
|
||||||
Machine.Cpu.IsThrottled ^= true;
|
Machine.Cpu.IsThrottled ^= true;
|
||||||
}
|
}
|
||||||
else if (control && (e.Key == Key.Multiply))
|
else if (control && (e.Key == Key.Multiply))
|
||||||
{
|
{
|
||||||
Machine.Video.IsMonochrome ^= true;
|
Machine.Video.IsMonochrome ^= true;
|
||||||
}
|
}
|
||||||
else if (control && (e.Key == Key.Subtract))
|
else if (control && (e.Key == Key.Subtract))
|
||||||
{
|
{
|
||||||
Machine.Video.IsFullScreen ^= true;
|
Machine.Video.IsFullScreen ^= true;
|
||||||
}
|
}
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPageLostFocus(object sender, RoutedEventArgs e) // reset keyboard state on lost focus; can't access keyboard state on got focus
|
private void OnPageLostFocus(object sender, RoutedEventArgs e) // reset keyboard state on lost focus; can't access keyboard state on got focus
|
||||||
{
|
{
|
||||||
IsAnyKeyDown = false;
|
IsAnyKeyDown = false;
|
||||||
for (int i = 0; i < KeyValues.Length; i++)
|
for (int i = 0; i < KeyValues.Length; i++)
|
||||||
{
|
{
|
||||||
_states[(int)KeyValues[i]] = false;
|
_states[(int)KeyValues[i]] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||||
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
||||||
private int GetAsciiKey(Key key, int platformKeyCode)
|
private int GetAsciiKey(Key key, int platformKeyCode)
|
||||||
{
|
{
|
||||||
var modifiers = System.Windows.Input.Keyboard.Modifiers;
|
var modifiers = System.Windows.Input.Keyboard.Modifiers;
|
||||||
bool control = ((modifiers & ModifierKeys.Control) != 0);
|
bool control = ((modifiers & ModifierKeys.Control) != 0);
|
||||||
bool shift = ((modifiers & ModifierKeys.Shift) != 0);
|
bool shift = ((modifiers & ModifierKeys.Shift) != 0);
|
||||||
bool capsLock = shift ^ _capsLock;
|
bool capsLock = shift ^ _capsLock;
|
||||||
|
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case Key.Left:
|
case Key.Left:
|
||||||
return 0x08;
|
return 0x08;
|
||||||
|
|
||||||
case Key.Tab:
|
case Key.Tab:
|
||||||
return 0x09;
|
return 0x09;
|
||||||
|
|
||||||
case Key.Down:
|
case Key.Down:
|
||||||
return 0x0A;
|
return 0x0A;
|
||||||
|
|
||||||
case Key.Up:
|
case Key.Up:
|
||||||
return 0x0B;
|
return 0x0B;
|
||||||
|
|
||||||
case Key.Enter:
|
case Key.Enter:
|
||||||
return 0x0D;
|
return 0x0D;
|
||||||
|
|
||||||
case Key.Right:
|
case Key.Right:
|
||||||
return 0x15;
|
return 0x15;
|
||||||
|
|
||||||
case Key.Escape:
|
case Key.Escape:
|
||||||
return 0x1B;
|
return 0x1B;
|
||||||
|
|
||||||
case Key.Back:
|
case Key.Back:
|
||||||
return control ? -1 : 0x7F;
|
return control ? -1 : 0x7F;
|
||||||
|
|
||||||
case Key.Space:
|
case Key.Space:
|
||||||
return ' ';
|
return ' ';
|
||||||
|
|
||||||
case Key.D1:
|
case Key.D1:
|
||||||
return shift ? '!' : '1';
|
return shift ? '!' : '1';
|
||||||
|
|
||||||
case Key.D2:
|
case Key.D2:
|
||||||
return control ? 0x00 : shift ? '@' : '2';
|
return control ? 0x00 : shift ? '@' : '2';
|
||||||
|
|
||||||
case Key.D3:
|
case Key.D3:
|
||||||
return shift ? '#' : '3';
|
return shift ? '#' : '3';
|
||||||
|
|
||||||
case Key.D4:
|
case Key.D4:
|
||||||
return shift ? '$' : '4';
|
return shift ? '$' : '4';
|
||||||
|
|
||||||
case Key.D5:
|
case Key.D5:
|
||||||
return shift ? '%' : '5';
|
return shift ? '%' : '5';
|
||||||
|
|
||||||
case Key.D6:
|
case Key.D6:
|
||||||
return control ? 0x1E : shift ? '^' : '6';
|
return control ? 0x1E : shift ? '^' : '6';
|
||||||
|
|
||||||
case Key.D7:
|
case Key.D7:
|
||||||
return shift ? '&' : '7';
|
return shift ? '&' : '7';
|
||||||
|
|
||||||
case Key.D8:
|
case Key.D8:
|
||||||
return shift ? '*' : '8';
|
return shift ? '*' : '8';
|
||||||
|
|
||||||
case Key.D9:
|
case Key.D9:
|
||||||
return shift ? '(' : '9';
|
return shift ? '(' : '9';
|
||||||
|
|
||||||
case Key.D0:
|
case Key.D0:
|
||||||
return shift ? ')' : '0';
|
return shift ? ')' : '0';
|
||||||
|
|
||||||
case Key.A:
|
case Key.A:
|
||||||
return control ? 0x01 : capsLock ? 'A' : 'a';
|
return control ? 0x01 : capsLock ? 'A' : 'a';
|
||||||
|
|
||||||
case Key.B:
|
case Key.B:
|
||||||
return control ? 0x02 : capsLock ? 'B' : 'b';
|
return control ? 0x02 : capsLock ? 'B' : 'b';
|
||||||
|
|
||||||
case Key.C:
|
case Key.C:
|
||||||
return control ? 0x03 : capsLock ? 'C' : 'c';
|
return control ? 0x03 : capsLock ? 'C' : 'c';
|
||||||
|
|
||||||
case Key.D:
|
case Key.D:
|
||||||
return control ? 0x04 : capsLock ? 'D' : 'd';
|
return control ? 0x04 : capsLock ? 'D' : 'd';
|
||||||
|
|
||||||
case Key.E:
|
case Key.E:
|
||||||
return control ? 0x05 : capsLock ? 'E' : 'e';
|
return control ? 0x05 : capsLock ? 'E' : 'e';
|
||||||
|
|
||||||
case Key.F:
|
case Key.F:
|
||||||
return control ? 0x06 : capsLock ? 'F' : 'f';
|
return control ? 0x06 : capsLock ? 'F' : 'f';
|
||||||
|
|
||||||
case Key.G:
|
case Key.G:
|
||||||
return control ? 0x07 : capsLock ? 'G' : 'g';
|
return control ? 0x07 : capsLock ? 'G' : 'g';
|
||||||
|
|
||||||
case Key.H:
|
case Key.H:
|
||||||
return control ? 0x08 : capsLock ? 'H' : 'h';
|
return control ? 0x08 : capsLock ? 'H' : 'h';
|
||||||
|
|
||||||
case Key.I:
|
case Key.I:
|
||||||
return control ? 0x09 : capsLock ? 'I' : 'i';
|
return control ? 0x09 : capsLock ? 'I' : 'i';
|
||||||
|
|
||||||
case Key.J:
|
case Key.J:
|
||||||
return control ? 0x0A : capsLock ? 'J' : 'j';
|
return control ? 0x0A : capsLock ? 'J' : 'j';
|
||||||
|
|
||||||
case Key.K:
|
case Key.K:
|
||||||
return control ? 0x0B : capsLock ? 'K' : 'k';
|
return control ? 0x0B : capsLock ? 'K' : 'k';
|
||||||
|
|
||||||
case Key.L:
|
case Key.L:
|
||||||
return control ? 0x0C : capsLock ? 'L' : 'l';
|
return control ? 0x0C : capsLock ? 'L' : 'l';
|
||||||
|
|
||||||
case Key.M:
|
case Key.M:
|
||||||
return control ? 0x0D : capsLock ? 'M' : 'm';
|
return control ? 0x0D : capsLock ? 'M' : 'm';
|
||||||
|
|
||||||
case Key.N:
|
case Key.N:
|
||||||
return control ? 0x0E : capsLock ? 'N' : 'n';
|
return control ? 0x0E : capsLock ? 'N' : 'n';
|
||||||
|
|
||||||
case Key.O:
|
case Key.O:
|
||||||
return control ? 0x0F : capsLock ? 'O' : 'o';
|
return control ? 0x0F : capsLock ? 'O' : 'o';
|
||||||
|
|
||||||
case Key.P:
|
case Key.P:
|
||||||
return control ? 0x10 : capsLock ? 'P' : 'p';
|
return control ? 0x10 : capsLock ? 'P' : 'p';
|
||||||
|
|
||||||
case Key.Q:
|
case Key.Q:
|
||||||
return control ? 0x11 : capsLock ? 'Q' : 'q';
|
return control ? 0x11 : capsLock ? 'Q' : 'q';
|
||||||
|
|
||||||
case Key.R:
|
case Key.R:
|
||||||
return control ? 0x12 : capsLock ? 'R' : 'r';
|
return control ? 0x12 : capsLock ? 'R' : 'r';
|
||||||
|
|
||||||
case Key.S:
|
case Key.S:
|
||||||
return control ? 0x13 : capsLock ? 'S' : 's';
|
return control ? 0x13 : capsLock ? 'S' : 's';
|
||||||
|
|
||||||
case Key.T:
|
case Key.T:
|
||||||
return control ? 0x14 : capsLock ? 'T' : 't';
|
return control ? 0x14 : capsLock ? 'T' : 't';
|
||||||
|
|
||||||
case Key.U:
|
case Key.U:
|
||||||
return control ? 0x15 : capsLock ? 'U' : 'u';
|
return control ? 0x15 : capsLock ? 'U' : 'u';
|
||||||
|
|
||||||
case Key.V:
|
case Key.V:
|
||||||
return control ? 0x16 : capsLock ? 'V' : 'v';
|
return control ? 0x16 : capsLock ? 'V' : 'v';
|
||||||
|
|
||||||
case Key.W:
|
case Key.W:
|
||||||
return control ? 0x17 : capsLock ? 'W' : 'w';
|
return control ? 0x17 : capsLock ? 'W' : 'w';
|
||||||
|
|
||||||
case Key.X:
|
case Key.X:
|
||||||
return control ? 0x18 : capsLock ? 'X' : 'x';
|
return control ? 0x18 : capsLock ? 'X' : 'x';
|
||||||
|
|
||||||
case Key.Y:
|
case Key.Y:
|
||||||
return control ? 0x19 : capsLock ? 'Y' : 'y';
|
return control ? 0x19 : capsLock ? 'Y' : 'y';
|
||||||
|
|
||||||
case Key.Z:
|
case Key.Z:
|
||||||
return control ? 0x1A : capsLock ? 'Z' : 'z';
|
return control ? 0x1A : capsLock ? 'Z' : 'z';
|
||||||
|
|
||||||
case Key.Unknown:
|
case Key.Unknown:
|
||||||
switch (Environment.OSVersion.Platform)
|
switch (Environment.OSVersion.Platform)
|
||||||
{
|
{
|
||||||
case PlatformID.Win32NT:
|
case PlatformID.Win32NT:
|
||||||
switch (platformKeyCode)
|
switch (platformKeyCode)
|
||||||
{
|
{
|
||||||
case 0xBA: // WinForms Keys.Oem1
|
case 0xBA: // WinForms Keys.Oem1
|
||||||
return shift ? ':' : ';';
|
return shift ? ':' : ';';
|
||||||
|
|
||||||
case 0xBF: // WinForms Keys.Oem2
|
case 0xBF: // WinForms Keys.Oem2
|
||||||
return shift ? '?' : '/';
|
return shift ? '?' : '/';
|
||||||
|
|
||||||
case 0xC0: // WinForms Keys.Oem3
|
case 0xC0: // WinForms Keys.Oem3
|
||||||
return shift ? '~' : '`';
|
return shift ? '~' : '`';
|
||||||
|
|
||||||
case 0xDB: // WinForms Keys.Oem4
|
case 0xDB: // WinForms Keys.Oem4
|
||||||
return shift ? '{' : '[';
|
return shift ? '{' : '[';
|
||||||
|
|
||||||
case 0xDC: // WinForms Keys.Oem5
|
case 0xDC: // WinForms Keys.Oem5
|
||||||
return control ? 0x1C : shift ? '|' : '\\';
|
return control ? 0x1C : shift ? '|' : '\\';
|
||||||
|
|
||||||
case 0xDD: // WinForms Keys.Oem6
|
case 0xDD: // WinForms Keys.Oem6
|
||||||
return control ? 0x1D : shift ? '}' : ']';
|
return control ? 0x1D : shift ? '}' : ']';
|
||||||
|
|
||||||
case 0xDE: // WinForms Keys.Oem7
|
case 0xDE: // WinForms Keys.Oem7
|
||||||
return shift ? '"' : '\'';
|
return shift ? '"' : '\'';
|
||||||
|
|
||||||
case 0xBD: // WinForms Keys.OemMinus
|
case 0xBD: // WinForms Keys.OemMinus
|
||||||
return control ? 0x1F : shift ? '_' : '-';
|
return control ? 0x1F : shift ? '_' : '-';
|
||||||
|
|
||||||
case 0xBB: // WinForms Keys.OemPlus
|
case 0xBB: // WinForms Keys.OemPlus
|
||||||
return shift ? '+' : '=';
|
return shift ? '+' : '=';
|
||||||
|
|
||||||
case 0xBC: // WinForms Keys.OemComma
|
case 0xBC: // WinForms Keys.OemComma
|
||||||
return shift ? '<' : ',';
|
return shift ? '<' : ',';
|
||||||
|
|
||||||
case 0xBE: // WinForms Keys.OemPeriod
|
case 0xBE: // WinForms Keys.OemPeriod
|
||||||
return shift ? '>' : '.';
|
return shift ? '>' : '.';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlatformID.MacOSX:
|
case PlatformID.MacOSX:
|
||||||
switch (platformKeyCode)
|
switch (platformKeyCode)
|
||||||
{
|
{
|
||||||
case 0x29:
|
case 0x29:
|
||||||
return shift ? ':' : ';';
|
return shift ? ':' : ';';
|
||||||
|
|
||||||
case 0x2C:
|
case 0x2C:
|
||||||
return shift ? '?' : '/';
|
return shift ? '?' : '/';
|
||||||
|
|
||||||
case 0x32:
|
case 0x32:
|
||||||
return shift ? '~' : '`';
|
return shift ? '~' : '`';
|
||||||
|
|
||||||
case 0x21:
|
case 0x21:
|
||||||
return shift ? '{' : '[';
|
return shift ? '{' : '[';
|
||||||
|
|
||||||
case 0x2A:
|
case 0x2A:
|
||||||
return control ? 0x1C : shift ? '|' : '\\';
|
return control ? 0x1C : shift ? '|' : '\\';
|
||||||
|
|
||||||
case 0x1E:
|
case 0x1E:
|
||||||
return control ? 0x1D : shift ? '}' : ']';
|
return control ? 0x1D : shift ? '}' : ']';
|
||||||
|
|
||||||
case 0x27:
|
case 0x27:
|
||||||
return shift ? '"' : '\'';
|
return shift ? '"' : '\'';
|
||||||
|
|
||||||
case 0x1B:
|
case 0x1B:
|
||||||
return control ? 0x1F : shift ? '_' : '-';
|
return control ? 0x1F : shift ? '_' : '-';
|
||||||
|
|
||||||
case 0x18:
|
case 0x18:
|
||||||
return shift ? '+' : '=';
|
return shift ? '+' : '=';
|
||||||
|
|
||||||
case 0x2B:
|
case 0x2B:
|
||||||
return shift ? '<' : ',';
|
return shift ? '<' : ',';
|
||||||
|
|
||||||
case 0x2F:
|
case 0x2F:
|
||||||
return shift ? '>' : '.';
|
return shift ? '>' : '.';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlatformID.Unix:
|
case PlatformID.Unix:
|
||||||
switch (platformKeyCode)
|
switch (platformKeyCode)
|
||||||
{
|
{
|
||||||
case 0x2F:
|
case 0x2F:
|
||||||
return shift ? ':' : ';';
|
return shift ? ':' : ';';
|
||||||
|
|
||||||
case 0x3D:
|
case 0x3D:
|
||||||
return shift ? '?' : '/';
|
return shift ? '?' : '/';
|
||||||
|
|
||||||
case 0x31:
|
case 0x31:
|
||||||
return shift ? '~' : '`';
|
return shift ? '~' : '`';
|
||||||
|
|
||||||
case 0x22:
|
case 0x22:
|
||||||
return shift ? '{' : '[';
|
return shift ? '{' : '[';
|
||||||
|
|
||||||
case 0x33:
|
case 0x33:
|
||||||
return control ? 0x1C : shift ? '|' : '\\';
|
return control ? 0x1C : shift ? '|' : '\\';
|
||||||
|
|
||||||
case 0x23:
|
case 0x23:
|
||||||
return control ? 0x1D : shift ? '}' : ']';
|
return control ? 0x1D : shift ? '}' : ']';
|
||||||
|
|
||||||
case 0x30:
|
case 0x30:
|
||||||
return shift ? '"' : '\'';
|
return shift ? '"' : '\'';
|
||||||
|
|
||||||
case 0x14:
|
case 0x14:
|
||||||
return control ? 0x1F : shift ? '_' : '-';
|
return control ? 0x1F : shift ? '_' : '-';
|
||||||
|
|
||||||
case 0x15:
|
case 0x15:
|
||||||
return shift ? '+' : '=';
|
return shift ? '+' : '=';
|
||||||
|
|
||||||
case 0x3B:
|
case 0x3B:
|
||||||
return shift ? '<' : ',';
|
return shift ? '<' : ',';
|
||||||
|
|
||||||
case 0x3C:
|
case 0x3C:
|
||||||
return shift ? '>' : '.';
|
return shift ? '>' : '.';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Key[] KeyValues =
|
private static readonly Key[] KeyValues =
|
||||||
(from key in
|
(from key in
|
||||||
(from field in typeof(Key).GetFields() // missing Enum.GetValues; use reflection
|
(from field in typeof(Key).GetFields() // missing Enum.GetValues; use reflection
|
||||||
where field.IsLiteral
|
where field.IsLiteral
|
||||||
select (Key)field.GetValue(typeof(Key)))
|
select (Key)field.GetValue(typeof(Key)))
|
||||||
where (key != Key.None) // filter Key.None
|
where (key != Key.None) // filter Key.None
|
||||||
select key).ToArray();
|
select key).ToArray();
|
||||||
|
|
||||||
private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
|
private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
|
||||||
|
|
||||||
private bool[] _states = new bool[KeyCount];
|
private bool[] _states = new bool[KeyCount];
|
||||||
private bool _capsLock;
|
private bool _capsLock;
|
||||||
private bool _updateAnyKeyDown;
|
private bool _updateAnyKeyDown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,99 +1,99 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class SilverlightVideoService : VideoService
|
public sealed class SilverlightVideoService : VideoService
|
||||||
{
|
{
|
||||||
public SilverlightVideoService(Machine machine, UserControl page, Image image) :
|
public SilverlightVideoService(Machine machine, UserControl page, Image image) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("page");
|
throw new ArgumentNullException("page");
|
||||||
}
|
}
|
||||||
if (image == null)
|
if (image == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("image");
|
throw new ArgumentNullException("image");
|
||||||
}
|
}
|
||||||
|
|
||||||
_page = page;
|
_page = page;
|
||||||
_image = image;
|
_image = image;
|
||||||
_image.Source = _bitmap;
|
_image.Source = _bitmap;
|
||||||
|
|
||||||
_page.LayoutUpdated += (sender, e) => SetWindowSizeToContent();
|
_page.LayoutUpdated += (sender, e) => SetWindowSizeToContent();
|
||||||
_page.SizeChanged += (sender, e) => SetImageSize();
|
_page.SizeChanged += (sender, e) => SetImageSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetFullScreen(bool isFullScreen)
|
public override void SetFullScreen(bool isFullScreen)
|
||||||
{
|
{
|
||||||
_page.Dispatcher.Send(() =>
|
_page.Dispatcher.Send(() =>
|
||||||
{
|
{
|
||||||
var application = Application.Current;
|
var application = Application.Current;
|
||||||
if (application.IsRunningOutOfBrowser)
|
if (application.IsRunningOutOfBrowser)
|
||||||
{
|
{
|
||||||
var content = application.Host.Content;
|
var content = application.Host.Content;
|
||||||
if (content.IsFullScreen != isFullScreen)
|
if (content.IsFullScreen != isFullScreen)
|
||||||
{
|
{
|
||||||
content.IsFullScreen = isFullScreen;
|
content.IsFullScreen = isFullScreen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
|
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
|
||||||
public override void SetPixel(int x, int y, uint color)
|
public override void SetPixel(int x, int y, uint color)
|
||||||
{
|
{
|
||||||
_pixels[y * BitmapWidth + x] = (int)color;
|
_pixels[y * BitmapWidth + x] = (int)color;
|
||||||
_pixelsDirty = true;
|
_pixelsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update() // main thread
|
public override void Update() // main thread
|
||||||
{
|
{
|
||||||
if (_pixelsDirty)
|
if (_pixelsDirty)
|
||||||
{
|
{
|
||||||
_pixelsDirty = false;
|
_pixelsDirty = false;
|
||||||
for (int i = 0; i < BitmapWidth * BitmapHeight; i++)
|
for (int i = 0; i < BitmapWidth * BitmapHeight; i++)
|
||||||
{
|
{
|
||||||
_bitmap.Pixels[i] = _pixels[i];
|
_bitmap.Pixels[i] = _pixels[i];
|
||||||
}
|
}
|
||||||
_bitmap.Invalidate();
|
_bitmap.Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetImageSize(bool swapOrientation = false)
|
private void SetImageSize(bool swapOrientation = false)
|
||||||
{
|
{
|
||||||
int uniformScale = Math.Max(1, swapOrientation ? Math.Min((int)_page.RenderSize.Height / BitmapWidth, (int)_page.RenderSize.Width / 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));
|
Math.Min((int)_page.RenderSize.Width / BitmapWidth, (int)_page.RenderSize.Height / BitmapHeight));
|
||||||
_image.Width = uniformScale * BitmapWidth;
|
_image.Width = uniformScale * BitmapWidth;
|
||||||
_image.Height = uniformScale * BitmapHeight;
|
_image.Height = uniformScale * BitmapHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetWindowSizeToContent()
|
private void SetWindowSizeToContent()
|
||||||
{
|
{
|
||||||
var application = Application.Current;
|
var application = Application.Current;
|
||||||
if (application.IsRunningOutOfBrowser && !_sizedToContent)
|
if (application.IsRunningOutOfBrowser && !_sizedToContent)
|
||||||
{
|
{
|
||||||
_sizedToContent = true;
|
_sizedToContent = true;
|
||||||
var window = application.MainWindow;
|
var window = application.MainWindow;
|
||||||
var size = application.RootVisual.DesiredSize;
|
var size = application.RootVisual.DesiredSize;
|
||||||
window.Width = size.Width;
|
window.Width = size.Width;
|
||||||
window.Height = size.Height;
|
window.Height = size.Height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int BitmapWidth = 560;
|
private const int BitmapWidth = 560;
|
||||||
private const int BitmapHeight = 384;
|
private const int BitmapHeight = 384;
|
||||||
|
|
||||||
private UserControl _page;
|
private UserControl _page;
|
||||||
private Image _image;
|
private Image _image;
|
||||||
private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight);
|
private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight);
|
||||||
private int[] _pixels = new int[BitmapWidth * BitmapHeight];
|
private int[] _pixels = new int[BitmapWidth * BitmapHeight];
|
||||||
private bool _pixelsDirty;
|
private bool _pixelsDirty;
|
||||||
private bool _sizedToContent;
|
private bool _sizedToContent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
180
Virtu/Speaker.cs
180
Virtu/Speaker.cs
|
@ -1,90 +1,90 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Jellyfish.Virtu.Services;
|
using Jellyfish.Virtu.Services;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed class Speaker : MachineComponent
|
public sealed class Speaker : MachineComponent
|
||||||
{
|
{
|
||||||
public Speaker(Machine machine) :
|
public Speaker(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
_flushOutputEvent = FlushOutputEvent; // cache delegates; avoids garbage
|
_flushOutputEvent = FlushOutputEvent; // cache delegates; avoids garbage
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
_audioService = Machine.Services.GetService<AudioService>();
|
_audioService = Machine.Services.GetService<AudioService>();
|
||||||
|
|
||||||
Volume = 0.5f;
|
Volume = 0.5f;
|
||||||
Machine.Events.AddEvent(CyclesPerFlush * Machine.Cpu.Multiplier, _flushOutputEvent);
|
Machine.Events.AddEvent(CyclesPerFlush * Machine.Cpu.Multiplier, _flushOutputEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
_audioService.Reset();
|
_audioService.Reset();
|
||||||
_isHigh = false;
|
_isHigh = false;
|
||||||
_highCycles = _totalCycles = 0;
|
_highCycles = _totalCycles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LoadState(BinaryReader reader, Version version)
|
public override void LoadState(BinaryReader reader, Version version)
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("reader");
|
throw new ArgumentNullException("reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
Volume = reader.ReadSingle();
|
Volume = reader.ReadSingle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SaveState(BinaryWriter writer)
|
public override void SaveState(BinaryWriter writer)
|
||||||
{
|
{
|
||||||
if (writer == null)
|
if (writer == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("writer");
|
throw new ArgumentNullException("writer");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(Volume);
|
writer.Write(Volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToggleOutput()
|
public void ToggleOutput()
|
||||||
{
|
{
|
||||||
UpdateCycles();
|
UpdateCycles();
|
||||||
_isHigh ^= true;
|
_isHigh ^= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FlushOutputEvent()
|
private void FlushOutputEvent()
|
||||||
{
|
{
|
||||||
UpdateCycles();
|
UpdateCycles();
|
||||||
_audioService.Output(_highCycles * short.MaxValue / _totalCycles); // quick and dirty decimation
|
_audioService.Output(_highCycles * short.MaxValue / _totalCycles); // quick and dirty decimation
|
||||||
_highCycles = _totalCycles = 0;
|
_highCycles = _totalCycles = 0;
|
||||||
|
|
||||||
Machine.Events.AddEvent(CyclesPerFlush * Machine.Cpu.Multiplier, _flushOutputEvent);
|
Machine.Events.AddEvent(CyclesPerFlush * Machine.Cpu.Multiplier, _flushOutputEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateCycles()
|
private void UpdateCycles()
|
||||||
{
|
{
|
||||||
int delta = (int)(Machine.Cpu.Cycles - _lastCycles);
|
int delta = (int)(Machine.Cpu.Cycles - _lastCycles);
|
||||||
if (_isHigh)
|
if (_isHigh)
|
||||||
{
|
{
|
||||||
_highCycles += delta;
|
_highCycles += delta;
|
||||||
}
|
}
|
||||||
_totalCycles += delta;
|
_totalCycles += delta;
|
||||||
_lastCycles = Machine.Cpu.Cycles;
|
_lastCycles = Machine.Cpu.Cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Volume { get { return _volume; } set { _volume = value; _audioService.SetVolume(_volume); } }
|
public float Volume { get { return _volume; } set { _volume = value; _audioService.SetVolume(_volume); } }
|
||||||
|
|
||||||
private const int CyclesPerFlush = 23;
|
private const int CyclesPerFlush = 23;
|
||||||
|
|
||||||
private Action _flushOutputEvent;
|
private Action _flushOutputEvent;
|
||||||
|
|
||||||
private AudioService _audioService;
|
private AudioService _audioService;
|
||||||
|
|
||||||
private bool _isHigh;
|
private bool _isHigh;
|
||||||
private int _highCycles;
|
private int _highCycles;
|
||||||
private int _totalCycles;
|
private int _totalCycles;
|
||||||
private long _lastCycles;
|
private long _lastCycles;
|
||||||
private float _volume;
|
private float _volume;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2300
Virtu/Video.cs
2300
Virtu/Video.cs
File diff suppressed because it is too large
Load Diff
3288
Virtu/VideoData.cs
3288
Virtu/VideoData.cs
File diff suppressed because it is too large
Load Diff
|
@ -1,250 +1,250 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProductVersion>8.0.30703</ProductVersion>
|
<ProductVersion>8.0.30703</ProductVersion>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<ProjectGuid>{C152D47E-BBC1-4C35-8646-465180720A72}</ProjectGuid>
|
<ProjectGuid>{C152D47E-BBC1-4C35-8646-465180720A72}</ProjectGuid>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>Jellyfish.Virtu</RootNamespace>
|
<RootNamespace>Jellyfish.Virtu</RootNamespace>
|
||||||
<AssemblyName>Jellyfish.Virtu</AssemblyName>
|
<AssemblyName>Jellyfish.Virtu</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<ApplicationIcon>AppIcon.ico</ApplicationIcon>
|
<ApplicationIcon>AppIcon.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>bin\</OutputPath>
|
<OutputPath>bin\</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE;WPF;WINDOWS;CODE_ANALYSIS</DefineConstants>
|
<DefineConstants>DEBUG;TRACE;WPF;WINDOWS;CODE_ANALYSIS</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<OutputPath>bin\</OutputPath>
|
<OutputPath>bin\</OutputPath>
|
||||||
<DefineConstants>TRACE;WPF;WINDOWS;CODE_ANALYSIS</DefineConstants>
|
<DefineConstants>TRACE;WPF;WINDOWS;CODE_ANALYSIS</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<StartupObject>Jellyfish.Virtu.MainApp</StartupObject>
|
<StartupObject>Jellyfish.Virtu.MainApp</StartupObject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SignAssembly>false</SignAssembly>
|
<SignAssembly>false</SignAssembly>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyOriginatorKeyFile>..\..\..\Jellyfish\StrongName.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>..\..\..\Jellyfish\StrongName.snk</AssemblyOriginatorKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SignManifests>false</SignManifests>
|
<SignManifests>false</SignManifests>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ManifestTimestampUrl>http://timestamp.verisign.com/scripts/timestamp.dll</ManifestTimestampUrl>
|
<ManifestTimestampUrl>http://timestamp.verisign.com/scripts/timestamp.dll</ManifestTimestampUrl>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ManifestCertificateThumbprint>7E57BBFFA7D9A57530AC8A09E5236FE0AAB041C2</ManifestCertificateThumbprint>
|
<ManifestCertificateThumbprint>7E57BBFFA7D9A57530AC8A09E5236FE0AAB041C2</ManifestCertificateThumbprint>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ManifestKeyFile>..\..\..\Jellyfish\CodeSign.pfx</ManifestKeyFile>
|
<ManifestKeyFile>..\..\..\Jellyfish\CodeSign.pfx</ManifestKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Deployment" />
|
<Reference Include="System.Deployment" />
|
||||||
<Reference Include="System.Xaml">
|
<Reference Include="System.Xaml">
|
||||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ApplicationDefinition Include="MainApp.xaml">
|
<ApplicationDefinition Include="MainApp.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
<Page Include="MainPage.xaml">
|
<Page Include="MainPage.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Page Include="MainWindow.xaml">
|
<Page Include="MainWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</Page>
|
</Page>
|
||||||
<Compile Include="MainApp.xaml.cs">
|
<Compile Include="MainApp.xaml.cs">
|
||||||
<DependentUpon>MainApp.xaml</DependentUpon>
|
<DependentUpon>MainApp.xaml</DependentUpon>
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="MainPage.xaml.cs">
|
<Compile Include="MainPage.xaml.cs">
|
||||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="MainWindow.xaml.cs">
|
<Compile Include="MainWindow.xaml.cs">
|
||||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\Cassette.cs">
|
<Compile Include="..\Cassette.cs">
|
||||||
<Link>Core\Cassette.cs</Link>
|
<Link>Core\Cassette.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Cpu.cs">
|
<Compile Include="..\Cpu.cs">
|
||||||
<Link>Core\Cpu.cs</Link>
|
<Link>Core\Cpu.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\CpuData.cs">
|
<Compile Include="..\CpuData.cs">
|
||||||
<Link>Core\CpuData.cs</Link>
|
<Link>Core\CpuData.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Disk525.cs">
|
<Compile Include="..\Disk525.cs">
|
||||||
<Link>Core\Disk525.cs</Link>
|
<Link>Core\Disk525.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskDsk.cs">
|
<Compile Include="..\DiskDsk.cs">
|
||||||
<Link>Core\DiskDsk.cs</Link>
|
<Link>Core\DiskDsk.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskIIController.cs">
|
<Compile Include="..\DiskIIController.cs">
|
||||||
<Link>Core\DiskIIController.cs</Link>
|
<Link>Core\DiskIIController.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskIIDrive.cs">
|
<Compile Include="..\DiskIIDrive.cs">
|
||||||
<Link>Core\DiskIIDrive.cs</Link>
|
<Link>Core\DiskIIDrive.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\DiskNib.cs">
|
<Compile Include="..\DiskNib.cs">
|
||||||
<Link>Core\DiskNib.cs</Link>
|
<Link>Core\DiskNib.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\GamePort.cs">
|
<Compile Include="..\GamePort.cs">
|
||||||
<Link>Core\GamePort.cs</Link>
|
<Link>Core\GamePort.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\GlobalSuppressions.cs">
|
<Compile Include="..\GlobalSuppressions.cs">
|
||||||
<Link>GlobalSuppressions.cs</Link>
|
<Link>GlobalSuppressions.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Keyboard.cs">
|
<Compile Include="..\Keyboard.cs">
|
||||||
<Link>Core\Keyboard.cs</Link>
|
<Link>Core\Keyboard.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Machine.cs">
|
<Compile Include="..\Machine.cs">
|
||||||
<Link>Core\Machine.cs</Link>
|
<Link>Core\Machine.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MachineComponent.cs">
|
<Compile Include="..\MachineComponent.cs">
|
||||||
<Link>Core\MachineComponent.cs</Link>
|
<Link>Core\MachineComponent.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MachineEvents.cs">
|
<Compile Include="..\MachineEvents.cs">
|
||||||
<Link>Core\MachineEvents.cs</Link>
|
<Link>Core\MachineEvents.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Memory.cs">
|
<Compile Include="..\Memory.cs">
|
||||||
<Link>Core\Memory.cs</Link>
|
<Link>Core\Memory.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\MemoryData.cs">
|
<Compile Include="..\MemoryData.cs">
|
||||||
<Link>Core\MemoryData.cs</Link>
|
<Link>Core\MemoryData.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\NoSlotClock.cs">
|
<Compile Include="..\NoSlotClock.cs">
|
||||||
<Link>Core\NoSlotClock.cs</Link>
|
<Link>Core\NoSlotClock.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\PeripheralCard.cs">
|
<Compile Include="..\PeripheralCard.cs">
|
||||||
<Link>Core\PeripheralCard.cs</Link>
|
<Link>Core\PeripheralCard.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Properties\Strings.Designer.cs">
|
<Compile Include="..\Properties\Strings.Designer.cs">
|
||||||
<Link>Properties\Strings.Designer.cs</Link>
|
<Link>Properties\Strings.Designer.cs</Link>
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Strings.resx</DependentUpon>
|
<DependentUpon>Strings.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\AudioService.cs">
|
<Compile Include="..\Services\AudioService.cs">
|
||||||
<Link>Services\AudioService.cs</Link>
|
<Link>Services\AudioService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\DebugService.cs">
|
<Compile Include="..\Services\DebugService.cs">
|
||||||
<Link>Services\DebugService.cs</Link>
|
<Link>Services\DebugService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\GamePortService.cs">
|
<Compile Include="..\Services\GamePortService.cs">
|
||||||
<Link>Services\GamePortService.cs</Link>
|
<Link>Services\GamePortService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\IsolatedStorageService.cs">
|
<Compile Include="..\Services\IsolatedStorageService.cs">
|
||||||
<Link>Services\IsolatedStorageService.cs</Link>
|
<Link>Services\IsolatedStorageService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\KeyboardService.cs">
|
<Compile Include="..\Services\KeyboardService.cs">
|
||||||
<Link>Services\KeyboardService.cs</Link>
|
<Link>Services\KeyboardService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\MachineService.cs">
|
<Compile Include="..\Services\MachineService.cs">
|
||||||
<Link>Services\MachineService.cs</Link>
|
<Link>Services\MachineService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\MachineServices.cs">
|
<Compile Include="..\Services\MachineServices.cs">
|
||||||
<Link>Services\MachineServices.cs</Link>
|
<Link>Services\MachineServices.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\StorageService.cs">
|
<Compile Include="..\Services\StorageService.cs">
|
||||||
<Link>Services\StorageService.cs</Link>
|
<Link>Services\StorageService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Services\VideoService.cs">
|
<Compile Include="..\Services\VideoService.cs">
|
||||||
<Link>Services\VideoService.cs</Link>
|
<Link>Services\VideoService.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Speaker.cs">
|
<Compile Include="..\Speaker.cs">
|
||||||
<Link>Core\Speaker.cs</Link>
|
<Link>Core\Speaker.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\Video.cs">
|
<Compile Include="..\Video.cs">
|
||||||
<Link>Core\Video.cs</Link>
|
<Link>Core\Video.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\VideoData.cs">
|
<Compile Include="..\VideoData.cs">
|
||||||
<Link>Core\VideoData.cs</Link>
|
<Link>Core\VideoData.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Services\WpfAudioService.cs" />
|
<Compile Include="Services\WpfAudioService.cs" />
|
||||||
<Compile Include="Services\WpfDebugService.cs" />
|
<Compile Include="Services\WpfDebugService.cs" />
|
||||||
<Compile Include="Services\WpfKeyboardService.cs" />
|
<Compile Include="Services\WpfKeyboardService.cs" />
|
||||||
<Compile Include="Services\WpfStorageService.cs" />
|
<Compile Include="Services\WpfStorageService.cs" />
|
||||||
<Compile Include="Services\WpfVideoService.cs" />
|
<Compile Include="Services\WpfVideoService.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AppDesigner Include="Properties\" />
|
<AppDesigner Include="Properties\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="AppIcon.ico" />
|
<Content Include="AppIcon.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="..\Properties\Strings.resx">
|
<EmbeddedResource Include="..\Properties\Strings.resx">
|
||||||
<Link>Properties\Strings.resx</Link>
|
<Link>Properties\Strings.resx</Link>
|
||||||
<Generator>ResXFileCodeGenerator</Generator>
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="..\Disks\Default.dsk">
|
<EmbeddedResource Include="..\Disks\Default.dsk">
|
||||||
<Link>Disks\Default.dsk</Link>
|
<Link>Disks\Default.dsk</Link>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="..\Roms\AppleIIe.rom">
|
<EmbeddedResource Include="..\Roms\AppleIIe.rom">
|
||||||
<Link>Roms\AppleIIe.rom</Link>
|
<Link>Roms\AppleIIe.rom</Link>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="..\Roms\DiskII.rom">
|
<EmbeddedResource Include="..\Roms\DiskII.rom">
|
||||||
<Link>Roms\DiskII.rom</Link>
|
<Link>Roms\DiskII.rom</Link>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
|
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
|
||||||
<Link>CustomDictionary.xml</Link>
|
<Link>CustomDictionary.xml</Link>
|
||||||
</CodeAnalysisDictionary>
|
</CodeAnalysisDictionary>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Library\Wpf\Jellyfish.Library.Wpf.csproj">
|
<ProjectReference Include="..\..\Library\Wpf\Jellyfish.Library.Wpf.csproj">
|
||||||
<Project>{93900841-7250-4D3A-837E-43EE3FD118DC}</Project>
|
<Project>{93900841-7250-4D3A-837E-43EE3FD118DC}</Project>
|
||||||
<Name>Jellyfish.Library.Wpf</Name>
|
<Name>Jellyfish.Library.Wpf</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
|
@ -1,26 +1,26 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2012
|
# Visual Studio 2012
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "..\..\Library\Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Library.Wpf", "..\..\Library\Wpf\Jellyfish.Library.Wpf.csproj", "{93900841-7250-4D3A-837E-43EE3FD118DC}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Wpf", "Jellyfish.Virtu.Wpf.csproj", "{C152D47E-BBC1-4C35-8646-465180720A72}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfish.Virtu.Wpf", "Jellyfish.Virtu.Wpf.csproj", "{C152D47E-BBC1-4C35-8646-465180720A72}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{93900841-7250-4D3A-837E-43EE3FD118DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C152D47E-BBC1-4C35-8646-465180720A72}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C152D47E-BBC1-4C35-8646-465180720A72}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<jl:ApplicationBase x:Class="Jellyfish.Virtu.MainApp"
|
<jl:ApplicationBase x:Class="Jellyfish.Virtu.MainApp"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
||||||
StartupUri="MainWindow.xaml">
|
StartupUri="MainWindow.xaml">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
</jl:ApplicationBase>
|
</jl:ApplicationBase>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed partial class MainApp : ApplicationBase
|
public sealed partial class MainApp : ApplicationBase
|
||||||
{
|
{
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
public MainApp() :
|
public MainApp() :
|
||||||
base("Virtu")
|
base("Virtu")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
<UserControl x:Class="Jellyfish.Virtu.MainPage"
|
<UserControl x:Class="Jellyfish.Virtu.MainPage"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
xmlns:jl="clr-namespace:Jellyfish.Library;assembly=Jellyfish.Library"
|
||||||
Focusable="True">
|
Focusable="True">
|
||||||
<Grid Background="Black">
|
<Grid Background="Black">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition />
|
<RowDefinition />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Button x:Name="_disk1Button" Content="Disk 1" Focusable="False" IsTabStop="False" Margin="4,4,0,4" />
|
<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" />
|
<Button x:Name="_disk2Button" Content="Disk 2" Focusable="False" IsTabStop="False" Margin="4,4,0,4" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<jl:FrameRateCounter Margin="0,0,4,0" HorizontalAlignment="Right" VerticalAlignment="Center" />
|
<jl:FrameRateCounter Margin="0,0,4,0" HorizontalAlignment="Right" VerticalAlignment="Center" />
|
||||||
<Grid Grid.Row="1">
|
<Grid Grid.Row="1">
|
||||||
<Image x:Name="_image" MinWidth="560" MinHeight="384" RenderOptions.BitmapScalingMode="NearestNeighbor" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
<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">
|
<ScrollViewer x:Name="_debugScrollViewer" BorderThickness="0" Focusable="False" IsTabStop="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
||||||
<TextBlock x:Name="_debugText" FontFamily="Consolas" FontSize="12" Foreground="White" />
|
<TextBlock x:Name="_debugText" FontFamily="Consolas" FontSize="12" Foreground="White" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
@ -1,88 +1,88 @@
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using Jellyfish.Virtu.Services;
|
using Jellyfish.Virtu.Services;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed partial class MainPage : UserControl, IDisposable
|
public sealed partial class MainPage : UserControl, IDisposable
|
||||||
{
|
{
|
||||||
public MainPage()
|
public MainPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
if (!DesignerProperties.GetIsInDesignMode(this))
|
if (!DesignerProperties.GetIsInDesignMode(this))
|
||||||
{
|
{
|
||||||
_debugService = DebugService.Default;
|
_debugService = DebugService.Default;
|
||||||
_storageService = new WpfStorageService(_machine);
|
_storageService = new WpfStorageService(_machine);
|
||||||
_keyboardService = new WpfKeyboardService(_machine, this);
|
_keyboardService = new WpfKeyboardService(_machine, this);
|
||||||
_gamePortService = new GamePortService(_machine); // not connected
|
_gamePortService = new GamePortService(_machine); // not connected
|
||||||
_audioService = new WpfAudioService(_machine, this);
|
_audioService = new WpfAudioService(_machine, this);
|
||||||
_videoService = new WpfVideoService(_machine, this, _image);
|
_videoService = new WpfVideoService(_machine, this, _image);
|
||||||
|
|
||||||
_machine.Services.AddService(typeof(DebugService), _debugService);
|
_machine.Services.AddService(typeof(DebugService), _debugService);
|
||||||
_machine.Services.AddService(typeof(StorageService), _storageService);
|
_machine.Services.AddService(typeof(StorageService), _storageService);
|
||||||
_machine.Services.AddService(typeof(KeyboardService), _keyboardService);
|
_machine.Services.AddService(typeof(KeyboardService), _keyboardService);
|
||||||
_machine.Services.AddService(typeof(GamePortService), _gamePortService);
|
_machine.Services.AddService(typeof(GamePortService), _gamePortService);
|
||||||
_machine.Services.AddService(typeof(AudioService), _audioService);
|
_machine.Services.AddService(typeof(AudioService), _audioService);
|
||||||
_machine.Services.AddService(typeof(VideoService), _videoService);
|
_machine.Services.AddService(typeof(VideoService), _videoService);
|
||||||
|
|
||||||
Loaded += (sender, e) => _machine.Start();
|
Loaded += (sender, e) => _machine.Start();
|
||||||
CompositionTarget.Rendering += OnCompositionTargetRendering;
|
CompositionTarget.Rendering += OnCompositionTargetRendering;
|
||||||
Application.Current.Exit += (sender, e) => _machine.Stop();
|
Application.Current.Exit += (sender, e) => _machine.Stop();
|
||||||
|
|
||||||
_disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
|
_disk1Button.Click += (sender, e) => OnDiskButtonClick(0);
|
||||||
_disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
|
_disk2Button.Click += (sender, e) => OnDiskButtonClick(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_machine.Dispose();
|
_machine.Dispose();
|
||||||
_debugService.Dispose();
|
_debugService.Dispose();
|
||||||
_storageService.Dispose();
|
_storageService.Dispose();
|
||||||
_keyboardService.Dispose();
|
_keyboardService.Dispose();
|
||||||
_gamePortService.Dispose();
|
_gamePortService.Dispose();
|
||||||
_audioService.Dispose();
|
_audioService.Dispose();
|
||||||
_videoService.Dispose();
|
_videoService.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteMessage(string message)
|
public void WriteMessage(string message)
|
||||||
{
|
{
|
||||||
_debugText.Text += message + Environment.NewLine;
|
_debugText.Text += message + Environment.NewLine;
|
||||||
_debugScrollViewer.UpdateLayout();
|
_debugScrollViewer.UpdateLayout();
|
||||||
_debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
|
_debugScrollViewer.ScrollToVerticalOffset(double.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
private void OnCompositionTargetRendering(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
_keyboardService.Update();
|
_keyboardService.Update();
|
||||||
_gamePortService.Update();
|
_gamePortService.Update();
|
||||||
_videoService.Update();
|
_videoService.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDiskButtonClick(int drive)
|
private void OnDiskButtonClick(int drive)
|
||||||
{
|
{
|
||||||
var dialog = new OpenFileDialog() { Filter = "Disk Files (*.do;*.dsk;*.nib;*.po)|*.do;*.dsk;*.nib;*.po|All Files (*.*)|*.*" };
|
var dialog = new OpenFileDialog() { Filter = "Disk Files (*.do;*.dsk;*.nib;*.po)|*.do;*.dsk;*.nib;*.po|All Files (*.*)|*.*" };
|
||||||
bool? result = dialog.ShowDialog();
|
bool? result = dialog.ShowDialog();
|
||||||
if (result.HasValue && result.Value)
|
if (result.HasValue && result.Value)
|
||||||
{
|
{
|
||||||
_machine.Pause();
|
_machine.Pause();
|
||||||
StorageService.LoadFile(dialog.FileName, stream => _machine.BootDiskII.Drives[drive].InsertDisk(dialog.FileName, stream, false));
|
StorageService.LoadFile(dialog.FileName, stream => _machine.BootDiskII.Drives[drive].InsertDisk(dialog.FileName, stream, false));
|
||||||
_machine.Unpause();
|
_machine.Unpause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Machine _machine = new Machine();
|
private Machine _machine = new Machine();
|
||||||
|
|
||||||
private DebugService _debugService;
|
private DebugService _debugService;
|
||||||
private StorageService _storageService;
|
private StorageService _storageService;
|
||||||
private KeyboardService _keyboardService;
|
private KeyboardService _keyboardService;
|
||||||
private GamePortService _gamePortService;
|
private GamePortService _gamePortService;
|
||||||
private AudioService _audioService;
|
private AudioService _audioService;
|
||||||
private VideoService _videoService;
|
private VideoService _videoService;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Window x:Class="Jellyfish.Virtu.MainWindow"
|
<Window x:Class="Jellyfish.Virtu.MainWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:jv="clr-namespace:Jellyfish.Virtu"
|
xmlns:jv="clr-namespace:Jellyfish.Virtu"
|
||||||
Title="Virtu" WindowStartupLocation="CenterScreen" FocusManager.FocusedElement="{Binding ElementName=_mainPage}">
|
Title="Virtu" WindowStartupLocation="CenterScreen" FocusManager.FocusedElement="{Binding ElementName=_mainPage}">
|
||||||
<jv:MainPage x:Name="_mainPage" />
|
<jv:MainPage x:Name="_mainPage" />
|
||||||
</Window>
|
</Window>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu
|
namespace Jellyfish.Virtu
|
||||||
{
|
{
|
||||||
public sealed partial class MainWindow : Window
|
public sealed partial class MainWindow : Window
|
||||||
{
|
{
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Resources;
|
using System.Resources;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
using Jellyfish.Virtu;
|
using Jellyfish.Virtu;
|
||||||
|
|
||||||
[assembly: AssemblyTitle("Virtu")]
|
[assembly: AssemblyTitle("Virtu")]
|
||||||
[assembly: AssemblyDescription("Apple IIe Emulator")]
|
[assembly: AssemblyDescription("Apple IIe Emulator")]
|
||||||
[assembly: AssemblyProduct("Jellyfish.Virtu.Wpf")]
|
[assembly: AssemblyProduct("Jellyfish.Virtu.Wpf")]
|
||||||
[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
|
[assembly: AssemblyCompany("Digital Jellyfish Design Ltd")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")]
|
[assembly: AssemblyCopyright("Copyright © 1995-2012 Digital Jellyfish Design Ltd")]
|
||||||
[assembly: AssemblyMetadata("Developers", "Sean Fausett & Nick Westgate")]
|
[assembly: AssemblyMetadata("Developers", "Sean Fausett & Nick Westgate")]
|
||||||
|
|
||||||
[assembly: AssemblyVersion(Machine.Version)]
|
[assembly: AssemblyVersion(Machine.Version)]
|
||||||
[assembly: AssemblyFileVersion(Machine.Version)]
|
[assembly: AssemblyFileVersion(Machine.Version)]
|
||||||
[assembly: AssemblyInformationalVersion(Machine.Version)]
|
[assembly: AssemblyInformationalVersion(Machine.Version)]
|
||||||
|
|
||||||
[assembly: CLSCompliant(false)]
|
[assembly: CLSCompliant(false)]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
[assembly: Guid("89a50370-1ed9-4cf1-ad08-043b6e6f3c90")]
|
[assembly: Guid("89a50370-1ed9-4cf1-ad08-043b6e6f3c90")]
|
||||||
|
|
||||||
[assembly: NeutralResourcesLanguage("en")]
|
[assembly: NeutralResourcesLanguage("en")]
|
||||||
|
|
||||||
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
|
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
|
||||||
|
|
|
@ -1,60 +1,60 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class WpfAudioService : AudioService
|
public sealed class WpfAudioService : AudioService
|
||||||
{
|
{
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
public WpfAudioService(Machine machine, UserControl page) :
|
public WpfAudioService(Machine machine, UserControl page) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("page");
|
throw new ArgumentNullException("page");
|
||||||
}
|
}
|
||||||
|
|
||||||
_directSound = new DirectSound(SampleRate, SampleChannels, SampleBits, SampleSize, OnDirectSoundUpdate);
|
_directSound = new DirectSound(SampleRate, SampleChannels, SampleBits, SampleSize, OnDirectSoundUpdate);
|
||||||
|
|
||||||
page.Loaded += (sender, e) =>
|
page.Loaded += (sender, e) =>
|
||||||
{
|
{
|
||||||
var window = Window.GetWindow(page);
|
var window = Window.GetWindow(page);
|
||||||
_directSound.Start(window.GetHandle());
|
_directSound.Start(window.GetHandle());
|
||||||
window.Closed += (_sender, _e) => _directSound.Stop();
|
window.Closed += (_sender, _e) => _directSound.Stop();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetVolume(float volume)
|
public override void SetVolume(float volume)
|
||||||
{
|
{
|
||||||
_directSound.SetVolume(volume);
|
_directSound.SetVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
_directSound.Dispose();
|
_directSound.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDirectSoundUpdate(IntPtr buffer, int bufferSize) // audio thread
|
private void OnDirectSoundUpdate(IntPtr buffer, int bufferSize) // audio thread
|
||||||
{
|
{
|
||||||
//if (_count++ % (1000 / SampleLatency) == 0)
|
//if (_count++ % (1000 / SampleLatency) == 0)
|
||||||
//{
|
//{
|
||||||
// DebugService.WriteLine("OnDirectSoundUpdate");
|
// DebugService.WriteLine("OnDirectSoundUpdate");
|
||||||
//}
|
//}
|
||||||
|
|
||||||
Marshal.Copy(Source, 0, buffer, bufferSize);
|
Marshal.Copy(Source, 0, buffer, bufferSize);
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DirectSound _directSound;
|
private DirectSound _directSound;
|
||||||
//private int _count;
|
//private int _count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
using System;
|
using System;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class WpfDebugService : DebugService
|
public sealed class WpfDebugService : DebugService
|
||||||
{
|
{
|
||||||
public WpfDebugService(Machine machine, MainPage page) :
|
public WpfDebugService(Machine machine, MainPage page) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("page");
|
throw new ArgumentNullException("page");
|
||||||
}
|
}
|
||||||
|
|
||||||
_page = page;
|
_page = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnWriteMessage(string message)
|
protected override void OnWriteMessage(string message)
|
||||||
{
|
{
|
||||||
_page.Dispatcher.Post(() => _page.WriteMessage(message));
|
_page.Dispatcher.Post(() => _page.WriteMessage(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private MainPage _page;
|
private MainPage _page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,298 +1,298 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class WpfKeyboardService : KeyboardService
|
public sealed class WpfKeyboardService : KeyboardService
|
||||||
{
|
{
|
||||||
public WpfKeyboardService(Machine machine, UserControl page) :
|
public WpfKeyboardService(Machine machine, UserControl page) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("page");
|
throw new ArgumentNullException("page");
|
||||||
}
|
}
|
||||||
|
|
||||||
page.KeyDown += OnPageKeyDown;
|
page.KeyDown += OnPageKeyDown;
|
||||||
page.KeyUp += OnPageKeyUp;
|
page.KeyUp += OnPageKeyUp;
|
||||||
page.GotKeyboardFocus += (sender, e) => _updateAnyKeyDown = true;
|
page.GotKeyboardFocus += (sender, e) => _updateAnyKeyDown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsKeyDown(int key)
|
public override bool IsKeyDown(int key)
|
||||||
{
|
{
|
||||||
return IsKeyDown((Key)key);
|
return IsKeyDown((Key)key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update() // main thread
|
public override void Update() // main thread
|
||||||
{
|
{
|
||||||
var keyboard = System.Windows.Input.Keyboard.PrimaryDevice;
|
var keyboard = System.Windows.Input.Keyboard.PrimaryDevice;
|
||||||
if (_updateAnyKeyDown)
|
if (_updateAnyKeyDown)
|
||||||
{
|
{
|
||||||
_updateAnyKeyDown = false;
|
_updateAnyKeyDown = false;
|
||||||
IsAnyKeyDown = false;
|
IsAnyKeyDown = false;
|
||||||
for (int i = 0; i < KeyValues.Length; i++)
|
for (int i = 0; i < KeyValues.Length; i++)
|
||||||
{
|
{
|
||||||
var key = KeyValues[i];
|
var key = KeyValues[i];
|
||||||
bool isKeyDown = keyboard.IsKeyDown(key);
|
bool isKeyDown = keyboard.IsKeyDown(key);
|
||||||
_states[(int)key] = isKeyDown;
|
_states[(int)key] = isKeyDown;
|
||||||
if (isKeyDown)
|
if (isKeyDown)
|
||||||
{
|
{
|
||||||
IsAnyKeyDown = true;
|
IsAnyKeyDown = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IsControlKeyDown = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
|
IsControlKeyDown = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
|
||||||
IsShiftKeyDown = ((keyboard.Modifiers & ModifierKeys.Shift) != 0);
|
IsShiftKeyDown = ((keyboard.Modifiers & ModifierKeys.Shift) != 0);
|
||||||
|
|
||||||
IsOpenAppleKeyDown = keyboard.IsKeyDown(Key.LeftAlt) || IsKeyDown(Key.NumPad0);
|
IsOpenAppleKeyDown = keyboard.IsKeyDown(Key.LeftAlt) || IsKeyDown(Key.NumPad0);
|
||||||
IsCloseAppleKeyDown = keyboard.IsKeyDown(Key.RightAlt) || IsKeyDown(Key.Decimal);
|
IsCloseAppleKeyDown = keyboard.IsKeyDown(Key.RightAlt) || IsKeyDown(Key.Decimal);
|
||||||
IsResetKeyDown = IsControlKeyDown && keyboard.IsKeyDown(Key.Back);
|
IsResetKeyDown = IsControlKeyDown && keyboard.IsKeyDown(Key.Back);
|
||||||
|
|
||||||
base.Update();
|
base.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsKeyDown(Key key)
|
private bool IsKeyDown(Key key)
|
||||||
{
|
{
|
||||||
return _states[(int)key];
|
return _states[(int)key];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPageKeyDown(object sender, KeyEventArgs e)
|
private void OnPageKeyDown(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
//DebugService.WriteLine(string.Concat("OnPageKeyDn: Key=", e.Key));
|
//DebugService.WriteLine(string.Concat("OnPageKeyDn: Key=", e.Key));
|
||||||
|
|
||||||
_states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = true;
|
_states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = true;
|
||||||
_updateAnyKeyDown = false;
|
_updateAnyKeyDown = false;
|
||||||
IsAnyKeyDown = true;
|
IsAnyKeyDown = true;
|
||||||
|
|
||||||
int asciiKey = GetAsciiKey(e.Key, e.KeyboardDevice);
|
int asciiKey = GetAsciiKey(e.Key, e.KeyboardDevice);
|
||||||
if (asciiKey >= 0)
|
if (asciiKey >= 0)
|
||||||
{
|
{
|
||||||
Machine.Keyboard.Latch = asciiKey;
|
Machine.Keyboard.Latch = asciiKey;
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPageKeyUp(object sender, KeyEventArgs e)
|
private void OnPageKeyUp(object sender, KeyEventArgs e)
|
||||||
{
|
{
|
||||||
//DebugService.WriteLine(string.Concat("OnPageKeyUp: Key=", e.Key));
|
//DebugService.WriteLine(string.Concat("OnPageKeyUp: Key=", e.Key));
|
||||||
|
|
||||||
_states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = false;
|
_states[(int)((e.Key == Key.System) ? e.SystemKey : e.Key)] = false;
|
||||||
_updateAnyKeyDown = true;
|
_updateAnyKeyDown = true;
|
||||||
|
|
||||||
bool control = ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) != 0);
|
bool control = ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) != 0);
|
||||||
|
|
||||||
if (control && (e.Key == Key.Divide))
|
if (control && (e.Key == Key.Divide))
|
||||||
{
|
{
|
||||||
Machine.Cpu.IsThrottled ^= true;
|
Machine.Cpu.IsThrottled ^= true;
|
||||||
}
|
}
|
||||||
else if (control && (e.Key == Key.Multiply))
|
else if (control && (e.Key == Key.Multiply))
|
||||||
{
|
{
|
||||||
Machine.Video.IsMonochrome ^= true;
|
Machine.Video.IsMonochrome ^= true;
|
||||||
}
|
}
|
||||||
else if (control && (e.Key == Key.Subtract))
|
else if (control && (e.Key == Key.Subtract))
|
||||||
{
|
{
|
||||||
Machine.Video.IsFullScreen ^= true;
|
Machine.Video.IsFullScreen ^= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||||
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
[SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
|
||||||
private static int GetAsciiKey(Key key, KeyboardDevice keyboard)
|
private static int GetAsciiKey(Key key, KeyboardDevice keyboard)
|
||||||
{
|
{
|
||||||
bool control = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
|
bool control = ((keyboard.Modifiers & ModifierKeys.Control) != 0);
|
||||||
bool shift = ((keyboard.Modifiers & ModifierKeys.Shift) != 0);
|
bool shift = ((keyboard.Modifiers & ModifierKeys.Shift) != 0);
|
||||||
bool capsLock = shift ^ keyboard.IsKeyToggled(Key.CapsLock);
|
bool capsLock = shift ^ keyboard.IsKeyToggled(Key.CapsLock);
|
||||||
|
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case Key.Left:
|
case Key.Left:
|
||||||
return 0x08;
|
return 0x08;
|
||||||
|
|
||||||
case Key.Tab:
|
case Key.Tab:
|
||||||
return 0x09;
|
return 0x09;
|
||||||
|
|
||||||
case Key.Down:
|
case Key.Down:
|
||||||
return 0x0A;
|
return 0x0A;
|
||||||
|
|
||||||
case Key.Up:
|
case Key.Up:
|
||||||
return 0x0B;
|
return 0x0B;
|
||||||
|
|
||||||
case Key.Enter:
|
case Key.Enter:
|
||||||
return 0x0D;
|
return 0x0D;
|
||||||
|
|
||||||
case Key.Right:
|
case Key.Right:
|
||||||
return 0x15;
|
return 0x15;
|
||||||
|
|
||||||
case Key.Escape:
|
case Key.Escape:
|
||||||
return 0x1B;
|
return 0x1B;
|
||||||
|
|
||||||
case Key.Back:
|
case Key.Back:
|
||||||
return control ? -1 : 0x7F;
|
return control ? -1 : 0x7F;
|
||||||
|
|
||||||
case Key.Space:
|
case Key.Space:
|
||||||
return ' ';
|
return ' ';
|
||||||
|
|
||||||
case Key.D1:
|
case Key.D1:
|
||||||
return shift ? '!' : '1';
|
return shift ? '!' : '1';
|
||||||
|
|
||||||
case Key.D2:
|
case Key.D2:
|
||||||
return control ? 0x00 : shift ? '@' : '2';
|
return control ? 0x00 : shift ? '@' : '2';
|
||||||
|
|
||||||
case Key.D3:
|
case Key.D3:
|
||||||
return shift ? '#' : '3';
|
return shift ? '#' : '3';
|
||||||
|
|
||||||
case Key.D4:
|
case Key.D4:
|
||||||
return shift ? '$' : '4';
|
return shift ? '$' : '4';
|
||||||
|
|
||||||
case Key.D5:
|
case Key.D5:
|
||||||
return shift ? '%' : '5';
|
return shift ? '%' : '5';
|
||||||
|
|
||||||
case Key.D6:
|
case Key.D6:
|
||||||
return control ? 0x1E : shift ? '^' : '6';
|
return control ? 0x1E : shift ? '^' : '6';
|
||||||
|
|
||||||
case Key.D7:
|
case Key.D7:
|
||||||
return shift ? '&' : '7';
|
return shift ? '&' : '7';
|
||||||
|
|
||||||
case Key.D8:
|
case Key.D8:
|
||||||
return shift ? '*' : '8';
|
return shift ? '*' : '8';
|
||||||
|
|
||||||
case Key.D9:
|
case Key.D9:
|
||||||
return shift ? '(' : '9';
|
return shift ? '(' : '9';
|
||||||
|
|
||||||
case Key.D0:
|
case Key.D0:
|
||||||
return shift ? ')' : '0';
|
return shift ? ')' : '0';
|
||||||
|
|
||||||
case Key.A:
|
case Key.A:
|
||||||
return control ? 0x01 : capsLock ? 'A' : 'a';
|
return control ? 0x01 : capsLock ? 'A' : 'a';
|
||||||
|
|
||||||
case Key.B:
|
case Key.B:
|
||||||
return control ? 0x02 : capsLock ? 'B' : 'b';
|
return control ? 0x02 : capsLock ? 'B' : 'b';
|
||||||
|
|
||||||
case Key.C:
|
case Key.C:
|
||||||
return control ? 0x03 : capsLock ? 'C' : 'c';
|
return control ? 0x03 : capsLock ? 'C' : 'c';
|
||||||
|
|
||||||
case Key.D:
|
case Key.D:
|
||||||
return control ? 0x04 : capsLock ? 'D' : 'd';
|
return control ? 0x04 : capsLock ? 'D' : 'd';
|
||||||
|
|
||||||
case Key.E:
|
case Key.E:
|
||||||
return control ? 0x05 : capsLock ? 'E' : 'e';
|
return control ? 0x05 : capsLock ? 'E' : 'e';
|
||||||
|
|
||||||
case Key.F:
|
case Key.F:
|
||||||
return control ? 0x06 : capsLock ? 'F' : 'f';
|
return control ? 0x06 : capsLock ? 'F' : 'f';
|
||||||
|
|
||||||
case Key.G:
|
case Key.G:
|
||||||
return control ? 0x07 : capsLock ? 'G' : 'g';
|
return control ? 0x07 : capsLock ? 'G' : 'g';
|
||||||
|
|
||||||
case Key.H:
|
case Key.H:
|
||||||
return control ? 0x08 : capsLock ? 'H' : 'h';
|
return control ? 0x08 : capsLock ? 'H' : 'h';
|
||||||
|
|
||||||
case Key.I:
|
case Key.I:
|
||||||
return control ? 0x09 : capsLock ? 'I' : 'i';
|
return control ? 0x09 : capsLock ? 'I' : 'i';
|
||||||
|
|
||||||
case Key.J:
|
case Key.J:
|
||||||
return control ? 0x0A : capsLock ? 'J' : 'j';
|
return control ? 0x0A : capsLock ? 'J' : 'j';
|
||||||
|
|
||||||
case Key.K:
|
case Key.K:
|
||||||
return control ? 0x0B : capsLock ? 'K' : 'k';
|
return control ? 0x0B : capsLock ? 'K' : 'k';
|
||||||
|
|
||||||
case Key.L:
|
case Key.L:
|
||||||
return control ? 0x0C : capsLock ? 'L' : 'l';
|
return control ? 0x0C : capsLock ? 'L' : 'l';
|
||||||
|
|
||||||
case Key.M:
|
case Key.M:
|
||||||
return control ? 0x0D : capsLock ? 'M' : 'm';
|
return control ? 0x0D : capsLock ? 'M' : 'm';
|
||||||
|
|
||||||
case Key.N:
|
case Key.N:
|
||||||
return control ? 0x0E : capsLock ? 'N' : 'n';
|
return control ? 0x0E : capsLock ? 'N' : 'n';
|
||||||
|
|
||||||
case Key.O:
|
case Key.O:
|
||||||
return control ? 0x0F : capsLock ? 'O' : 'o';
|
return control ? 0x0F : capsLock ? 'O' : 'o';
|
||||||
|
|
||||||
case Key.P:
|
case Key.P:
|
||||||
return control ? 0x10 : capsLock ? 'P' : 'p';
|
return control ? 0x10 : capsLock ? 'P' : 'p';
|
||||||
|
|
||||||
case Key.Q:
|
case Key.Q:
|
||||||
return control ? 0x11 : capsLock ? 'Q' : 'q';
|
return control ? 0x11 : capsLock ? 'Q' : 'q';
|
||||||
|
|
||||||
case Key.R:
|
case Key.R:
|
||||||
return control ? 0x12 : capsLock ? 'R' : 'r';
|
return control ? 0x12 : capsLock ? 'R' : 'r';
|
||||||
|
|
||||||
case Key.S:
|
case Key.S:
|
||||||
return control ? 0x13 : capsLock ? 'S' : 's';
|
return control ? 0x13 : capsLock ? 'S' : 's';
|
||||||
|
|
||||||
case Key.T:
|
case Key.T:
|
||||||
return control ? 0x14 : capsLock ? 'T' : 't';
|
return control ? 0x14 : capsLock ? 'T' : 't';
|
||||||
|
|
||||||
case Key.U:
|
case Key.U:
|
||||||
return control ? 0x15 : capsLock ? 'U' : 'u';
|
return control ? 0x15 : capsLock ? 'U' : 'u';
|
||||||
|
|
||||||
case Key.V:
|
case Key.V:
|
||||||
return control ? 0x16 : capsLock ? 'V' : 'v';
|
return control ? 0x16 : capsLock ? 'V' : 'v';
|
||||||
|
|
||||||
case Key.W:
|
case Key.W:
|
||||||
return control ? 0x17 : capsLock ? 'W' : 'w';
|
return control ? 0x17 : capsLock ? 'W' : 'w';
|
||||||
|
|
||||||
case Key.X:
|
case Key.X:
|
||||||
return control ? 0x18 : capsLock ? 'X' : 'x';
|
return control ? 0x18 : capsLock ? 'X' : 'x';
|
||||||
|
|
||||||
case Key.Y:
|
case Key.Y:
|
||||||
return control ? 0x19 : capsLock ? 'Y' : 'y';
|
return control ? 0x19 : capsLock ? 'Y' : 'y';
|
||||||
|
|
||||||
case Key.Z:
|
case Key.Z:
|
||||||
return control ? 0x1A : capsLock ? 'Z' : 'z';
|
return control ? 0x1A : capsLock ? 'Z' : 'z';
|
||||||
|
|
||||||
case Key.Oem1:
|
case Key.Oem1:
|
||||||
return shift ? ':' : ';';
|
return shift ? ':' : ';';
|
||||||
|
|
||||||
case Key.Oem2:
|
case Key.Oem2:
|
||||||
return shift ? '?' : '/';
|
return shift ? '?' : '/';
|
||||||
|
|
||||||
case Key.Oem3:
|
case Key.Oem3:
|
||||||
return shift ? '~' : '`';
|
return shift ? '~' : '`';
|
||||||
|
|
||||||
case Key.Oem4:
|
case Key.Oem4:
|
||||||
return shift ? '{' : '[';
|
return shift ? '{' : '[';
|
||||||
|
|
||||||
case Key.Oem5:
|
case Key.Oem5:
|
||||||
return control ? 0x1C : shift ? '|' : '\\';
|
return control ? 0x1C : shift ? '|' : '\\';
|
||||||
|
|
||||||
case Key.Oem6:
|
case Key.Oem6:
|
||||||
return control ? 0x1D : shift ? '}' : ']';
|
return control ? 0x1D : shift ? '}' : ']';
|
||||||
|
|
||||||
case Key.Oem7:
|
case Key.Oem7:
|
||||||
return shift ? '"' : '\'';
|
return shift ? '"' : '\'';
|
||||||
|
|
||||||
case Key.OemMinus:
|
case Key.OemMinus:
|
||||||
return control ? 0x1F : shift ? '_' : '-';
|
return control ? 0x1F : shift ? '_' : '-';
|
||||||
|
|
||||||
case Key.OemPlus:
|
case Key.OemPlus:
|
||||||
return shift ? '+' : '=';
|
return shift ? '+' : '=';
|
||||||
|
|
||||||
case Key.OemComma:
|
case Key.OemComma:
|
||||||
return shift ? '<' : ',';
|
return shift ? '<' : ',';
|
||||||
|
|
||||||
case Key.OemPeriod:
|
case Key.OemPeriod:
|
||||||
return shift ? '>' : '.';
|
return shift ? '>' : '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Key[] KeyValues =
|
private static readonly Key[] KeyValues =
|
||||||
(from key in (Key[])Enum.GetValues(typeof(Key))
|
(from key in (Key[])Enum.GetValues(typeof(Key))
|
||||||
where (key != Key.None) // filter Key.None; avoids validation exception
|
where (key != Key.None) // filter Key.None; avoids validation exception
|
||||||
select key).ToArray();
|
select key).ToArray();
|
||||||
|
|
||||||
private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
|
private static readonly int KeyCount = (int)(KeyValues.Max()) + 1;
|
||||||
|
|
||||||
private bool[] _states = new bool[KeyCount];
|
private bool[] _states = new bool[KeyCount];
|
||||||
private bool _updateAnyKeyDown;
|
private bool _updateAnyKeyDown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
using System.Deployment.Application;
|
using System.Deployment.Application;
|
||||||
using System.IO.IsolatedStorage;
|
using System.IO.IsolatedStorage;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class WpfStorageService : IsolatedStorageService
|
public sealed class WpfStorageService : IsolatedStorageService
|
||||||
{
|
{
|
||||||
public WpfStorageService(Machine machine) :
|
public WpfStorageService(Machine machine) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IsolatedStorageFile GetStore()
|
protected override IsolatedStorageFile GetStore()
|
||||||
{
|
{
|
||||||
return ApplicationDeployment.IsNetworkDeployed ? // clickonce
|
return ApplicationDeployment.IsNetworkDeployed ? // clickonce
|
||||||
IsolatedStorageFile.GetUserStoreForApplication() : IsolatedStorageFile.GetUserStoreForAssembly();
|
IsolatedStorageFile.GetUserStoreForApplication() : IsolatedStorageFile.GetUserStoreForAssembly();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,107 +1,107 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using Jellyfish.Library;
|
using Jellyfish.Library;
|
||||||
|
|
||||||
namespace Jellyfish.Virtu.Services
|
namespace Jellyfish.Virtu.Services
|
||||||
{
|
{
|
||||||
public sealed class WpfVideoService : VideoService
|
public sealed class WpfVideoService : VideoService
|
||||||
{
|
{
|
||||||
public WpfVideoService(Machine machine, UserControl page, Image image) :
|
public WpfVideoService(Machine machine, UserControl page, Image image) :
|
||||||
base(machine)
|
base(machine)
|
||||||
{
|
{
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("page");
|
throw new ArgumentNullException("page");
|
||||||
}
|
}
|
||||||
if (image == null)
|
if (image == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("image");
|
throw new ArgumentNullException("image");
|
||||||
}
|
}
|
||||||
|
|
||||||
_page = page;
|
_page = page;
|
||||||
_image = image;
|
_image = image;
|
||||||
_image.Source = _bitmap;
|
_image.Source = _bitmap;
|
||||||
|
|
||||||
_page.Loaded += (sender, e) => SetWindowSizeToContent();
|
_page.Loaded += (sender, e) => SetWindowSizeToContent();
|
||||||
_page.SizeChanged += (sender, e) => SetImageSize();
|
_page.SizeChanged += (sender, e) => SetImageSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetFullScreen(bool isFullScreen)
|
public override void SetFullScreen(bool isFullScreen)
|
||||||
{
|
{
|
||||||
if (_isFullScreen != isFullScreen)
|
if (_isFullScreen != isFullScreen)
|
||||||
{
|
{
|
||||||
_isFullScreen = isFullScreen;
|
_isFullScreen = isFullScreen;
|
||||||
_page.Dispatcher.Send(() =>
|
_page.Dispatcher.Send(() =>
|
||||||
{
|
{
|
||||||
var window = Window.GetWindow(_page);
|
var window = Window.GetWindow(_page);
|
||||||
if (_isFullScreen)
|
if (_isFullScreen)
|
||||||
{
|
{
|
||||||
window.ResizeMode = ResizeMode.NoResize;
|
window.ResizeMode = ResizeMode.NoResize;
|
||||||
window.WindowStyle = WindowStyle.None;
|
window.WindowStyle = WindowStyle.None;
|
||||||
window.WindowState = WindowState.Maximized;
|
window.WindowState = WindowState.Maximized;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
window.WindowState = WindowState.Normal;
|
window.WindowState = WindowState.Normal;
|
||||||
window.WindowStyle = WindowStyle.SingleBorderWindow;
|
window.WindowStyle = WindowStyle.SingleBorderWindow;
|
||||||
window.ResizeMode = ResizeMode.CanResize;
|
window.ResizeMode = ResizeMode.CanResize;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
|
[SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow")]
|
||||||
public override void SetPixel(int x, int y, uint color)
|
public override void SetPixel(int x, int y, uint color)
|
||||||
{
|
{
|
||||||
_pixels[y * BitmapWidth + x] = color;
|
_pixels[y * BitmapWidth + x] = color;
|
||||||
_pixelsDirty = true;
|
_pixelsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update() // main thread
|
public override void Update() // main thread
|
||||||
{
|
{
|
||||||
if (_pixelsDirty)
|
if (_pixelsDirty)
|
||||||
{
|
{
|
||||||
_pixelsDirty = false;
|
_pixelsDirty = false;
|
||||||
_bitmap.WritePixels(BitmapRect, _pixels, BitmapStride, 0);
|
_bitmap.WritePixels(BitmapRect, _pixels, BitmapStride, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetImageSize()
|
private void SetImageSize()
|
||||||
{
|
{
|
||||||
int uniformScale = Math.Max(1, Math.Min((int)_page.RenderSize.Width / BitmapWidth, (int)_page.RenderSize.Height / BitmapHeight));
|
int uniformScale = Math.Max(1, Math.Min((int)_page.RenderSize.Width / BitmapWidth, (int)_page.RenderSize.Height / BitmapHeight));
|
||||||
_image.Width = uniformScale * BitmapWidth;
|
_image.Width = uniformScale * BitmapWidth;
|
||||||
_image.Height = uniformScale * BitmapHeight;
|
_image.Height = uniformScale * BitmapHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetWindowSizeToContent()
|
private void SetWindowSizeToContent()
|
||||||
{
|
{
|
||||||
if (!_sizedToContent)
|
if (!_sizedToContent)
|
||||||
{
|
{
|
||||||
_sizedToContent = true;
|
_sizedToContent = true;
|
||||||
var window = Application.Current.MainWindow;
|
var window = Application.Current.MainWindow;
|
||||||
var size = window.DesiredSize;
|
var size = window.DesiredSize;
|
||||||
window.Width = size.Width;
|
window.Width = size.Width;
|
||||||
window.Height = size.Height;
|
window.Height = size.Height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int BitmapWidth = 560;
|
private const int BitmapWidth = 560;
|
||||||
private const int BitmapHeight = 384;
|
private const int BitmapHeight = 384;
|
||||||
private const int BitmapDpi = 96;
|
private const int BitmapDpi = 96;
|
||||||
private static readonly PixelFormat BitmapPixelFormat = PixelFormats.Bgr32;
|
private static readonly PixelFormat BitmapPixelFormat = PixelFormats.Bgr32;
|
||||||
private static readonly int BitmapStride = (BitmapWidth * BitmapPixelFormat.BitsPerPixel + 7) / 8;
|
private static readonly int BitmapStride = (BitmapWidth * BitmapPixelFormat.BitsPerPixel + 7) / 8;
|
||||||
private static readonly Int32Rect BitmapRect = new Int32Rect(0, 0, BitmapWidth, BitmapHeight);
|
private static readonly Int32Rect BitmapRect = new Int32Rect(0, 0, BitmapWidth, BitmapHeight);
|
||||||
|
|
||||||
private UserControl _page;
|
private UserControl _page;
|
||||||
private Image _image;
|
private Image _image;
|
||||||
private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight, BitmapDpi, BitmapDpi, BitmapPixelFormat, null);
|
private WriteableBitmap _bitmap = new WriteableBitmap(BitmapWidth, BitmapHeight, BitmapDpi, BitmapDpi, BitmapPixelFormat, null);
|
||||||
private uint[] _pixels = new uint[BitmapWidth * BitmapHeight];
|
private uint[] _pixels = new uint[BitmapWidth * BitmapHeight];
|
||||||
private bool _pixelsDirty;
|
private bool _pixelsDirty;
|
||||||
private bool _isFullScreen;
|
private bool _isFullScreen;
|
||||||
private bool _sizedToContent;
|
private bool _sizedToContent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue