Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 12 additions & 23 deletions crates/ps2-filetypes/src/parser/icon_sys.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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],
Expand All @@ -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());

Expand All @@ -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(
Expand Down Expand Up @@ -155,8 +157,7 @@ fn parse_icon_sys(bytes: Vec<u8>) -> Result<IconSys> {
c.read_exact(&mut magic)?;

let flags = c.read_u16::<LE>()?;
let linebreak_pos = convert_linepos(c.read_u8()?);
_ = c.read_u8(); // Reserved, always 0
let linebreak_pos = c.read_u16::<LE>()? / 2;
_ = c.read_u32::<LE>(); // Reserved, always 0
let background_transparency = c.read_u32::<LE>()?;

Expand Down Expand Up @@ -243,29 +244,17 @@ fn parse_direction(c: &mut Cursor<Vec<u8>>) -> Result<Vector> {
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)
}
20 changes: 5 additions & 15 deletions crates/suitcase/src/tabs/icon_sys_viewer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand All @@ -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(),
Expand Down
Loading