From 376dda4ea67524d153b7a687a814a3ad70b9ac86 Mon Sep 17 00:00:00 2001 From: Ian C Date: Sun, 6 May 2012 23:05:25 +0000 Subject: Added keyboard and place holder to move files under a difference license. --- different-licenses/Read Me.txt | 0 wpspec.sln | 24 ++++ wpspec/wpspec/App.xaml.cs | 8 ++ wpspec/wpspec/GamePage.xaml.cs | 98 +++++++++++++--- wpspec/wpspec/Shared.cs | 24 ++-- wpspec/wpspec/Spectrum/Emulation.cs | 126 ++++++++++++++++++++- wpspec/wpspec/wpspec.csproj | 10 ++ .../wpspecLibContent/wpspecLibContent.contentproj | 7 ++ 8 files changed, 269 insertions(+), 28 deletions(-) create mode 100644 different-licenses/Read Me.txt diff --git a/different-licenses/Read Me.txt b/different-licenses/Read Me.txt new file mode 100644 index 0000000..e69de29 diff --git a/wpspec.sln b/wpspec.sln index cca3c94..ab33399 100644 --- a/wpspec.sln +++ b/wpspec.sln @@ -15,6 +15,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Noddybox.Emulation.EightBit EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Noddybox.Emulation.EightBit.Z80.Disassembler", "..\Noddybox.Emulation\WindowsPhone\Noddybox.Emulation.EightBit.Z80.Disassembler\Noddybox.Emulation.EightBit.Z80.Disassembler.csproj", "{08D7120E-3D84-49D2-B73D-255E5DB9655C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Noddybox.Emulation.Keyboard.Schema", "..\EmulationKeyboard\WindowsPhone\Noddybox.Emulation.Keyboard.Schema\Noddybox.Emulation.Keyboard.Schema.csproj", "{0F5AA96A-9253-4E06-A3F9-5517A2A9C558}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Noddybox.Emulation.Xna.Keyboard", "..\EmulationKeyboard\WindowsPhone\Noddybox.Emulation.Xna.Keyboard\Noddybox.Emulation.Xna.Keyboard.csproj", "{3B034AAA-A9FD-4307-95F2-D87BE0A51990}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -95,6 +99,26 @@ Global {08D7120E-3D84-49D2-B73D-255E5DB9655C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {08D7120E-3D84-49D2-B73D-255E5DB9655C}.Release|Mixed Platforms.Build.0 = Release|Any CPU {08D7120E-3D84-49D2-B73D-255E5DB9655C}.Release|Windows Phone.ActiveCfg = Release|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Debug|Windows Phone.ActiveCfg = Debug|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Release|Any CPU.Build.0 = Release|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558}.Release|Windows Phone.ActiveCfg = Release|Any CPU + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Debug|Any CPU.ActiveCfg = Debug|Windows Phone + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Debug|Mixed Platforms.ActiveCfg = Debug|Windows Phone + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Debug|Mixed Platforms.Build.0 = Debug|Windows Phone + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Debug|Windows Phone.ActiveCfg = Debug|Windows Phone + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Debug|Windows Phone.Build.0 = Debug|Windows Phone + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Release|Any CPU.ActiveCfg = Release|Windows Phone + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Release|Mixed Platforms.ActiveCfg = Release|Windows Phone + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Release|Mixed Platforms.Build.0 = Release|Windows Phone + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Release|Windows Phone.ActiveCfg = Release|Windows Phone + {3B034AAA-A9FD-4307-95F2-D87BE0A51990}.Release|Windows Phone.Build.0 = Release|Windows Phone EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/wpspec/wpspec/App.xaml.cs b/wpspec/wpspec/App.xaml.cs index 8b490e8..5edf742 100644 --- a/wpspec/wpspec/App.xaml.cs +++ b/wpspec/wpspec/App.xaml.cs @@ -15,6 +15,9 @@ using Microsoft.Phone.Shell; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; +using System.Windows.Resources; +using Noddybox.Emulation.Keyboard.Schema; +using System.IO; namespace wpspec { @@ -84,6 +87,11 @@ namespace wpspec private void Application_Launching(object sender, LaunchingEventArgs e) { Shared.Spectrum = new Spectrum.Emulation(); + + using (BinaryReader stream = new BinaryReader(App.GetResourceStream(new Uri("Resources/Spectrum.keyboard", UriKind.Relative)).Stream)) + { + Shared.SpectrumKeyboard = KeyboardDefinition.Load(stream); + } } // Code to execute when the application is activated (brought to foreground) diff --git a/wpspec/wpspec/GamePage.xaml.cs b/wpspec/wpspec/GamePage.xaml.cs index 079b19f..96c690a 100644 --- a/wpspec/wpspec/GamePage.xaml.cs +++ b/wpspec/wpspec/GamePage.xaml.cs @@ -1,19 +1,30 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; +// This file is part of the wpspec Spectrum emulator. +// +// wpspec is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// wpspec is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Noddybox.Emulation. If not, see . +// +// Copyright (c) 2012 Ian Cowburn +// +using System; using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Input; using System.Windows.Navigation; -using System.Windows.Shapes; using Microsoft.Phone.Controls; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using wpspec.Spectrum; -using System.Diagnostics; +using Noddybox.Emulation.Xna.Keyboard; +using Microsoft.Xna.Framework.Input.Touch; namespace wpspec { @@ -26,6 +37,9 @@ namespace wpspec private SpriteBatch spriteBatch; private Texture2D screen; private Vector2 location; + private Rectangle locationZoomed; + private Texture2D keyboardImage; + private KeyboardDriver keyboard; #endregion @@ -76,8 +90,28 @@ namespace wpspec // timer.Start(); - location = new Vector2(SharedGraphicsDeviceManager.Current.GraphicsDevice.DisplayMode.Width / 2 - Shared.Spectrum.Width / 2, - 10); + // Initialise locations for normal and zoomed display + // + location = new Vector2(SharedGraphicsDeviceManager.Current.GraphicsDevice.DisplayMode.Width / 2 - Shared.Spectrum.Width / 2, 10); + locationZoomed = new Rectangle(SharedGraphicsDeviceManager.Current.GraphicsDevice.DisplayMode.Width / 2 - Shared.Spectrum.Width * 100 / 140, 10, + Shared.Spectrum.Height * 100 / 70, Shared.Spectrum.Width * 100 / 70); + + // Reset settings + // + Shared.Spectrum.ResetKeyboard(); + + // Create a keyboard driver + // + keyboardImage = contentManager.Load("keyboard"); + + keyboard = new KeyboardDriver + (SharedGraphicsDeviceManager.Current.GraphicsDevice, + keyboardImage, + new Vector2(0, 600), + Shared.SpectrumKeyboard); + + keyboard.KeyEvent += HandleKeyboardEvent; + keyboard.TouchEvent += HandleTouchEvent; base.OnNavigatedTo(e); } @@ -95,6 +129,10 @@ namespace wpspec screen.Dispose(); screen = null; + keyboard.KeyEvent -= HandleKeyboardEvent; + keyboard.TouchEvent -= HandleTouchEvent; + keyboard = null; + base.OnNavigatedFrom(e); } @@ -107,7 +145,7 @@ namespace wpspec /// private void OnUpdate(object sender, GameTimerEventArgs e) { - // TODO: Softkeyboard + keyboard.Update(); Shared.Spectrum.Run(); } @@ -121,11 +159,45 @@ namespace wpspec screen.SetData(Shared.Spectrum.Screen); spriteBatch.Begin(); - spriteBatch.Draw(screen, location, Color.White); + + if (Shared.IsZoomed) + { + spriteBatch.Draw(screen, locationZoomed, Color.White); + } + else + { + spriteBatch.Draw(screen, location, Color.White); + } + + keyboard.Draw(spriteBatch); spriteBatch.End(); SharedGraphicsDeviceManager.Current.GraphicsDevice.Textures[0] = null; } #endregion + + #region Keyboard driver events + + private void HandleKeyboardEvent(object sender, KeyboardDriver.KeyPressEventArgs e) + { + if (e.Pressed) + { + Shared.Spectrum.KeyPressed(e.Key); + } + else + { + Shared.Spectrum.KeyReleased(e.Key); + } + } + + private void HandleTouchEvent(object sender, KeyboardDriver.TouchLocationEventArgs e) + { + if (e.Location.State == TouchLocationState.Released && e.Location.Position.Y < 400) + { + Shared.IsZoomed = !Shared.IsZoomed; + } + } + + #endregion } } \ No newline at end of file diff --git a/wpspec/wpspec/Shared.cs b/wpspec/wpspec/Shared.cs index 28b8e9e..193d977 100644 --- a/wpspec/wpspec/Shared.cs +++ b/wpspec/wpspec/Shared.cs @@ -1,19 +1,11 @@ -using System; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Ink; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; +using Noddybox.Emulation.Keyboard.Schema; using wpspec.Spectrum; namespace wpspec { /// - /// Contains shared objects between the Silverlight and XNA domains + /// Contains shared objects between the Silverlight and XNA domains, and object and runtime + /// settings that need to persist between navigations to and from the game page. /// public static class Shared { @@ -21,5 +13,15 @@ namespace wpspec /// The emulation driving the Spectrum. /// public static Emulation Spectrum {get; set;} + + /// + /// Whether the display has been zoomed. + /// + public static bool IsZoomed {get; set;} + + /// + /// The layout for the spectrum keyboard. + /// + public static KeyboardDefinition SpectrumKeyboard {get; set;} } } diff --git a/wpspec/wpspec/Spectrum/Emulation.cs b/wpspec/wpspec/Spectrum/Emulation.cs index 9360462..7564022 100644 --- a/wpspec/wpspec/Spectrum/Emulation.cs +++ b/wpspec/wpspec/Spectrum/Emulation.cs @@ -1,5 +1,22 @@ -using System; -using System.Windows; +// This file is part of the wpspec Spectrum emulator. +// +// wpspec is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// wpspec is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Noddybox.Emulation. If not, see . +// +// Copyright (c) 2012 Ian Cowburn +// +using System; +using System.Collections.Generic; using Noddybox.Emulation; using Noddybox.Emulation.EightBit; using Noddybox.Emulation.EightBit.Z80; @@ -20,6 +37,20 @@ namespace wpspec.Spectrum { #region Private Data + private class KeyMatrix + { + public int Row {get; private set;} + public byte Set {get; private set; } + public byte Clear {get; private set;} + + public KeyMatrix(int row, byte set) + { + Row = row; + Set = set; + Clear = (byte)(set ^ 0xff); + } + } + private readonly byte[] mem = new byte[0x10000]; private readonly Clock clock = new Clock(0, 224, 312, 0); @@ -27,6 +58,8 @@ namespace wpspec.Spectrum private readonly byte[] matrix = new byte[9]; + private readonly Dictionary matrixLookup; + private readonly int[] screenAccel = new int[192]; private readonly int[] attrAccel = new int[192]; @@ -323,8 +356,6 @@ namespace wpspec.Spectrum matrix[f] = 0x1f; } - matrix[1] ^= 1; - matrix[8] = 0; Random rnd = new Random(); @@ -339,6 +370,41 @@ namespace wpspec.Spectrum Z80.Reset(); } + + /// + /// Reset the keyboard so that if the emulation continues from a break no keys can become stuck. + /// + public void ResetKeyboard() + { + for(int f = 0; f < 8; f++) + { + matrix[f] = 0x1f; + } + + matrix[8] = 0; + } + + + /// + /// Called when a key on the keyboard is pressed. + /// + /// The key. + public void KeyPressed(SpectrumKeySymbol key) + { + KeyMatrix m = matrixLookup[key]; + matrix[m.Row] &= m.Clear; + } + + /// + /// Called when a key on the keyboard is released. + /// + /// The key. + public void KeyReleased(SpectrumKeySymbol key) + { + KeyMatrix m = matrixLookup[key]; + matrix[m.Row] |= m.Set; + } + /// /// Run the emulation for a frame. /// @@ -407,6 +473,58 @@ namespace wpspec.Spectrum } } + // Initialise the matrix lookups + // + matrixLookup = new Dictionary(); + + matrixLookup[SpectrumKeySymbol.Key1] = new KeyMatrix(3, 0x01); + matrixLookup[SpectrumKeySymbol.Key2] = new KeyMatrix(3, 0x02); + matrixLookup[SpectrumKeySymbol.Key3] = new KeyMatrix(3, 0x04); + matrixLookup[SpectrumKeySymbol.Key4] = new KeyMatrix(3, 0x08); + matrixLookup[SpectrumKeySymbol.Key5] = new KeyMatrix(3, 0x10); + + matrixLookup[SpectrumKeySymbol.Key6] = new KeyMatrix(4, 0x10); + matrixLookup[SpectrumKeySymbol.Key7] = new KeyMatrix(4, 0x08); + matrixLookup[SpectrumKeySymbol.Key8] = new KeyMatrix(4, 0x04); + matrixLookup[SpectrumKeySymbol.Key9] = new KeyMatrix(4, 0x02); + matrixLookup[SpectrumKeySymbol.Key0] = new KeyMatrix(4, 0x01); + + matrixLookup[SpectrumKeySymbol.KeyQ] = new KeyMatrix(2, 0x01); + matrixLookup[SpectrumKeySymbol.KeyW] = new KeyMatrix(2, 0x02); + matrixLookup[SpectrumKeySymbol.KeyE] = new KeyMatrix(2, 0x04); + matrixLookup[SpectrumKeySymbol.KeyR] = new KeyMatrix(2, 0x08); + matrixLookup[SpectrumKeySymbol.KeyT] = new KeyMatrix(2, 0x10); + + matrixLookup[SpectrumKeySymbol.KeyY] = new KeyMatrix(5, 0x10); + matrixLookup[SpectrumKeySymbol.KeyU] = new KeyMatrix(5, 0x08); + matrixLookup[SpectrumKeySymbol.KeyI] = new KeyMatrix(5, 0x04); + matrixLookup[SpectrumKeySymbol.KeyO] = new KeyMatrix(5, 0x02); + matrixLookup[SpectrumKeySymbol.KeyP] = new KeyMatrix(5, 0x01); + + matrixLookup[SpectrumKeySymbol.KeyA] = new KeyMatrix(1, 0x01); + matrixLookup[SpectrumKeySymbol.KeyS] = new KeyMatrix(1, 0x02); + matrixLookup[SpectrumKeySymbol.KeyD] = new KeyMatrix(1, 0x04); + matrixLookup[SpectrumKeySymbol.KeyF] = new KeyMatrix(1, 0x08); + matrixLookup[SpectrumKeySymbol.KeyG] = new KeyMatrix(1, 0x10); + + matrixLookup[SpectrumKeySymbol.KeyH] = new KeyMatrix(6, 0x10); + matrixLookup[SpectrumKeySymbol.KeyJ] = new KeyMatrix(6, 0x08); + matrixLookup[SpectrumKeySymbol.KeyK] = new KeyMatrix(6, 0x04); + matrixLookup[SpectrumKeySymbol.KeyL] = new KeyMatrix(6, 0x02); + matrixLookup[SpectrumKeySymbol.KeyEnter] = new KeyMatrix(6, 0x01); + + matrixLookup[SpectrumKeySymbol.KeyCapsLock] = new KeyMatrix(0, 0x01); + matrixLookup[SpectrumKeySymbol.KeyZ] = new KeyMatrix(0, 0x02); + matrixLookup[SpectrumKeySymbol.KeyX] = new KeyMatrix(0, 0x04); + matrixLookup[SpectrumKeySymbol.KeyC] = new KeyMatrix(0, 0x08); + matrixLookup[SpectrumKeySymbol.KeyV] = new KeyMatrix(0, 0x10); + + matrixLookup[SpectrumKeySymbol.KeyB] = new KeyMatrix(7, 0x10); + matrixLookup[SpectrumKeySymbol.KeyN] = new KeyMatrix(7, 0x08); + matrixLookup[SpectrumKeySymbol.KeyM] = new KeyMatrix(7, 0x04); + matrixLookup[SpectrumKeySymbol.KeySymbolShift] = new KeyMatrix(7, 0x02); + matrixLookup[SpectrumKeySymbol.KeySpace] = new KeyMatrix(7, 0x01); + // Initialise the clock events // clock.EndOfLine += LineHandler; diff --git a/wpspec/wpspec/wpspec.csproj b/wpspec/wpspec/wpspec.csproj index eb2cf9c..34fc200 100644 --- a/wpspec/wpspec/wpspec.csproj +++ b/wpspec/wpspec/wpspec.csproj @@ -105,6 +105,7 @@ + @@ -153,6 +154,7 @@ Designer + @@ -164,6 +166,14 @@ + + {0F5AA96A-9253-4E06-A3F9-5517A2A9C558} + Noddybox.Emulation.Keyboard.Schema + + + {3B034AAA-A9FD-4307-95F2-D87BE0A51990} + Noddybox.Emulation.Xna.Keyboard + {08D7120E-3D84-49D2-B73D-255E5DB9655C} Noddybox.Emulation.EightBit.Z80.Disassembler diff --git a/wpspec/wpspecLibContent/wpspecLibContent.contentproj b/wpspec/wpspecLibContent/wpspecLibContent.contentproj index e7e4df7..c0e0454 100644 --- a/wpspec/wpspecLibContent/wpspecLibContent.contentproj +++ b/wpspec/wpspecLibContent/wpspecLibContent.contentproj @@ -41,6 +41,13 @@ False + + + keyboard + TextureImporter + TextureProcessor + +