Some work on the RecordingGamePad.

This commit is contained in:
SND\simsmaster_cp 2012-08-08 12:04:37 +00:00
parent d9d44bfba0
commit 3ca3e314d7
6 changed files with 173 additions and 41 deletions

View File

@ -65,13 +65,13 @@ namespace ANX.InputSystem.Recording
#if XNAEXT #if XNAEXT
RecordingMotionSensingDevice msd; RecordingMotionSensingDevice msd;
#endif #endif
public IGamePad GamePad public IGamePad GamePad
{ {
get get
{ {
AddInSystemFactory.Instance.PreventSystemChange( AddInSystemFactory.Instance.PreventSystemChange(
AddInType.InputSystem); AddInType.InputSystem);
if (gamePad == null) if (gamePad == null)
gamePad = new RecordingGamePad(); gamePad = new RecordingGamePad();
return gamePad; return gamePad;
@ -81,9 +81,9 @@ namespace ANX.InputSystem.Recording
public IMouse Mouse public IMouse Mouse
{ {
get get
{ {
AddInSystemFactory.Instance.PreventSystemChange( AddInSystemFactory.Instance.PreventSystemChange(
AddInType.InputSystem); AddInType.InputSystem);
if (mouse == null) if (mouse == null)
mouse = new RecordingMouse(); mouse = new RecordingMouse();
return mouse; return mouse;
@ -93,9 +93,9 @@ namespace ANX.InputSystem.Recording
public IKeyboard Keyboard public IKeyboard Keyboard
{ {
get get
{ {
AddInSystemFactory.Instance.PreventSystemChange( AddInSystemFactory.Instance.PreventSystemChange(
AddInType.InputSystem); AddInType.InputSystem);
if (keyboard == null) if (keyboard == null)
keyboard = new RecordingKeyboard(); keyboard = new RecordingKeyboard();
return keyboard; return keyboard;
@ -106,9 +106,9 @@ namespace ANX.InputSystem.Recording
public IMotionSensingDevice MotionSensingDevice public IMotionSensingDevice MotionSensingDevice
{ {
get get
{ {
AddInSystemFactory.Instance.PreventSystemChange( AddInSystemFactory.Instance.PreventSystemChange(
AddInType.InputSystem); AddInType.InputSystem);
if (msd == null) if (msd == null)
msd = new RecordingMotionSensingDevice(); msd = new RecordingMotionSensingDevice();
return msd; return msd;

View File

@ -70,7 +70,7 @@ namespace ANX.InputSystem.Recording
public event EventHandler EndOfPlaybackReached; public event EventHandler EndOfPlaybackReached;
/// <summary> /// <summary>
/// How many bytes this Instance requires per Paket. Must never change! /// How many bytes this Instance requires per Packet. Must never change!
/// </summary> /// </summary>
public int PacketLenght { get; protected set; } public int PacketLenght { get; protected set; }
@ -150,17 +150,35 @@ namespace ANX.InputSystem.Recording
} }
if (state.Length != PacketLenght) if (state.Length != PacketLenght)
throw new InvalidOperationException("The passed state's lenght does not match the speficed FramePaketLenght."); throw new InvalidOperationException("The passed state's lenght does not match the speficed FramePacketLenght.");
TryWriteNullStates();
recordStream.WriteByte((byte)PacketType.InputData);
recordStream.Write(state, 0, state.Length);
}
/// <summary>
/// Writes a custom packet to the stream. When this packet is found during ReadState()
/// HandleUserPacket is called to handle the packet. Please note that the packetTypes 0 and
/// 1 are reseved.
/// </summary>
protected virtual void WriteUserState(byte packetType, byte[] packetData)
{
TryWriteNullStates();
recordStream.WriteByte(packetType);
recordStream.WriteByte(packetData.Length);
}
private void TryWriteNullStates()
{
if (nullStateCounter > 0) //Note how many packets we had nothing if (nullStateCounter > 0) //Note how many packets we had nothing
{ {
recordStream.WriteByte((byte)PacketType.NullFrameCounter); recordStream.WriteByte((byte)PacketType.NullFrameCounter);
recordStream.Write(BitConverter.GetBytes(nullStateCounter), 0, 4); recordStream.Write(BitConverter.GetBytes(nullStateCounter), 0, 4);
nullStateCounter = 0; nullStateCounter = 0;
} }
recordStream.WriteByte((byte)PacketType.InputData);
recordStream.Write(state, 0, state.Length);
} }
/// <summary> /// <summary>
@ -178,7 +196,7 @@ namespace ANX.InputSystem.Recording
if (recordStream.Position == recordStream.Length) if (recordStream.Position == recordStream.Length)
{ {
OnEndOfPlaybackReached(); OnEndOfPlaybackReached();
return null; //TODO: Better switch to RecordingState.None here? return null;
} }
PacketType type = (PacketType)recordStream.ReadByte(); PacketType type = (PacketType)recordStream.ReadByte();
@ -193,8 +211,12 @@ namespace ANX.InputSystem.Recording
byte[] buffer2 = new byte[PacketLenght]; byte[] buffer2 = new byte[PacketLenght];
recordStream.Read(buffer2, 0, PacketLenght); recordStream.Read(buffer2, 0, PacketLenght);
return buffer2; return buffer2;
default: default: //Custom Packet Type
throw new NotImplementedException("The PaketType " + Enum.GetName(typeof(PacketType), type) + "is not supported."); byte packetLenght = (byte)recordStream.ReadByte();
byte[] buffer3 = new byte[packetLenght];
recordStream.Read(buffer3, 0, packetLenght);
HandleUserPacket((byte)type, buffer3);
return ReadState(); //We read another packet until we find a "valid" one.
} }
} }
@ -210,5 +232,13 @@ namespace ANX.InputSystem.Recording
if (EndOfPlaybackReached != null) if (EndOfPlaybackReached != null)
EndOfPlaybackReached(this, EventArgs.Empty); EndOfPlaybackReached(this, EventArgs.Empty);
} }
/// <summary>
/// Overwrite this method to handle custom packet types written by WriteUserState(). When
/// ReadState() encounters an unknown packet type this method is called.
/// </summary>
protected virtual void HandleUserPacket(byte packetType, byte[] packetData)
{
}
} }
} }

View File

@ -6,6 +6,7 @@ using System.Text;
using ANX.Framework.NonXNA; using ANX.Framework.NonXNA;
using ANX.Framework.Input; using ANX.Framework.Input;
using ANX.Framework; using ANX.Framework;
using System.IO;
#endregion #endregion
@ -58,14 +59,50 @@ using ANX.Framework;
namespace ANX.InputSystem.Recording namespace ANX.InputSystem.Recording
{ {
[Flags]
enum GamePadRecordInfo : int
{
LeftStick = 1,
RightStick = 2,
LeftTrigger = 4,
RightTrigger = 8,
AButton = 16,
BButton = 32,
XButton = 64,
YButton = 128,
StartButton = 256,
BackButton = 512,
LeftShoulderButton = 1024,
RightShoulderButton = 2048,
LeftStickButton = 4096,
RightStickButton = 8192,
DPadUp = 16384,
DPadDown = 32768,
DPadLeft = 65536,
DPadRight = 131072,
BothSticks = LeftStick | RightStick,
BothTriggers = LeftTrigger | RightTrigger,
AllAnalog = BothSticks | BothTriggers,
ABXYButton = AButton | BButton | XButton | YButton,
BothStickButtons = LeftStickButton | RightStickButton,
BothSoulderButtons = LeftShoulderButton | RightShoulderButton,
AllDPad = DPadUp | DPadDown | DPadLeft | DPadRight,
AllButtons = ABXYButton | BothStickButtons | StartButton | BackButton | BothSoulderButtons,
All = AllAnalog | AllButtons | AllDPad
}
/// <summary> /// <summary>
/// Wrapper arround another IGamePad, will record all inputs and allows playback. /// Wrapper arround another IGamePad, will record all inputs and allows playback.
/// </summary> /// </summary>
public class RecordingGamePad : RecordableDevice, IGamePad public class RecordingGamePad : RecordableDevice, IGamePad
{ {
public GamePadCapabilities GetCapabilities(PlayerIndex playerIndex) private IGamePad realGamePad;
private GamePadRecordInfo recordInfo;
public GamePadCapabilities GetCapabilities(PlayerIndex playerIndex) //no recording here...
{ {
throw new NotImplementedException(); return realGamePad.GetCapabilities(playerIndex);
} }
public GamePadState GetState(PlayerIndex playerIndex, out bool isConnected, out int packetNumber) public GamePadState GetState(PlayerIndex playerIndex, out bool isConnected, out int packetNumber)
@ -73,7 +110,7 @@ namespace ANX.InputSystem.Recording
throw new NotImplementedException(); throw new NotImplementedException();
} }
public GamePadState GetState(PlayerIndex playerIndex, Framework.Input.GamePadDeadZone deadZoneMode, out bool isConnected, out int packetNumber) public GamePadState GetState(PlayerIndex playerIndex, GamePadDeadZone deadZoneMode, out bool isConnected, out int packetNumber)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -82,5 +119,51 @@ namespace ANX.InputSystem.Recording
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <summary>
/// Intializes this instance using a new MemoryStream as the Buffer, the
/// default's InputSystems GamePad and the passed GamePadRecordInfo.
/// </summary>
public void Initialize(GamePadRecordInfo info)
{
this.Initialize(info, new MemoryStream(), InputDeviceFactory.Instance.GetDefaultGamePad());
}
/// <summary>
/// Intializes this instance using a new MemoryStream as the Buffer, recording
/// the passed IGamePad, using the passed GamePadRecordInfo.
/// </summary>
public void Initialize(GamePadRecordInfo info, IGamePad gamePad)
{
this.Initialize(info, new MemoryStream(), gamePad);
}
/// <summary>
/// Intializes this instance using the passed Stream as the Buffer, the
/// default's InputSystems GamePad and the passed GamePadRecordInfo.
/// </summary>
public void Initialize(GamePadRecordInfo info, Stream bufferStream)
{
this.Initialize(info, bufferStream, InputDeviceFactory.Instance.GetDefaultGamePad());
}
/// <summary>
/// Intializes this instance using the passed Stream as the Buffer, recording
/// the passed IGamePad, using the passed GamePadRecordInfo.
/// </summary>
public void Initialize(GamePadRecordInfo info, Stream bufferStream, IGamePad gamePad)
{
realGamePad = gamePad;
recordInfo = info;
PacketLenght = GetPaketSize(info);
base.Initialize(bufferStream);
}
private int GetPaketSize(GamePadRecordInfo info)
{
throw new NotImplementedException();
}
} }
} }

