public bool FrameAdvance(IController controller, bool render, bool rendersound) { _controller = controller; _lagged = true; _frame++; if (!IsGameGear) { PSG.Set_Panning(Settings.ForceStereoSeparation ? ForceStereoByte : (byte)0xFF); } if (Tracer.Enabled) { Cpu.TraceCallback = s => Tracer.Put(s); } else { Cpu.TraceCallback = null; } if (IsGameGear_C == false) { Cpu.NonMaskableInterrupt = controller.IsPressed("Pause"); } else if (!IsGameGear && IsGameGear_C) { Cpu.NonMaskableInterrupt = controller.IsPressed("P1 Start"); } if (IsGame3D && Settings.Fix3D) { render = ((Frame & 1) == 0) & render; } int scanlinesPerFrame = Vdp.DisplayType == DisplayType.NTSC ? 262 : 313; Vdp.SpriteLimit = Settings.SpriteLimit; for (int i = 0; i < scanlinesPerFrame; i++) { Vdp.ScanLine = i; Vdp.RenderCurrentScanline(render); Vdp.ProcessFrameInterrupt(); Vdp.ProcessLineInterrupt(); ProcessLineControls(); for (int j = 0; j < Vdp.IPeriod; j++) { Cpu.ExecuteOne(); PSG.generate_sound(); s_L = PSG.current_sample_L; s_R = PSG.current_sample_R; if (s_L != old_s_L) { blip_L.AddDelta(sampleclock, s_L - old_s_L); old_s_L = s_L; } if (s_R != old_s_R) { blip_R.AddDelta(sampleclock, s_R - old_s_R); old_s_R = s_R; } sampleclock++; } if (Vdp.ScanLine == scanlinesPerFrame - 1) { Vdp.ProcessGGScreen(); Vdp.ProcessOverscan(); } } if (_lagged) { _lagCount++; _isLag = true; } else { _isLag = false; } return(true); }