public override Frame transition_frame(Frame from_frame, Frame to_frame) { Frame frame = from_frame.copy(); int dst_x = 0; int dst_y = 0; double prog = this.progress; if (this.in_out == true) { prog = 1.0 - prog; } if (this.direction == SlideOverTransitionDirection.North) { dst_x = 0; dst_y = (int)(prog * frame.height); } else if (this.direction == SlideOverTransitionDirection.South) { dst_x = 0; dst_y = (int)(-prog * frame.height); } else if (this.direction == SlideOverTransitionDirection.East) { dst_x = (int)(-prog * frame.width); dst_y = 0; } else if (this.direction == SlideOverTransitionDirection.West) { dst_x = (int)(prog * frame.width); dst_y = 0; } Frame.copy_rect(frame, dst_x, dst_y, to_frame, 0, 0, from_frame.width, from_frame.height, DMDBlendMode.DMDBlendModeCopy); return frame; }
public ObscuredWipeTransition(Frame obscuring_frame, DMDBlendMode composite_op, ObscuredWipeTransitionDirection direction = ObscuredWipeTransitionDirection.North) { this.composite_op = composite_op; this.direction = direction; this.progress_per_frame = 1.0 / 15.0; this.obs_frame = obscuring_frame; }
public override Frame transition_frame(Frame from_frame, Frame to_frame) { Frame frame = new Frame(from_frame.width, from_frame.height); int dst_x = 0; int dst_y = 0; int width, height; double prog = this.progress; if (this.in_out == false) prog = 1.0 - prog; if (this.direction == ExpandTransitionDirection.Vertical) { dst_x = 0; dst_y = Convert.ToInt32((frame.height / 2 - prog * (frame.height / 2))); width = frame.width; height = Convert.ToInt32(prog * frame.height); } else { dst_x = Convert.ToInt32((frame.width / 2 - prog * (frame.width / 2))); dst_y = 0; width = Convert.ToInt32(prog * frame.width); height = frame.height; } Frame.copy_rect(frame, dst_x, dst_y, to_frame, dst_x, dst_y, width, height, DMDBlendMode.DMDBlendModeCopy); return frame; }
/// <summary> /// Returns a Frame with the given markup rendered within it. /// /// The frame width is fixed, but the height will be adjusted to fit the contents while respecting /// min_height. /// /// The Y offset can be configured by supplying 'y_offset' /// </summary> public Frame frame_for_markup(string markup, int y_offset = 0) { markup = markup.Replace("\r", ""); string[] lines = markup.Split('\n'); foreach (bool draw in new bool[] { false, true }) { int y = y_offset; foreach (string line in lines) { if (line.StartsWith("#") && line.EndsWith("#")) // Centered headline y = this.draw_text(y, line.Substring(1, line.Length - 2), font_bold, FontJustify.Center, draw); else if (line.StartsWith("#")) // Left justified headline y = this.draw_text(y, line.Substring(1), font_bold, FontJustify.Left, draw); else if (line.EndsWith("#")) // Right justified headline y = this.draw_text(y, line.Substring(0, line.Length - 2), font_bold, FontJustify.Right, draw); else if (line.StartsWith("[") && line.EndsWith("]")) // Centered text y = this.draw_text(y, line.Substring(1, line.Length - 2), font_plain, FontJustify.Center, draw); else if (line.EndsWith("]")) // Right justified text y = this.draw_text(y, line.Substring(0, line.Length - 2), font_plain, FontJustify.Right, draw); else if (line.StartsWith("[")) // Left justified text y = this.draw_text(y, line.Substring(1), font_plain, FontJustify.Left, draw); else // Left justified but nothing to clip off y = this.draw_text(y, line, font_plain, FontJustify.Left, draw); } if (!draw) this.frame = new Frame(this.width, Math.Max(this.min_height, y)); } return this.frame; }
public Frame subframe(int x, int y, int width, int height) { // Generates a new frame based on a sub rectangle of this frame Frame subframe = new Frame(width, height); Frame.copy_rect(subframe, 0, 0, this, x, y, width, height, DMDBlendMode.DMDBlendModeCopy); return subframe; }
public GroupedLayer(int width, int height, List<Layer> layers = null) { this.buffer = new Frame(width, height); if (layers == null) this.layers = new List<Layer>(); else this.layers = layers; }
public MarkupGenerator(int width = 128, int min_height = 32) { this.width = width; this.min_height = min_height; this.frame = null; this.font_plain = FontManager.instance.font_named("Font07x5.dmd"); this.font_bold = FontManager.instance.font_named("Font09Bx7.dmd"); }
public Font(string filename = "") { this._anim = new Animation(); this.char_size = 0; this.bitmap = null; if (filename != "") { this.load(filename); } }
public ScriptedLayer(int width, int height, List<Pair<int, Layer>> script) { this.buffer = new Frame(width, height); this.script = script; this.script_index = 0; this.frame_start_time = -1; this.force_direction = Direction.None; this.on_complete = null; this.is_new_script_item = true; this.last_layer = null; }
public override Frame transition_frame(Frame from_frame, Frame to_frame) { Frame frame = new Frame(from_frame.width, from_frame.height); double prog0 = this.progress; double prog1 = this.progress; if (this.in_out == false) prog0 = 1.0 - prog0; else prog1 = 1.0 - prog1; int src_x, src_y, ovr_x, ovr_y; // TODO: Improve src_x/y so that it moves at the same speed as ovr_x/y with the midpoint if (direction == ObscuredWipeTransitionDirection.North) { src_x = 0; src_y = (int)(prog1 * frame.height); ovr_x = 0; ovr_y = (int)(frame.height - prog0 * (this.obs_frame.height + 2 * frame.height)); } else if (direction == ObscuredWipeTransitionDirection.South) { src_x = 0; src_y = (int)(prog0 * frame.height); ovr_x = 0; ovr_y = (int)(frame.height - prog1 * (this.obs_frame.height + 2 * frame.height)); } else if (direction == ObscuredWipeTransitionDirection.East) { src_x = (int)(prog0 * frame.width); src_y = 0; ovr_x = (int)(frame.width - prog1 * (this.obs_frame.width + 2 * frame.width)); ovr_y = 0; } else { src_x = (int)(prog1 * frame.width); src_y = 0; ovr_x = (int)(frame.width - prog0 * (this.obs_frame.width + 2 * frame.width)); ovr_y = 0; } if (this.direction == ObscuredWipeTransitionDirection.East || this.direction == ObscuredWipeTransitionDirection.South) { Frame tmpFrame = from_frame; from_frame = to_frame; to_frame = tmpFrame; } Frame.copy_rect(frame, 0, 0, from_frame, 0, 0, from_frame.width, from_frame.height, DMDBlendMode.DMDBlendModeCopy); Frame.copy_rect(frame, src_x, src_y, to_frame, src_x, src_y, from_frame.width - src_x, from_frame.height - src_y, DMDBlendMode.DMDBlendModeCopy); Frame.copy_rect(frame, ovr_x, ovr_y, obs_frame, 0, 0, this.obs_frame.width, this.obs_frame.height, this.composite_op); return frame; }
public AnimatedLayer(bool opaque = false, bool hold = true, bool repeat = false, int frame_time = 1, Frame[] frames = null) : base(opaque) { this.hold = hold; this.repeat = repeat; this.frames = frames; this.frame_time = frame_time; this.frame_time_counter = frame_time; this.frame_listeners = new List<Pair<int, Delegate>>(); this.reset(); }
public TextLayer(int x, int y, Font font, FontJustify justify, bool opaque = false) : base(opaque) { this.set_target_position(x, y); this.font = font; this.started_at = -1; this.seconds = -1; this.frame = null; this.frame_old = null; this.justify = justify; this.blink_frames = -1; this.blink_frames_counter = 0; }
public void dmd_draw(dmd.Frame frame) { if (!dmdConfigured) { DMDConfig dmdConfig = new DMDConfig(kDMDColumns, kDMDRows); DMDConfigPopulateDefaults(ref dmdConfig); PinProc.PRDMDUpdateConfig(ProcHandle, ref dmdConfig); dmdConfigured = true; } //dmd_draw(testFrame); byte[] dots = new byte[4 * kDMDColumns * kDMDRows / 8]; dmd.DMDGlobals.DMDFrameCopyPROCSubframes(ref frame.frame, dots, kDMDColumns, kDMDRows, 4, dmdMapping); dmd_draw(dots); }
public override Frame transition_frame(Frame from_frame, Frame to_frame) { Frame frame = new Frame(from_frame.width, from_frame.height); int dst_x = 0; int dst_y = 0; int dst_x1 = 0; int dst_y1 = 0; double prog = this.progress; double prog1 = this.progress; if (this.in_out == true) prog = 1.0 - prog; else prog1 = 1.0 - prog1; if (direction == PushTransitionDirection.North) { dst_x = 0; dst_y = (int)(prog * frame.height); dst_x1 = 0; dst_y1 = (int)(-prog1 * frame.height); } else if (direction == PushTransitionDirection.South) { dst_x = 0; dst_y = (int)(-prog * frame.height); dst_x1 = 0; dst_y1 = (int)(prog1 * frame.height); } else if (direction == PushTransitionDirection.East) { dst_x = (int)(-prog * frame.width); dst_y = 0; dst_x1 = (int)(prog1 * frame.width); dst_y1 = 0; } else if (direction == PushTransitionDirection.West) { dst_x = (int)(prog * frame.width); dst_y = 0; dst_x1 = (int)(-prog1 * frame.width); dst_y1 = 0; } Frame.copy_rect(frame, dst_x, dst_y, to_frame, 0, 0, from_frame.width, from_frame.height, DMDBlendMode.DMDBlendModeCopy); Frame.copy_rect(frame, dst_x1, dst_y1, from_frame, 0, 0, from_frame.width, from_frame.height, DMDBlendMode.DMDBlendModeCopy); return frame; }
/// <summary> /// Composites the next frame of this layer onto the given target buffer. /// Called by DisplayController.update() /// Generally subclasses should not override this method. Implement next_frame() instead /// </summary> /// <param name="target"></param> /// <returns></returns> public virtual Frame composite_next(Frame target) { Frame src = next_frame(); if (src != null) { if (transition != null) { src = this.transition.next_frame(target, src); } // src not all zeroes // Target = all zeros here Frame.copy_rect(target, (int)(this.target_x + this.target_x_offset), (int)(this.target_y + this.target_y_offset), src, 0, 0, src.width, src.height, this.composite_op); } return src; }
/// <summary> /// Uses this fonts characters to draw the given string at the given position /// </summary> public void draw(Frame frame, string text, int x, int y) { foreach (char ch in text) { int char_offset = (int)ch - (int)' '; if (char_offset < 0 || char_offset >= 96) continue; int char_x = this.char_size * (char_offset % 10); int char_y = this.char_size * (char_offset / 10); int width = this.char_widths[(int)char_offset]; Frame.copy_rect(frame, x, y, this.bitmap, char_x, char_y, width, this.char_size, this.composite_op); x += width + this.tracking; } }
public CrossFadeTransition(int width, int height) { this.width = width; this.height = height; this.progress_per_frame = 1.0 / 45.0; // Create the frames that will be used in the composite operations this.frames = new List<Frame>(); for (int i = 0; i < 16; i++) { Frame frame = new Frame(width, height); frame.fill_rect(0, 0, width, height, (byte)i); this.frames.Add(frame); } }
public PanningLayer(int width, int height, Frame frame, Pair<int, int> origin, Pair<int, int> translate, bool bounce = true) { this.buffer = new Frame(width, height); this.frame = frame; this.origin = origin; this.original_origin = origin; this.translate = translate; this.bounce = bounce; this.tick = 0; // make sure the translate value doesnt cause us to do any strange movements if (width == frame.width) this.translate = new Pair<int, int>(0, this.translate.Second); if (height == frame.height) this.translate = new Pair<int, int>(this.translate.First, 0); }
public override Frame transition_frame(Frame from_frame, Frame to_frame) { Frame frame = new Frame(from_frame.width, from_frame.height); double prog0 = this.progress; double prog1 = this.progress; int src_x = 0; int src_y = 0; if (this.in_out == false) prog0 = 1.0 - prog0; else prog1 = 1.0 - prog1; if (this.direction == WipeTransitionDirection.North) { src_x = 0; src_y = (int)(prog1 * frame.height); } else if (this.direction == WipeTransitionDirection.South) { src_x = 0; src_y = (int)(prog0 * frame.height); } else if (this.direction == WipeTransitionDirection.East) { src_x = (int)(prog0 * frame.width); src_y = 0; } else if (this.direction == WipeTransitionDirection.East) { src_x = (int)(prog1 * frame.width); src_y = 0; } if (this.direction == WipeTransitionDirection.East || this.direction == WipeTransitionDirection.South) { Frame tmpFrame = from_frame; from_frame = to_frame; to_frame = tmpFrame; } Frame.copy_rect(frame, 0, 0, from_frame, 0, 0, from_frame.width, from_frame.height, DMDBlendMode.DMDBlendModeCopy); Frame.copy_rect(frame, src_x, src_y, to_frame, src_x, src_y, from_frame.width, from_frame.height, DMDBlendMode.DMDBlendModeCopy); return frame; }
public override Frame transition_frame(Frame from_frame, Frame to_frame) { // Calculate the frame index int index = 0; if (this.in_out == true) index = (int)(this.progress * (frames.Count - 1)); else index = (int)((1.0 - this.progress) * (frames.Count - 1)); // Subtract the respective reference frame from each of the input frames from_frame = from_frame.copy(); Frame.copy_rect(from_frame, 0, 0, this.frames[index], 0, 0, this.width, this.height, DMDBlendMode.DMDBlendModeSubtract); to_frame = to_frame.copy(); Frame.copy_rect(to_frame, 0, 0, this.frames[frames.Count - (index + 1)], 0, 0, this.width, this.height, DMDBlendMode.DMDBlendModeSubtract); // Add the results together Frame.copy_rect(from_frame, 0, 0, to_frame, 0, 0, this.width, this.height, DMDBlendMode.DMDBlendModeAdd); return from_frame; }
public override Frame next_frame() { if (this.blink_frames > 0) { if (this.blink_frames_counter == 0) { this.blink_frames_counter = this.blink_frames; if (this.frame == null) this.frame = this.frame_old; else { this.frame_old = this.frame; this.frame = null; } } else this.blink_frames_counter--; } return this.frame; }
public void populate_from_dmd_file(string filename) { BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open)); long file_length = br.BaseStream.Length; br.BaseStream.Seek(4, SeekOrigin.Begin); // Skip over the 4 byte DMD header int frame_count = br.ReadInt32(); this.width = (int)br.ReadInt32(); this.height = (int)br.ReadInt32(); if (file_length != 16 + this.width * this.height * frame_count) throw new Exception("File size inconsistent with header information. Old or incompatible file format?"); for (int frame_index = 0; frame_index < frame_count; frame_index++) { byte[] frame = br.ReadBytes((int)(this.width * this.height)); Frame new_frame = new Frame(this.width, this.height); new_frame.set_data(frame); this.frames.Add(new_frame); } }
/// <summary> /// Applies the transition and increments the progress if the transition is running. /// Returns the resulting frame object. /// </summary> public virtual Frame next_frame(Frame from_frame, Frame to_frame) { this.progress = Math.Max(0.0, Math.Min(1.0, this.progress + this.progress_mult * this.progress_per_frame)); if (this.progress <= 0.0) { if (this.in_out == true) return from_frame; else return to_frame; } if (this.progress >= 1.0) { if (this.completed_handler != null) this.completed_handler.DynamicInvoke(); if (this.in_out == true) return to_frame; else return from_frame; } return this.transition_frame(from_frame, to_frame); }
public override Frame next_frame() { if (this.started_at == -1) this.started_at = Time.GetTime(); if ((this.seconds != -1) && (this.started_at + this.seconds < Time.GetTime())) this.frame = null; else if (this.blink_frames > 0) { if (this.blink_frames_counter == 0) { this.blink_frames_counter = this.blink_frames; if (this.frame == null) this.frame = this.frame_old; else { this.frame_old = this.frame; this.frame = null; } } else this.blink_frames_counter--; } return this.frame; }
/// <summary> /// Applies the transition at the current progress value. /// /// Subclasses should override this method to provide more interesting transition effects. /// base implementation simply returns the from_frame /// </summary> public virtual Frame transition_frame(Frame from_frame, Frame to_frame) { return from_frame; }
public Frame copy() { Frame frame = new Frame(width, height); frame.set_data(this.get_data()); return frame; }
/// <summary> /// Iterates over 'GameController.Modes' from lowest to highest and composites a DMD image for this /// point in time by checking for a layer attribute on each Mode class. /// /// If the mode has a layer attribute, that layer's composite_next method is called to apply that layer's /// next frame to the frame in progress. /// </summary> public void update() { List<Layer> layers = new List<Layer>(); foreach (Mode mode in this.game.Modes.Modes) { if (mode.layer != null) { layers.Add(mode.layer); if (mode.layer.opaque) break; } } Frame frame = new Frame(this.width, this.height); for (int i = layers.Count - 1; i >= 0; i--) { if (layers[i].enabled) layers[i].composite_next(frame); } if (this.message_layer != null) { this.message_layer.composite_next(frame); } if (frame != null && this.frame_handlers != null) { foreach (DMDFrameHandler handler in this.frame_handlers) { handler.DynamicInvoke(frame); } } }
/// <summary> /// Loads a font from a dmd file. Fonts are stored in .dmd files with frame 0 containing /// the bitmap data and frame 1 containing the character widths. 96 characters (32..127, ASCII /// printables) are stored in a 10x10 grid starting with space (' ') in the upper left at 0,0 /// The character widths are stored in the second frame within the raw bitmap data in bytes 0-95 /// </summary> /// <param name="filename"></param> public void load(string filename) { this.char_widths = new List<int>(); this._anim.load(filename, false); if (this._anim.width != this._anim.height) throw new Exception("Width != Height"); if (this._anim.frames.Count == 1) { // We allow 1 frame for handmade fonts. // This is so that they can be loaded as a basic bitmap, have their char widths modified // then be saved (TODO) this._anim.frames.Add(new Frame(this._anim.width, this._anim.height)); } else if (this._anim.frames.Count != 2) { throw new Exception("Expected 2 frames, got " + this._anim.frames.Count.ToString()); } this.char_size = (this._anim.width / 10); this.bitmap = this._anim.frames[0]; for (int i = 0; i < 96; i++) { this.char_widths.Add(this._anim.frames[1].get_dot(i % _anim.width, i / _anim.width)); } }
/// <summary> /// Displays the given message for the given number of seconds /// </summary> public void set_text(string text, int seconds = -1, int blink_frames = -1) { this.started_at = -1; this.seconds = seconds; this.blink_frames = blink_frames; this.blink_frames_counter = this.blink_frames; if (text == "") this.frame = null; else { Pair<int, int> font_size = this.font.size(text); this.frame = new Frame(font_size.First, font_size.Second); this.font.draw(this.frame, text, 0, 0); if (this.justify == FontJustify.Left) { this.target_x_offset = 0; this.target_y_offset = 0; } else if (this.justify == FontJustify.Right) { this.target_x_offset = (127 - font_size.First); this.target_y_offset = 0; } else if (this.justify == FontJustify.Center) { this.target_x_offset = (int)-(font_size.First / 2); this.target_y_offset = 0; } } }
public FrameLayer(bool opaque = false, Frame frame = null) : base(opaque) { this.frame = frame; }