using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using Console = Game.Console; namespace Game { public class PlayerInputDemo : PlayerInput { protected List buffer = new List(); protected IEnumerator bufferEnumerable; public PlayerInputDemo(string demoPath) { if (!File.Exists(demoPath)) return; int expectedPlayerInputStateSize = Marshal.SizeOf(typeof(PlayerInputState)); FileStream stream = File.OpenRead(demoPath); int ver = stream.ReadByte(); int inputStateSize = stream.ReadByte(); if (ver != DemoVer && inputStateSize != expectedPlayerInputStateSize) { Console.Print("demover mismatch: version " + ver + " != " + DemoVer + ", inputStateSize " + inputStateSize + " != " + Marshal.SizeOf(typeof(PlayerInputState))); stream.Close(); return; } T RawDeserialize(byte[] rawData, int position) { int rawsize = Marshal.SizeOf(typeof(T)); if (rawsize > rawData.Length - position) throw new ArgumentException("Not enough data to fill struct. Array length from position: " + (rawData.Length - position) + ", Struct length: " + rawsize); IntPtr buffer = Marshal.AllocHGlobal(rawsize); Marshal.Copy(rawData, position, buffer, rawsize); T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T)); Marshal.FreeHGlobal(buffer); return retobj; } while (true) { byte[] b = new byte[expectedPlayerInputStateSize]; int readBytes = stream.Read(b, 0, b.Length); if (readBytes < expectedPlayerInputStateSize) break; buffer.Add(RawDeserialize(b, 0)); } bufferEnumerable = buffer.GetEnumerator(); Console.Print("demo numstates: " + buffer.Count); OnEndFrame(); // advances to first frame } public override void OnEndFrame() { // TODO: check if the current state frame matches the current frame number before advancing /*asdf++; if (asdf < 8) return;*/ if (bufferEnumerable == null || !bufferEnumerable.MoveNext()) { if (buffer.Any()) { bufferEnumerable.Dispose(); bufferEnumerable = null; buffer.Clear(); Console.Print("Demo ended"); } return; } //var actorState = currentState.actor; currentState.input = bufferEnumerable.Current; //frame++; //currentState.actor = actorState; } } }