View File

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using ANX.Framework.NonXNA;
#endregion #endregion
@ -71,6 +72,7 @@ namespace ANX.InputSystem.Recording
None None
} }
//0-1 are reserved for the recording Engine, 2-255 can be used using WriteUserState().
enum PacketType : byte enum PacketType : byte
{ {
NullFrameCounter = 0, NullFrameCounter = 0,
@ -78,10 +80,32 @@ namespace ANX.InputSystem.Recording
} }
/// <summary> /// <summary>
/// Static Helper-class containing some recording related stuff. /// Static Helper-class containing some recording-related stuff.
/// </summary> /// </summary>
static class RecordingHelper public static class RecordingHelper
{ {
/// <summary>
/// Returns the RecordingMouse of the RecordingInput-System.
/// </summary>
public static RecordingMouse GetMouse()
{
return ((RecordingMouse)AddInSystemFactory.Instance.GetCreator<IInputSystemCreator>("Recording").Mouse);
}
/// <summary>
/// Returns the RecordingKeyboard of the RecordingInput-System.
/// </summary>
public static RecordingKeyboard GetKeyboard()
{
return ((RecordingKeyboard)AddInSystemFactory.Instance.GetCreator<IInputSystemCreator>("Recording").Keyboard);
}
/// <summary>
/// Returns the RecordingGamePad of the RecordingInput-System.
/// </summary>
public static RecordingGamePad GetGamepad()
{
return ((RecordingGamePad)AddInSystemFactory.Instance.GetCreator<IInputSystemCreator>("Recording").GamePad);
}
} }
} }

