URI: 
       Moved icy play to it's own repository. - icy_draw - icy_draw is the successor to mystic draw. fork / mirror
  HTML git clone https://git.drkhsh.at/icy_draw.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 86365cba12863768f8fb8a79e146f39acad0605a
   DIR parent 25110cc014dbdd556e0b0479878c158c04473385
  HTML Author: Mike Krüger <mkrueger@posteo.de>
       Date:   Wed,  4 Oct 2023 11:05:18 +0200
       
       Moved icy play to it's own repository.
       
       Diffstat:
         D crates/icy_play/Cargo.toml          |      21 ---------------------
         D crates/icy_play/src/com.rs          |      69 ------------------------------
         D crates/icy_play/src/main.rs         |     210 -------------------------------
         M i18n/de/icy_draw.ftl                |       2 ++
         M i18n/en/icy_draw.ftl                |       2 ++
         M src/ui/editor/animation/mod.rs      |      14 +++++++++++++-
       
       6 files changed, 17 insertions(+), 301 deletions(-)
       ---
   DIR diff --git a/crates/icy_play/Cargo.toml b/crates/icy_play/Cargo.toml
       @@ -1,21 +0,0 @@
       -[package]
       -name = "icy_play"
       -version = "0.1.0"
       -edition = "2021"
       -authors = ["Mike Krüger <mkrueger@posteo.de>"]
       -description = "Plays icy_anim files for bbs systems."
       -license = "Apache-2.0"
       -repository = "https://github.com/mkrueger/icy_draw"
       -
       -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
       -
       -[dependencies]
       -icy_engine = { git ="https://github.com/mkrueger/icy_engine", features=["minimal"], default-features = false  }
       -icy_engine_egui = { git ="https://github.com/mkrueger/icy_engine_egui", features = ["animations"], default-features = false }
       -#icy_engine = { path = "../../../icy_engine", features=["minimal"], default-features = false }
       -#icy_engine_egui = { path = "../../../icy_engine_egui", features = ["animations"], default-features = false}
       -clap = { version="4.4.0", features = ["derive"] }
       -anyhow = "1.0.75"
       -
       -[profile.release]
       -strip = "symbols"
   DIR diff --git a/crates/icy_play/src/com.rs b/crates/icy_play/src/com.rs
       @@ -1,69 +0,0 @@
       -use std::{
       -    io::{self, Read, Write},
       -    net::{TcpStream, ToSocketAddrs},
       -    time::Duration,
       -};
       -
       -pub trait Com {
       -    fn write(&mut self, buf: &[u8]) -> anyhow::Result<usize>;
       -    fn read(&mut self, block: bool) -> anyhow::Result<Option<Vec<u8>>>;
       -}
       -
       -pub struct StdioCom {}
       -
       -impl StdioCom {
       -    pub fn start() -> anyhow::Result<Self> {
       -        Ok(Self {})
       -    }
       -}
       -impl Com for StdioCom {
       -    fn write(&mut self, buf: &[u8]) -> anyhow::Result<usize> {
       -        std::io::stdout().write_all(buf)?;
       -        Ok(buf.len())
       -    }
       -
       -    fn read(&mut self, _block: bool) -> anyhow::Result<Option<Vec<u8>>> {
       -        Ok(None)
       -    }
       -}
       -
       -pub struct SocketCom {
       -    tcp_stream: TcpStream,
       -}
       -
       -impl SocketCom {
       -    pub fn connect<A: ToSocketAddrs>(address: A) -> anyhow::Result<Self> {
       -        let tcp_stream = TcpStream::connect(address)?;
       -        tcp_stream.set_read_timeout(Some(Duration::from_millis(500)))?;
       -        Ok(Self { tcp_stream })
       -    }
       -}
       -
       -impl Com for SocketCom {
       -    fn write(&mut self, buf: &[u8]) -> anyhow::Result<usize> {
       -        self.tcp_stream.write_all(buf)?;
       -        Ok(buf.len())
       -    }
       -
       -    fn read(&mut self, block: bool) -> anyhow::Result<Option<Vec<u8>>> {
       -        let mut buf = [0; 1024 * 256];
       -        self.tcp_stream.set_nonblocking(!block)?;
       -        if self.tcp_stream.peek(&mut buf)? == 0 {
       -            return Ok(None);
       -        }
       -
       -        match self.tcp_stream.read(&mut buf) {
       -            Ok(size) => {
       -                self.tcp_stream.set_nonblocking(true)?;
       -                Ok(Some(buf[0..size].to_vec()))
       -            }
       -            Err(ref e) => {
       -                self.tcp_stream.set_nonblocking(true)?;
       -                if e.kind() == io::ErrorKind::WouldBlock {
       -                    return Ok(None);
       -                }
       -                Err(anyhow::anyhow!(format!("Connection aborted: {e}")))
       -            }
       -        }
       -    }
       -}
   DIR diff --git a/crates/icy_play/src/main.rs b/crates/icy_play/src/main.rs
       @@ -1,210 +0,0 @@
       -use clap::{Parser, Subcommand};
       -use icy_engine::{update_crc32, Buffer, SaveOptions, TextPane};
       -use icy_engine_egui::animations::Animator;
       -use std::{fs, path::PathBuf, thread, time::Duration};
       -
       -use crate::com::Com;
       -
       -mod com;
       -
       -#[derive(Clone, Debug, PartialEq, Eq)]
       -pub enum Terminal {
       -    IcyTerm,
       -    SyncTerm,
       -    Unknown,
       -    Name(String),
       -}
       -
       -impl Terminal {
       -    pub fn use_dcs(&self) -> bool {
       -        matches!(self, Terminal::IcyTerm)
       -    }
       -
       -    fn can_repeat_rle(&self) -> bool {
       -        matches!(self, Terminal::IcyTerm | Terminal::SyncTerm)
       -    }
       -}
       -
       -#[derive(Parser)]
       -pub struct Cli {
       -    #[arg(help = "If true modern terminal output (UTF8) is used.", long, default_value_t = false)]
       -    utf8: bool,
       -
       -    #[arg(help = "File to play/show.", required = true)]
       -    path: Option<PathBuf>,
       -
       -    #[arg(help = "Socket port address for i/o", long)]
       -    port: Option<String>,
       -
       -    #[command(subcommand)]
       -    command: Option<Commands>,
       -}
       -
       -#[derive(Subcommand)]
       -enum Commands {
       -    #[command(about = "Plays the animation (default)")]
       -    Play,
       -
       -    #[command(about = "Show a specific frame of the animation")]
       -    ShowFrame { frame: usize },
       -}
       -
       -pub fn get_line_checksums(buf: &Buffer) -> Vec<u32> {
       -    let mut result = Vec::new();
       -    for y in 0..buf.get_height() {
       -        let mut crc = 0;
       -        for x in 0..buf.get_width() {
       -            let ch = buf.get_char((x, y));
       -            crc = update_crc32(crc, ch.ch as u8);
       -            let fg = buf.palette.get_color(ch.attribute.get_foreground()).get_rgb();
       -            crc = update_crc32(crc, fg.0);
       -            crc = update_crc32(crc, fg.1);
       -            crc = update_crc32(crc, fg.2);
       -            let bg = buf.palette.get_color(ch.attribute.get_background()).get_rgb();
       -            crc = update_crc32(crc, bg.0);
       -            crc = update_crc32(crc, bg.1);
       -            crc = update_crc32(crc, bg.2);
       -            crc = update_crc32(crc, ch.attribute.attr as u8);
       -            crc = update_crc32(crc, (ch.attribute.attr >> 8) as u8);
       -        }
       -        result.push(crc);
       -    }
       -    result
       -}
       -
       -fn main() {
       -    let args = Cli::parse();
       -
       -    let mut io: Box<dyn Com> = if let Some(port) = args.port {
       -        println!("connect to : {}", "127.0.0.1:".to_string() + port.as_str());
       -        Box::new(com::SocketCom::connect("127.0.0.1:".to_string() + port.as_str()).unwrap())
       -    } else {
       -        Box::new(com::StdioCom::start().unwrap())
       -    };
       -
       -    if let Some(path) = args.path {
       -        let parent = Some(path.parent().unwrap().to_path_buf());
       -
       -        let Some(ext) = path.extension() else {
       -            println!("Error: File extension not found.");
       -            return;
       -        };
       -        let ext = ext.to_string_lossy().to_ascii_lowercase();
       -        let mut term = Terminal::Unknown;
       -
       -        match ext.as_str() {
       -            "icyanim" => match fs::read_to_string(path) {
       -                Ok(txt) => {
       -                    let animator = Animator::run(&parent, txt);
       -                    animator.lock().unwrap().set_is_playing(true);
       -
       -                    let mut opt: SaveOptions = SaveOptions::default();
       -                    if args.utf8 {
       -                        opt.modern_terminal_output = true;
       -                    }
       -                    match args.command.unwrap_or(Commands::Play) {
       -                        Commands::Play => {
       -                            io.write(b"\x1B[0c").unwrap();
       -                            match io.read(true) {
       -                                Ok(Some(data)) => {
       -                                    let txt: String = String::from_utf8_lossy(&data).to_string();
       -                                    term = if txt.contains("73;99;121;84;101;114;109") {
       -                                        Terminal::IcyTerm
       -                                    } else if txt.contains("67;84;101;114") {
       -                                        Terminal::SyncTerm
       -                                    } else {
       -                                        Terminal::Name(txt)
       -                                    }
       -                                } // 67;84;101;114;109;1;316
       -                                Ok(_) | Err(_) => {
       -                                    // ignore (timeout)
       -                                }
       -                            }
       -                            // flush.
       -                            while let Ok(Some(_)) = io.read(false) {}
       -                            let mut checksums = Vec::new();
       -
       -                            // turn caret off
       -                            let _ = io.write(b"\x1b[?25l");
       -
       -                            while animator.lock().unwrap().is_playing() {
       -                                if let Ok(Some(v)) = io.read(false) {
       -                                    if v.contains(&b'\x1b') || v.contains(&b'\n') || v.contains(&b' ') {
       -                                        break;
       -                                    }
       -                                }
       -                                if let Some((buffer, _, delay)) = animator.lock().unwrap().get_cur_frame_buffer() {
       -                                    let new_checksums = get_line_checksums(buffer);
       -                                    let mut skip_lines = Vec::new();
       -                                    if checksums.len() == new_checksums.len() {
       -                                        for i in 0..checksums.len() {
       -                                            if checksums[i] == new_checksums[i] {
       -                                                skip_lines.push(i);
       -                                            }
       -                                        }
       -                                    }
       -                                    //println!("skip lines: {:?}", skip_lines );
       -                                    show_buffer(&mut io, buffer, false, args.utf8, &term, skip_lines).unwrap();
       -                                    checksums = new_checksums;
       -                                    std::thread::sleep(Duration::from_millis(*delay as u64));
       -                                } else {
       -                                    thread::sleep(Duration::from_millis(10));
       -                                }
       -                                while !animator.lock().unwrap().next_frame() {
       -                                    thread::sleep(Duration::from_millis(10));
       -                                }
       -                            }
       -                            let _ = io.write(b"\x1b[?25h\x1b[0;0 D");
       -                        }
       -                        Commands::ShowFrame { frame } => {
       -                            show_buffer(&mut io, &animator.lock().unwrap().frames[frame].0, true, args.utf8, &term, Vec::new()).unwrap();
       -                        }
       -                    }
       -                }
       -                Err(e) => {
       -                    println!("Error opening file: {e}");
       -                }
       -            },
       -            _ => {
       -                let buffer = Buffer::load_buffer(&path, true);
       -                if let Ok(buffer) = &buffer {
       -                    show_buffer(&mut io, buffer, true, args.utf8, &Terminal::Unknown, Vec::new()).unwrap();
       -                }
       -            }
       -        }
       -    }
       -}
       -
       -fn show_buffer(io: &mut Box<dyn Com>, buffer: &Buffer, single_frame: bool, use_utf8: bool, terminal: &Terminal, skip_lines: Vec<usize>) -> anyhow::Result<()> {
       -    let mut opt: SaveOptions = SaveOptions::default();
       -    if use_utf8 {
       -        opt.modern_terminal_output = true;
       -    }
       -    opt.control_char_handling = icy_engine::ControlCharHandling::FilterOut;
       -    opt.longer_terminal_output = true;
       -    opt.compress = true;
       -    opt.use_cursor_forward = false;
       -    opt.preserve_line_length = true;
       -    opt.use_repeat_sequences = terminal.can_repeat_rle();
       -
       -    opt.skip_lines = Some(skip_lines);
       -
       -    if matches!(terminal, Terminal::IcyTerm) {
       -        opt.control_char_handling = icy_engine::ControlCharHandling::IcyTerm;
       -    }
       -    let bytes = buffer.to_bytes("ans", &opt)?;
       -
       -    if !single_frame && terminal.use_dcs() {
       -        io.write(b"\x1BP0;1;0!z")?;
       -    }
       -    io.write(&bytes)?;
       -    /*for i in 0..buffer.get_height() {
       -        io.write(format!("\x1b[{};1H{}:", i + 1, i).as_bytes())?;
       -    }
       -    */
       -    //io.write(format!("\x1b[23;1HTerminal:{:?}", terminal).as_bytes())?;
       -    if !single_frame && terminal.use_dcs() {
       -        io.write(b"\x1b\\\x1b[0*z")?;
       -    }
       -    Ok(())
       -}
   DIR diff --git a/i18n/de/icy_draw.ftl b/i18n/de/icy_draw.ftl
       @@ -352,6 +352,8 @@ animation_editor_path_label=Datei:
        animation_editor_export_button=Export
        animation_editor_ansi_label=Ansimation
        animation_encoding_frame=Berechne Bild { $cur } von { $total }
       +animation_of_frame_count=von { $total }
       +animation_icy_play_note=Für Animationen in der Konsole/BBS (oder zum Ansi honvertieren) braucht man:
        
        new-file-template-cp437-title=CP437 ANSI
        new-file-template-cp437-description=
   DIR diff --git a/i18n/en/icy_draw.ftl b/i18n/en/icy_draw.ftl
       @@ -348,6 +348,8 @@ animation_editor_path_label=Path:
        animation_editor_export_button=Export
        animation_editor_ansi_label=Ansimation
        animation_encoding_frame=Encoding frame { $cur } of { $total }
       +animation_of_frame_count=of { $total }
       +animation_icy_play_note=Note: For playing the animation in the console/bbs or ansi conversion use:
        
        new-file-template-cp437-title=CP437 ANSI
        new-file-template-cp437-description=
   DIR diff --git a/src/ui/editor/animation/mod.rs b/src/ui/editor/animation/mod.rs
       @@ -208,7 +208,14 @@ impl Document for AnimationEditor {
                                    }
        
                                    let mut cf = animator.get_cur_frame() + 1;
       -                            if frame_count > 0 && ui.add(Slider::new(&mut cf, 1..=frame_count).text(format!("of {}", frame_count))).changed() {
       +
       +                            
       +
       +                            if frame_count > 0 && ui.add(Slider::new(&mut cf, 1..=frame_count).text(fl!(
       +                                crate::LANGUAGE_LOADER,
       +                                "animation_of_frame_count",
       +                                total = frame_count
       +                            ))).changed() {
                                        animator.set_cur_frame(cf - 1);
                                        animator.display_frame(self.buffer_view.clone());
                                    }
       @@ -304,6 +311,11 @@ impl Document for AnimationEditor {
        
                                if !self.encoding_error.is_empty() {
                                    ui.colored_label(ui.style().visuals.error_fg_color, RichText::new(&self.encoding_error));
       +                        } else {
       +                            ui.horizontal(|ui| {
       +                                ui.label(fl!(crate::LANGUAGE_LOADER, "animation_icy_play_note"));
       +                                ui.hyperlink_to("Icy Play", "https://github.com/mkrueger/icy_play");
       +                            });
                                }
                            }
                        });