public bool TryRender(VideoUpdatedEventArgs e) { AssertUndisposed(); if (!_isBusy.TryAcquire(true)) { return false; } DataBox dataBox = _context.MapSubresource(_texture, 0, 512 * 512 * 4, MapMode.WriteDiscard, SlimDX.Direct3D11.MapFlags.None); unsafe { ushort* snesBuffer = (ushort*)e.VideoBuffer.DataPointer; byte* textureBuffer = (byte*)dataBox.Data.DataPointer; for (int j = 0; j < e.Height; j++) { for (int i = 0; i < e.Width; i++) { ushort color = *snesBuffer++; int b; b = ((color >> 10) & 31) * 8; *textureBuffer++ = (byte)(b + b / 35); b = ((color >> 5) & 31) * 8; *textureBuffer++ = (byte)(b + b / 35); b = ((color >> 0) & 31) * 8; *textureBuffer++ = (byte)(b + b / 35); *textureBuffer++ = 255; } textureBuffer += dataBox.RowPitch - e.Width * 4; snesBuffer += e.Height > 256 ? 512 - e.Width : 1024 - e.Width; } } dataBox.Data.Close(); _context.UnmapSubresource(_texture, 0); _workerThread.DoWork(new Action(() => { AssertUndisposed(); _context.ClearRenderTargetView(_backBufferView, new Color4(0.0F, 0.0F, 0.0F)); _context.InputAssembler.InputLayout = _layout; _context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip; _context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(_vertices, Marshal.SizeOf(typeof(Vertex)), 0)); _effect.GetVariableByName("TexelRange").AsVector().Set(new Vector2(e.Width / 512.0F, e.Height / 512.0F)); _pass.Apply(_context); _context.Draw(4, 0); Present(IsComposited && !IsFullscreen ? 0 : 1, PresentFlags.None); _isBusy.Value = false; })); return true; }
void Snes_VideoUpdated(object sender, VideoUpdatedEventArgs e) { if (_isVideoSynced) { _videoDriver.Render(e); } else { _videoDriver.TryRender(e); } }
public void Render(VideoUpdatedEventArgs e) { while (!TryRender(e)) { _isBusy.WaitWhile(); } }