public void LoadStateBinary(BinaryReader reader) { int size = api.QUERY_serialize_size(); byte[] buf = reader.ReadBytes(size); CoreLoadState(buf); if (DeterministicEmulation) // deserialize controller and fast-foward now { // reconstruct savestatebuff at the same time to avoid a costly core serialize MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write(buf); bool framezero = reader.ReadBoolean(); bw.Write(framezero); if (!framezero) { SnesSaveController ssc = new SnesSaveController(ControllerDefinition); ssc.DeSerialize(reader); IController tmp = this.Controller; this.Controller = ssc; nocallbacks = true; FrameAdvance(false, false); nocallbacks = false; this.Controller = tmp; ssc.Serialize(bw); } else // hack: dummy controller info { bw.Write(reader.ReadBytes(536)); } bw.Close(); savestatebuff = ms.ToArray(); } // other variables IsLagFrame = reader.ReadBoolean(); LagCount = reader.ReadInt32(); Frame = reader.ReadInt32(); var profile = reader.ReadString(); ValidateLoadstateProfile(profile); }
public void FrameAdvance(bool render, bool rendersound) { api.MessageCounter = 0; if(Settings.UseRingBuffer) api.BeginBufferIO(); /* if the input poll callback is called, it will set this to false * this has to be done before we save the per-frame state in deterministic * mode, because in there, the core actually advances, and might advance * through the point in time where IsLagFrame gets set to false. makes sense? */ IsLagFrame = true; // for deterministic emulation, save the state we're going to use before frame advance // don't do this during nocallbacks though, since it's already been done if (!nocallbacks && DeterministicEmulation) { MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write(CoreSaveState()); bw.Write(false); // not framezero SnesSaveController ssc = new SnesSaveController(); ssc.CopyFrom(Controller); ssc.Serialize(bw); bw.Close(); savestatebuff = ms.ToArray(); } if (!nocallbacks && CoreComm.Tracer.Enabled) api.QUERY_set_trace_callback(tracecb); else api.QUERY_set_trace_callback(null); // speedup when sound rendering is not needed if (!rendersound) api.QUERY_set_audio_sample(null); else api.QUERY_set_audio_sample(soundcb); bool resetSignal = Controller["Reset"]; if (resetSignal) api.CMD_reset(); bool powerSignal = Controller["Power"]; if (powerSignal) api.CMD_power(); //too many messages api.QUERY_set_layer_enable(0, 0, Settings.ShowBG1_0); api.QUERY_set_layer_enable(0, 1, Settings.ShowBG1_1); api.QUERY_set_layer_enable(1, 0, Settings.ShowBG2_0); api.QUERY_set_layer_enable(1, 1, Settings.ShowBG2_1); api.QUERY_set_layer_enable(2, 0, Settings.ShowBG3_0); api.QUERY_set_layer_enable(2, 1, Settings.ShowBG3_1); api.QUERY_set_layer_enable(3, 0, Settings.ShowBG4_0); api.QUERY_set_layer_enable(3, 1, Settings.ShowBG4_1); api.QUERY_set_layer_enable(4, 0, Settings.ShowOBJ_0); api.QUERY_set_layer_enable(4, 1, Settings.ShowOBJ_1); api.QUERY_set_layer_enable(4, 2, Settings.ShowOBJ_2); api.QUERY_set_layer_enable(4, 3, Settings.ShowOBJ_3); RefreshMemoryCallbacks(false); //apparently this is one frame? timeFrameCounter++; api.CMD_run(); while (api.QUERY_HasMessage) Console.WriteLine(api.QUERY_DequeueMessage()); if (IsLagFrame) LagCount++; //diagnostics for IPC traffic //Console.WriteLine(api.MessageCounter); api.EndBufferIO(); }
public void FrameAdvance(bool render, bool rendersound) { api.MessageCounter = 0; if (Settings.UseRingBuffer) { api.BeginBufferIO(); } /* if the input poll callback is called, it will set this to false * this has to be done before we save the per-frame state in deterministic * mode, because in there, the core actually advances, and might advance * through the point in time where IsLagFrame gets set to false. makes sense? */ IsLagFrame = true; // for deterministic emulation, save the state we're going to use before frame advance // don't do this during nocallbacks though, since it's already been done if (!nocallbacks && DeterministicEmulation) { MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write(CoreSaveState()); bw.Write(false); // not framezero SnesSaveController ssc = new SnesSaveController(); ssc.CopyFrom(Controller); ssc.Serialize(bw); bw.Close(); savestatebuff = ms.ToArray(); } if (!nocallbacks && CoreComm.Tracer.Enabled) { api.QUERY_set_trace_callback(tracecb); } else { api.QUERY_set_trace_callback(null); } // speedup when sound rendering is not needed if (!rendersound) { api.QUERY_set_audio_sample(null); } else { api.QUERY_set_audio_sample(soundcb); } bool resetSignal = Controller["Reset"]; if (resetSignal) { api.CMD_reset(); } bool powerSignal = Controller["Power"]; if (powerSignal) { api.CMD_power(); } //too many messages api.QUERY_set_layer_enable(0, 0, Settings.ShowBG1_0); api.QUERY_set_layer_enable(0, 1, Settings.ShowBG1_1); api.QUERY_set_layer_enable(1, 0, Settings.ShowBG2_0); api.QUERY_set_layer_enable(1, 1, Settings.ShowBG2_1); api.QUERY_set_layer_enable(2, 0, Settings.ShowBG3_0); api.QUERY_set_layer_enable(2, 1, Settings.ShowBG3_1); api.QUERY_set_layer_enable(3, 0, Settings.ShowBG4_0); api.QUERY_set_layer_enable(3, 1, Settings.ShowBG4_1); api.QUERY_set_layer_enable(4, 0, Settings.ShowOBJ_0); api.QUERY_set_layer_enable(4, 1, Settings.ShowOBJ_1); api.QUERY_set_layer_enable(4, 2, Settings.ShowOBJ_2); api.QUERY_set_layer_enable(4, 3, Settings.ShowOBJ_3); RefreshMemoryCallbacks(false); //apparently this is one frame? timeFrameCounter++; api.CMD_run(); while (api.QUERY_HasMessage) { Console.WriteLine(api.QUERY_DequeueMessage()); } if (IsLagFrame) { LagCount++; } //diagnostics for IPC traffic //Console.WriteLine(api.MessageCounter); api.EndBufferIO(); }