diff --git a/crates/ps2-filetypes/src/parser/icon_sys.rs b/crates/ps2-filetypes/src/parser/icon_sys.rs index ece8117..bbf8e70 100644 --- a/crates/ps2-filetypes/src/parser/icon_sys.rs +++ b/crates/ps2-filetypes/src/parser/icon_sys.rs @@ -1,8 +1,8 @@ -use std::io::{Cursor, Read, Result}; use crate::color::Color; use crate::sjis::{decode_sjis, encode_sjis}; use crate::util::parse_cstring; use byteorder::{ReadBytesExt, LE}; +use std::io::{Cursor, Read, Result}; #[derive(Clone, Copy, Debug)] pub struct ColorF { @@ -62,7 +62,7 @@ impl Vector { #[derive(Clone, Debug)] pub struct IconSys { pub flags: u16, - pub linebreak_pos: u8, + pub linebreak_pos: u16, pub background_transparency: u32, pub background_colors: [Color; 4], pub light_directions: [Vector; 3], @@ -85,8 +85,7 @@ impl IconSys { bytes.extend_from_slice(b"PS2D"); bytes.extend(self.flags.to_le_bytes()); - bytes.extend(convert_linepos(self.linebreak_pos).to_le_bytes()); - bytes.extend(0u8.to_le_bytes()); // Reserved + bytes.extend((self.linebreak_pos * 2).to_le_bytes()); bytes.extend(0u32.to_le_bytes()); // Reserved bytes.extend(self.background_transparency.to_le_bytes()); @@ -104,7 +103,10 @@ impl IconSys { bytes.extend_from_slice(&self.ambient_color.to_bytes()); - let title_bytes = encode_sjis(&join_title_lines(self.title_line1.clone(), self.title_line2.clone())); + let title_bytes = encode_sjis(&join_title_lines( + self.title_line1.clone(), + self.title_line2.clone(), + )); let title_len = title_bytes.len(); if title_len > 68 { return Err(std::io::Error::new( @@ -155,8 +157,7 @@ fn parse_icon_sys(bytes: Vec) -> Result { c.read_exact(&mut magic)?; let flags = c.read_u16::()?; - let linebreak_pos = convert_linepos(c.read_u8()?); - _ = c.read_u8(); // Reserved, always 0 + let linebreak_pos = c.read_u16::()? / 2; _ = c.read_u32::(); // Reserved, always 0 let background_transparency = c.read_u32::()?; @@ -243,29 +244,17 @@ fn parse_direction(c: &mut Cursor>) -> Result { Ok(Vector { x, y, z, w }) } -/** - * The linebreak is stored at byte 0x06 in the 4 lower bits, but with the least significant bit first. - * For example a linebreak on the 5rd (0b 0000 0101) character will be represented as 0b 0000 1010. - * The 4 higher bits are seemingly ignored in the context of OSDMENU. - */ -fn convert_linepos(source: u8) -> u8 { - // zero out the 4 most significant bits - let low_half = source & 0b00001111; - low_half.reverse_bits() >> 4 -} - -fn split_title(linebreak_pos: u8, title: String) -> (String, String) { - if linebreak_pos >= title.len() as u8 { +fn split_title(linebreak_pos: u16, title: String) -> (String, String) { + if linebreak_pos >= title.len() as u16 { return (title, "".to_string()); } let (title_line1, title_line2) = title.split_at(linebreak_pos as usize); - // trim the leading space on line2 necessary for proper linebreak - (title_line1.into(), title_line2.trim_start().into()) + (title_line1.into(), title_line2.into()) } fn join_title_lines(title_line1: String, title_line2: String) -> String { if title_line2.len() == 0 { return title_line1; } - format!("{} {}", title_line1, title_line2) + format!("{}{}", title_line1, title_line2) } diff --git a/crates/suitcase/src/tabs/icon_sys_viewer.rs b/crates/suitcase/src/tabs/icon_sys_viewer.rs index 129d1ae..14ddcff 100644 --- a/crates/suitcase/src/tabs/icon_sys_viewer.rs +++ b/crates/suitcase/src/tabs/icon_sys_viewer.rs @@ -168,17 +168,14 @@ impl IconSysViewer { Grid::new(Id::from("IconSysEditor")).num_columns(2).min_col_width(MIN_COL_WIDTH).show(ui, |ui| { ui.label("Title first line"); ui.add(TextEdit::singleline(&mut self.title_line1)); - if (self.title_line1.len() > 15) { - ui.label(format!("OSDMENU can only handle linebreak before 15 characters. {}/15", self.title_line1.len())); + if self.title_line1.len() >= 16 { + ui.label(format!("Must be 16 characters or less. {}/16", self.title_line1.len())); } ui.end_row(); ui.label("Title second line"); ui.add(TextEdit::singleline(&mut self.title_line2)); - if self.title_len() > 34 { - ui.end_row(); - ui.end_row(); - ui.label(""); - ui.label(RichText::new(format!("Title too long {}/34", self.title_len())).color(Color32::RED)); + if self.title_line2.len() >= 16 { + ui.label(format!("Must be 16 characters or less. {}/16", self.title_line2.len())); } }); ui.add_space(SEPARATOR_MARGIN); @@ -290,13 +287,6 @@ impl IconSysViewer { }); }); } - - fn title_len(&self) -> usize { - if self.title_line2.len() == 0 { - return self.title_line1.len(); - } - self.title_line1.len() + self.title_line2.len() + 1 // 1 extra char for the linebreak space - } } impl Tab for IconSysViewer { @@ -320,7 +310,7 @@ impl Tab for IconSysViewer { let new_sys = IconSys { title_line1: self.title_line1.clone(), title_line2: self.title_line2.clone(), - linebreak_pos: self.title_line1.len() as u8, + linebreak_pos: self.title_line1.len() as u16, icon_file: self.icon_file.clone(), icon_copy_file: self.icon_copy_file.clone(), icon_delete_file: self.icon_delete_file.clone(),