public void RenderGray2(DMDFrame frame) { if (!_isOpen) { Init(); } int width = frame.width; int height = frame.height; if (_gray2Colorizer != null && frame.width == 128 && frame.height == 16 && _gray2Colorizer.Has128x32Animation) { // Pin2DMD colorization may have 512 byte masks with a 128x16 source, // indicating this should be upsized and treated as a centered 128x32 DMD. height = frame.height; height *= 2; _gray2Colorizer.SetDimensions(width, height); if (_upsizedFrame == null) { _upsizedFrame = new DMDFrame() { width = width, height = height, Data = new byte[width * height] } } ; Buffer.BlockCopy(frame.Data, 0, _upsizedFrame.Data, 8 * width, frame.Data.Length); _vpmGray2Source.NextFrame(_upsizedFrame); } else { _gray2Colorizer?.SetDimensions(width, height); _gray4Colorizer?.SetDimensions(width, height); _vpmGray2Source.NextFrame(frame); } }
public void RenderRgb24(DMDFrame frame) { if (!_isOpen) { Init(); } _vpmRgb24Source.NextFrame(frame); }
public void RenderGray4(DMDFrame frame) { if (!_isOpen) { Init(); } _gray2Colorizer?.SetDimensions(frame.width, frame.height); _gray4Colorizer?.SetDimensions(frame.width, frame.height); _vpmGray4Source.NextFrame(frame); }
public void Convert(DMDFrame frame) { if (_coloring.Palettes.Length > 1 && _animations == null) { if (frame.Data[0] == 0x08 && frame.Data[1] == 0x09 && frame.Data[2] == 0x0a && frame.Data[3] == 0x0b) { uint newpal = (uint)frame.Data[5] * 8 + (uint)frame.Data[4]; for (int i = 0; i < 6; i++) { frame.Data[i] = 0; } if (newpal != _lastEmbedded) { LoadPalette(newpal); if (!_coloring.DefaultPalette.IsPersistent) { _resetEmbedded = true; } _lastEmbedded = (int)newpal; } } else if (_resetEmbedded) { _lastEmbedded = _coloring.DefaultPaletteIndex; SetPalette(_coloring.DefaultPalette, _coloring.DefaultPaletteIndex); _resetEmbedded = false; } } byte[][] planes; if (Dimensions.Value.Width * Dimensions.Value.Height != frame.Data.Length * 4) { planes = FrameUtil.Split(Dimensions.Value.Width, Dimensions.Value.Height, 4, frame.Data); } else { planes = FrameUtil.Split(Dimensions.Value.Width / 2, Dimensions.Value.Height / 2, 4, frame.Data); } if (_coloring.Mappings != null) { if (frame is RawDMDFrame vd && vd.RawPlanes.Length > 0) { TriggerAnimation(vd.RawPlanes, false); } else { TriggerAnimation(planes, false); } }
public void Convert(DMDFrame frame) { var planes = FrameUtil.Split(Dimensions.Value.Width, Dimensions.Value.Height, 2, frame.Data); if (_coloring.Mappings != null) { if (frame is RawDMDFrame vd && vd.RawPlanes.Length > 0) { // Reverse bit order for non-WPC. TriggerAnimation(vd.RawPlanes, vd.RawPlanes.Length > 3); } else { TriggerAnimation(planes, false); } }
public void NextFrame(DMDFrame frame) { if (_lastFrameFormat.Value == FrameFormat.Rgb24 && _lastFrame != null && FrameUtil.CompareBuffers(frame.Data, 0, _lastFrame, 0, frame.Data.Length)) { // identical frame, drop. return; } if (_lastFrame?.Length != frame.Data.Length) { _lastFrame = new byte[frame.Data.Length]; } SetDimensions(frame.width, frame.height); _framesRgb24.OnNext(frame); Buffer.BlockCopy(frame.Data, 0, _lastFrame, 0, frame.Data.Length); _lastFrameFormat.OnNext(FrameFormat.Rgb24); }
public void RenderGray4(DMDFrame frame) { if (!_isOpen) { Init(); } int width = frame.width; int height = frame.height; if (_config.Global.ScaleToHd) { if (width == 128 && height == 32) { width *= 2; height *= 2; frame.Update(width, height, frame.Data); } } _gray2Colorizer?.SetDimensions(frame.width, frame.height); _gray4Colorizer?.SetDimensions(frame.width, frame.height); _vpmGray4Source.NextFrame(frame); }
public void Convert(DMDFrame frame) { byte[][] planes; if (Dimensions.Value.Width * Dimensions.Value.Height != frame.Data.Length * 4) { planes = FrameUtil.Split(Dimensions.Value.Width, Dimensions.Value.Height, 2, frame.Data); } else { planes = FrameUtil.Split(Dimensions.Value.Width / 2, Dimensions.Value.Height / 2, 2, frame.Data); } if (_coloring.Mappings != null) { if (frame is RawDMDFrame vd && vd.RawPlanes.Length > 0) { TriggerAnimation(vd.RawPlanes, false); } else { TriggerAnimation(planes, false); } }
public void NextFrame(DMDFrame frame) { SetDimensions(frame.width, frame.height); _framesGray2.OnNext(frame); _lastFrameFormat.OnNext(FrameFormat.Gray2); }
private void ServerThread(object data) { try { var server = new NamedPipeServerStream(PipeName, PipeDirection.In, 1, PipeTransmissionMode.Message); var isGameRunning = true; var chunkSize = 0; var gray2Frame = new DMDFrame { width = 132, height = 32 }; var messageChunk = new byte[4096]; // for each frame do { // connect and wait for a new frame server.WaitForConnection(); _lastTick = DateTime.Now.Ticks; // for each chunk do { chunkSize = server.Read(messageChunk, 0, messageChunk.Length); // game table has ended, clear the DMD with an empty byte array - chunkSize is only 4 if "done" is recieved from the pipe if (chunkSize == 4) { messageChunk = new byte[messageChunk.Length]; if (!_isPaused) { _onPause.OnNext(Unit.Default); _isPaused = true; } } else if (_isPaused) { _onResume.OnNext(Unit.Default); _isPaused = false; } } while (chunkSize != 0 || !server.IsMessageComplete); // convert message to frame data UpdateFrame(messageChunk); // publish frame data _framesGray4.OnNext(gray2Frame.Update(_frame)); // disconnect as the pipe was consumed server.Disconnect(); // wait for next cycle var sleepTicks = _ticksPerCycle - (DateTime.Now.Ticks - _lastTick); var sleepMs = (int)(sleepTicks / TimeSpan.TicksPerMillisecond); if (sleepMs > 0) { Thread.Sleep(sleepMs); } } while (isGameRunning); Logger.Info($"Pipe server for FutureDMD terminated!"); if (server != null) { server.Dispose(); } server = null; } catch (IOException e) { Logger.Error(e); } }