View File

@ -60,7 +60,7 @@ using ANX.InputSystem.Recording;
namespace RecordingSample namespace RecordingSample
{ {
/// <summary> /// <summary>
/// Sample, showing the use of the RecordingSystem (currently only the Mouse). /// Sample, showing the use of the RecordingSystem.
/// </summary> /// </summary>
public class Game1 : Game public class Game1 : Game
{ {
@ -81,12 +81,11 @@ namespace RecordingSample
protected override void Initialize() protected override void Initialize()
{ {
Window.Title = "Use Mouse to move arround, press r to record, p for playback and n for none"; Window.Title = "Move the Mouse or press Enter. press R to record, P for playback and N for none";
//this is quite ugly... could this be improved? recMouse = RecordingHelper.GetMouse(); //((RecordingMouse)AddInSystemFactory.Instance.GetDefaultCreator<IInputSystemCreator>().Mouse);
recMouse = ((RecordingMouse)AddInSystemFactory.Instance.GetDefaultCreator<IInputSystemCreator>().Mouse);
recMouse.Initialize(MouseRecordInfo.Position); recMouse.Initialize(MouseRecordInfo.Position);
recKeyboard = ((RecordingKeyboard)AddInSystemFactory.Instance.GetDefaultCreator<IInputSystemCreator>().Keyboard); recKeyboard = RecordingHelper.GetKeyboard();
recKeyboard.Initialize(Keys.Enter); recKeyboard.Initialize(Keys.Enter);
base.Initialize(); base.Initialize();
@ -142,13 +141,10 @@ namespace RecordingSample
GraphicsDevice.Clear(Color.CornflowerBlue); GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(); spriteBatch.Begin();
if (Keyboard.GetState().IsKeyDown(Keys.Enter)) if (Keyboard.GetState().IsKeyDown(Keys.Enter)) //Keyboard
{
spriteBatch.Draw(logo, Vector2.Zero, Color.White); spriteBatch.Draw(logo, Vector2.Zero, Color.White);
}
//spriteBatch.End(); spriteBatch.Draw(logo, new Rectangle(Mouse.GetState().X, Mouse.GetState().Y, 115, 30), Color.White); //Mouse
//spriteBatch.Begin();
spriteBatch.Draw(logo, new Rectangle(Mouse.GetState().X, Mouse.GetState().Y, 115, 30), Color.White);
spriteBatch.End(); spriteBatch.End();
base.Draw(gameTime); base.Draw(gameTime);

View File

@ -9,8 +9,7 @@ namespace RecordingSample
static void Main(string[] args) static void Main(string[] args)
{ {
//This is technically unessasary, because there is only a reference to the RecordingSystem... //This is technically unessasary, because there is only a reference to the RecordingSystem...
AddInSystemFactory.Instance.SetPreferredSystem( AddInSystemFactory.Instance.SetPreferredSystem(AddInType.InputSystem, "Recording");
AddInType.InputSystem, "Recording");
using (Game1 game = new Game1()) using (Game1 game = new Game1())
{ {