mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-18 00:45:08 +08:00
Add opcode_name label to custom export ystb
This commit is contained in:
@@ -1027,17 +1027,13 @@ impl YSTB {
|
|||||||
let mut reader = MemReader::new(yscm);
|
let mut reader = MemReader::new(yscm);
|
||||||
reader.pos = 4;
|
reader.pos = 4;
|
||||||
let com = YSCMData::unpack(&mut reader, false, encoding, &None)?;
|
let com = YSCMData::unpack(&mut reader, false, encoding, &None)?;
|
||||||
let labels = if config.yuris_ystb_disasm {
|
let labels = match Self::try_load_yslb(filename, &archive, config, encoding) {
|
||||||
match Self::try_load_yslb(filename, &archive, config, encoding) {
|
Ok(labels) => labels,
|
||||||
Ok(labels) => labels,
|
Err(e) => {
|
||||||
Err(e) => {
|
eprintln!("WARNING: Failed to load ysl.bin file: {}", e);
|
||||||
eprintln!("WARNING: Failed to load ysl.bin file: {}", e);
|
crate::COUNTER.inc_warning();
|
||||||
crate::COUNTER.inc_warning();
|
BTreeMap::new()
|
||||||
BTreeMap::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
BTreeMap::new()
|
|
||||||
};
|
};
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
data,
|
data,
|
||||||
@@ -1178,6 +1174,93 @@ impl YSTB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct YSTBDataSer<'a> {
|
||||||
|
data: &'a YSTBData,
|
||||||
|
com: &'a YSCMData,
|
||||||
|
labels: &'a BTreeMap<u32, Label>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> serde::Serialize for YSTBDataSer<'a> {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
use serde::ser::SerializeStruct;
|
||||||
|
let h = &self.data.header;
|
||||||
|
let mut s = serializer.serialize_struct("YSTBData", 4)?;
|
||||||
|
s.serialize_field("version", &h.version)?;
|
||||||
|
s.serialize_field("reserve0", &h.reserve0)?;
|
||||||
|
s.serialize_field(
|
||||||
|
"insts",
|
||||||
|
&YSTBInstSliceSer {
|
||||||
|
insts: &self.data.insts,
|
||||||
|
com: self.com,
|
||||||
|
labels: self.labels,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
s.serialize_field("line_numbers", &self.data.line_numbers)?;
|
||||||
|
s.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct YSTBInstSliceSer<'a> {
|
||||||
|
insts: &'a [YSTBInst],
|
||||||
|
com: &'a YSCMData,
|
||||||
|
labels: &'a BTreeMap<u32, Label>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> serde::Serialize for YSTBInstSliceSer<'a> {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
use serde::ser::SerializeSeq;
|
||||||
|
let mut seq = serializer.serialize_seq(Some(self.insts.len()))?;
|
||||||
|
for (i, inst) in self.insts.iter().enumerate() {
|
||||||
|
let offset = i as u32;
|
||||||
|
let opcode_name = self
|
||||||
|
.com
|
||||||
|
.opcodes
|
||||||
|
.get(inst.opcode as usize)
|
||||||
|
.map(|m| m.name.as_str());
|
||||||
|
let label = self.labels.get(&offset);
|
||||||
|
seq.serialize_element(&YSTBInstSer {
|
||||||
|
inst,
|
||||||
|
opcode_name,
|
||||||
|
label,
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
seq.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct YSTBInstSer<'a> {
|
||||||
|
inst: &'a YSTBInst,
|
||||||
|
opcode_name: Option<&'a str>,
|
||||||
|
label: Option<&'a Label>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> serde::Serialize for YSTBInstSer<'a> {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
use serde::ser::SerializeStruct;
|
||||||
|
let nfields = 3 + self.opcode_name.is_some() as usize + self.label.is_some() as usize;
|
||||||
|
let mut s = serializer.serialize_struct("YSTBInst", nfields)?;
|
||||||
|
s.serialize_field("opcode", &self.inst.opcode)?;
|
||||||
|
if let Some(name) = self.opcode_name {
|
||||||
|
s.serialize_field("opcode_name", name)?;
|
||||||
|
}
|
||||||
|
s.serialize_field("unk", &self.inst.unk)?;
|
||||||
|
s.serialize_field("args", &self.inst.args)?;
|
||||||
|
if let Some(label) = self.label {
|
||||||
|
s.serialize_field("label", &label.name)?;
|
||||||
|
}
|
||||||
|
s.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Script for YSTB {
|
impl Script for YSTB {
|
||||||
fn default_output_script_type(&self) -> OutputScriptType {
|
fn default_output_script_type(&self) -> OutputScriptType {
|
||||||
OutputScriptType::Custom
|
OutputScriptType::Custom
|
||||||
@@ -1203,10 +1286,15 @@ impl Script for YSTB {
|
|||||||
|
|
||||||
fn custom_export(&self, filename: &std::path::Path, encoding: Encoding) -> Result<()> {
|
fn custom_export(&self, filename: &std::path::Path, encoding: Encoding) -> Result<()> {
|
||||||
if !self.disasm {
|
if !self.disasm {
|
||||||
|
let wrapper = YSTBDataSer {
|
||||||
|
data: &self.data,
|
||||||
|
com: &self.com,
|
||||||
|
labels: &self.labels,
|
||||||
|
};
|
||||||
let s = if self.custom_yaml {
|
let s = if self.custom_yaml {
|
||||||
serde_yaml_ng::to_string(&self.data)?
|
serde_yaml_ng::to_string(&wrapper)?
|
||||||
} else {
|
} else {
|
||||||
serde_json::to_string_pretty(&self.data)?
|
serde_json::to_string_pretty(&wrapper)?
|
||||||
};
|
};
|
||||||
let mut f = std::fs::File::create(filename)?;
|
let mut f = std::fs::File::create(filename)?;
|
||||||
let encoded = encode_string(encoding, &s, true)?;
|
let encoded = encode_string(encoding, &s, true)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user