mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-07-08 01:31:53 +08:00
Support more tags
This commit is contained in:
@@ -229,6 +229,130 @@ impl AbmpRes for AbImgData15 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
/// tag: abimgdat14
|
||||||
|
struct AbImgData14 {
|
||||||
|
name: String,
|
||||||
|
internal_name: String,
|
||||||
|
typ: u8,
|
||||||
|
param: Vec<u8>,
|
||||||
|
data: ResourceRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbmpRes for AbImgData14 {
|
||||||
|
fn read_from<T: Read + Seek>(
|
||||||
|
data: &mut T,
|
||||||
|
encoding: Encoding,
|
||||||
|
img: &mut AbmpImage,
|
||||||
|
) -> Result<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let tag = data.read_fstring(0x10, encoding, true)?;
|
||||||
|
if tag != "abimgdat14" {
|
||||||
|
anyhow::bail!("Invalid AbImgData14 tag: {}", tag);
|
||||||
|
}
|
||||||
|
let name_length = data.read_u16()? as usize;
|
||||||
|
let name = data.read_fstring(name_length, encoding, false)?;
|
||||||
|
let internal_name_length = data.read_u16()? as usize;
|
||||||
|
let internal_name = data.read_fstring(internal_name_length, encoding, false)?;
|
||||||
|
let typ = data.read_u8()?;
|
||||||
|
let param = data.read_exact_vec(0x4C)?;
|
||||||
|
let size = data.read_u32()?;
|
||||||
|
let resource = data.read_exact_vec(size as usize)?;
|
||||||
|
img.resources.push(resource);
|
||||||
|
let index = img.resources.len() - 1;
|
||||||
|
let mut nname = if !name.is_empty() {
|
||||||
|
name.clone()
|
||||||
|
} else if !internal_name.is_empty() {
|
||||||
|
internal_name.clone()
|
||||||
|
} else {
|
||||||
|
format!("abimage14_{index}")
|
||||||
|
};
|
||||||
|
match typ {
|
||||||
|
0 => nname.push_str(".bmp"),
|
||||||
|
1 => nname.push_str(".jpg"),
|
||||||
|
3 => nname.push_str(".png"),
|
||||||
|
4 => nname.push_str(".m"),
|
||||||
|
5 => nname.push_str(".argb"),
|
||||||
|
6 => nname.push_str(".b"),
|
||||||
|
7 => nname.push_str(".ogv"),
|
||||||
|
8 => nname.push_str(".mdl"),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
img.resource_filenames.push(nname);
|
||||||
|
Ok(AbImgData14 {
|
||||||
|
name,
|
||||||
|
internal_name,
|
||||||
|
typ,
|
||||||
|
param,
|
||||||
|
data: ResourceRef { index },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
/// tag: abimgdat13
|
||||||
|
struct AbImgData13 {
|
||||||
|
name: String,
|
||||||
|
internal_name: String,
|
||||||
|
typ: u8,
|
||||||
|
param: Vec<u8>,
|
||||||
|
data: ResourceRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbmpRes for AbImgData13 {
|
||||||
|
fn read_from<T: Read + Seek>(
|
||||||
|
data: &mut T,
|
||||||
|
encoding: Encoding,
|
||||||
|
img: &mut AbmpImage,
|
||||||
|
) -> Result<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let tag = data.read_fstring(0x10, encoding, true)?;
|
||||||
|
if tag != "abimgdat13" {
|
||||||
|
anyhow::bail!("Invalid AbImgData13 tag: {}", tag);
|
||||||
|
}
|
||||||
|
let name_length = data.read_u16()? as usize;
|
||||||
|
let name = data.read_fstring(name_length, encoding, false)?;
|
||||||
|
let internal_name_length = data.read_u16()? as usize;
|
||||||
|
let internal_name = data.read_fstring(internal_name_length, encoding, false)?;
|
||||||
|
let typ = data.read_u8()?;
|
||||||
|
let param = data.read_exact_vec(0xC)?;
|
||||||
|
let size = data.read_u32()?;
|
||||||
|
let resource = data.read_exact_vec(size as usize)?;
|
||||||
|
img.resources.push(resource);
|
||||||
|
let index = img.resources.len() - 1;
|
||||||
|
let mut nname = if !name.is_empty() {
|
||||||
|
name.clone()
|
||||||
|
} else if !internal_name.is_empty() {
|
||||||
|
internal_name.clone()
|
||||||
|
} else {
|
||||||
|
format!("abimage13_{index}")
|
||||||
|
};
|
||||||
|
match typ {
|
||||||
|
0 => nname.push_str(".bmp"),
|
||||||
|
1 => nname.push_str(".jpg"),
|
||||||
|
3 => nname.push_str(".png"),
|
||||||
|
4 => nname.push_str(".m"),
|
||||||
|
5 => nname.push_str(".argb"),
|
||||||
|
6 => nname.push_str(".b"),
|
||||||
|
7 => nname.push_str(".ogv"),
|
||||||
|
8 => nname.push_str(".mdl"),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
img.resource_filenames.push(nname);
|
||||||
|
Ok(AbImgData13 {
|
||||||
|
name,
|
||||||
|
internal_name,
|
||||||
|
typ,
|
||||||
|
param,
|
||||||
|
data: ResourceRef { index },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
/// tag: absnddat12
|
/// tag: absnddat12
|
||||||
struct AbSndData12 {
|
struct AbSndData12 {
|
||||||
@@ -277,14 +401,62 @@ impl AbmpRes for AbSndData12 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
/// tag: absnddat11
|
||||||
|
struct AbSndData11 {
|
||||||
|
name: String,
|
||||||
|
internal_name: String,
|
||||||
|
data: ResourceRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbmpRes for AbSndData11 {
|
||||||
|
fn read_from<T: Read + Seek>(
|
||||||
|
data: &mut T,
|
||||||
|
encoding: Encoding,
|
||||||
|
img: &mut AbmpImage,
|
||||||
|
) -> Result<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let tag = data.read_fstring(0x10, encoding, true)?;
|
||||||
|
if tag != "absnddat11" {
|
||||||
|
anyhow::bail!("Invalid AbSndData11 tag: {}", tag);
|
||||||
|
}
|
||||||
|
let name_length = data.read_u16()? as usize;
|
||||||
|
let name = data.read_fstring(name_length, encoding, false)?;
|
||||||
|
let internal_name_length = data.read_u16()? as usize;
|
||||||
|
let internal_name = data.read_fstring(internal_name_length, encoding, false)?;
|
||||||
|
let size = data.read_u32()?;
|
||||||
|
let resource = data.read_exact_vec(size as usize)?;
|
||||||
|
img.resources.push(resource);
|
||||||
|
let index = img.resources.len() - 1;
|
||||||
|
let nname = if !name.is_empty() {
|
||||||
|
name.clone()
|
||||||
|
} else if !internal_name.is_empty() {
|
||||||
|
internal_name.clone()
|
||||||
|
} else {
|
||||||
|
format!("absnddat11_{index}")
|
||||||
|
};
|
||||||
|
img.resource_filenames.push(nname);
|
||||||
|
Ok(AbSndData11 {
|
||||||
|
name,
|
||||||
|
internal_name,
|
||||||
|
data: ResourceRef { index },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(tag = "@type")]
|
#[serde(tag = "@type")]
|
||||||
enum AbmpResource {
|
enum AbmpResource {
|
||||||
Data(AbData),
|
Data(AbData),
|
||||||
Image10(AbImage10),
|
Image10(AbImage10),
|
||||||
ImgData15(AbImgData15),
|
ImgData15(AbImgData15),
|
||||||
|
ImgData14(AbImgData14),
|
||||||
|
ImgData13(AbImgData13),
|
||||||
Sound10(AbSound10),
|
Sound10(AbSound10),
|
||||||
SndData12(AbSndData12),
|
SndData12(AbSndData12),
|
||||||
|
SndData11(AbSndData11),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbmpRes for AbmpResource {
|
impl AbmpRes for AbmpResource {
|
||||||
@@ -304,9 +476,18 @@ impl AbmpRes for AbmpResource {
|
|||||||
"abimgdat15" => Ok(AbmpResource::ImgData15(AbImgData15::read_from(
|
"abimgdat15" => Ok(AbmpResource::ImgData15(AbImgData15::read_from(
|
||||||
data, encoding, img,
|
data, encoding, img,
|
||||||
)?)),
|
)?)),
|
||||||
|
"abimgdat14" => Ok(AbmpResource::ImgData14(AbImgData14::read_from(
|
||||||
|
data, encoding, img,
|
||||||
|
)?)),
|
||||||
|
"abimgdat13" => Ok(AbmpResource::ImgData13(AbImgData13::read_from(
|
||||||
|
data, encoding, img,
|
||||||
|
)?)),
|
||||||
"absound10" => Ok(AbmpResource::Sound10(AbSound10::read_from(
|
"absound10" => Ok(AbmpResource::Sound10(AbSound10::read_from(
|
||||||
data, encoding, img,
|
data, encoding, img,
|
||||||
)?)),
|
)?)),
|
||||||
|
"absnddat11" => Ok(AbmpResource::SndData11(AbSndData11::read_from(
|
||||||
|
data, encoding, img,
|
||||||
|
)?)),
|
||||||
"absnddat12" => Ok(AbmpResource::SndData12(AbSndData12::read_from(
|
"absnddat12" => Ok(AbmpResource::SndData12(AbSndData12::read_from(
|
||||||
data, encoding, img,
|
data, encoding, img,
|
||||||
)?)),
|
)?)),
|
||||||
@@ -323,6 +504,7 @@ struct AbmpImage {
|
|||||||
/// Valid version: 10, 11, 12
|
/// Valid version: 10, 11, 12
|
||||||
version: u8,
|
version: u8,
|
||||||
datas: Vec<AbmpResource>,
|
datas: Vec<AbmpResource>,
|
||||||
|
extra: Vec<u8>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
resources: Vec<Vec<u8>>,
|
resources: Vec<Vec<u8>>,
|
||||||
/// Just used for dump
|
/// Just used for dump
|
||||||
@@ -339,6 +521,8 @@ struct Resource {
|
|||||||
struct AbmpImage2 {
|
struct AbmpImage2 {
|
||||||
version: u8,
|
version: u8,
|
||||||
datas: Vec<AbmpResource>,
|
datas: Vec<AbmpResource>,
|
||||||
|
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||||
|
extra: Vec<u8>,
|
||||||
resources: Vec<Resource>,
|
resources: Vec<Resource>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,11 +538,17 @@ impl AbmpImage {
|
|||||||
datas: Vec::new(),
|
datas: Vec::new(),
|
||||||
resources: Vec::new(),
|
resources: Vec::new(),
|
||||||
resource_filenames: Vec::new(),
|
resource_filenames: Vec::new(),
|
||||||
|
extra: Vec::new(),
|
||||||
};
|
};
|
||||||
let len = reader.stream_length()?;
|
let len = reader.stream_length()?;
|
||||||
while reader.stream_position()? < len {
|
let mut pos = reader.stream_position()?;
|
||||||
|
while pos < len - 16 {
|
||||||
let data = AbmpResource::read_from(reader, encoding, &mut img)?;
|
let data = AbmpResource::read_from(reader, encoding, &mut img)?;
|
||||||
img.datas.push(data);
|
img.datas.push(data);
|
||||||
|
pos = reader.stream_position()?;
|
||||||
|
}
|
||||||
|
if pos < len {
|
||||||
|
img.extra = reader.read_exact_vec((len - pos) as usize)?;
|
||||||
}
|
}
|
||||||
Ok(img)
|
Ok(img)
|
||||||
}
|
}
|
||||||
@@ -368,6 +558,7 @@ impl AbmpImage {
|
|||||||
version: self.version,
|
version: self.version,
|
||||||
datas: self.datas.clone(),
|
datas: self.datas.clone(),
|
||||||
resources: Vec::new(),
|
resources: Vec::new(),
|
||||||
|
extra: self.extra.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user