Add support to support PUA in BGI string

This commit is contained in:
2025-07-08 10:20:21 +08:00
parent e317c487fb
commit 601abba284
17 changed files with 104 additions and 60 deletions

View File

@@ -116,7 +116,7 @@ impl Script for BGIBpScript {
let text_address = i.offset_pos + i.text_offset as usize - 1;
// println!("offset: {}, text address: {}, text_offset: {}", i.offset_pos, text_address, i.text_offset);
let str = self.data.cpeek_cstring_at(text_address)?;
let str = decode_to_string(self.encoding, str.as_bytes())?;
let str = decode_to_string(self.encoding, str.as_bytes(), true)?;
messages.push(Message {
name: None,
message: str,

View File

@@ -66,14 +66,14 @@ impl BGIBsiScript {
let section_count = reader.read_u32()?;
for _ in 0..section_count {
let section_name = reader.read_cstring()?;
let section_name = decode_to_string(encoding, section_name.as_bytes())?;
let section_name = decode_to_string(encoding, section_name.as_bytes(), true)?;
let mut section_data = BTreeMap::new();
let entry_count = reader.read_u32()?;
for _ in 0..entry_count {
let key = reader.read_cstring()?;
let key = decode_to_string(encoding, key.as_bytes())?;
let key = decode_to_string(encoding, key.as_bytes(), true)?;
let value = reader.read_cstring()?;
let value = decode_to_string(encoding, value.as_bytes())?;
let value = decode_to_string(encoding, value.as_bytes(), true)?;
section_data.insert(key, value);
}
data.insert(section_name, section_data);
@@ -134,7 +134,7 @@ fn create_file<'a>(
output_encoding: Encoding,
) -> Result<()> {
let input = crate::utils::files::read_file(custom_filename)?;
let s = decode_to_string(output_encoding, &input)?;
let s = decode_to_string(output_encoding, &input, true)?;
let data: BTreeMap<String, BTreeMap<String, String>> = serde_json::from_str(&s)
.map_err(|e| anyhow::anyhow!("Failed to read BSI Map data from JSON: {}", e))?;
writer.write_u32(data.len() as u32)?;

View File

@@ -454,7 +454,8 @@ impl<'a> V1Parser<'a> {
pub fn read_string_at_address(&mut self, address: usize) -> Result<String> {
let start = self.offset + address;
let buf = self.buf.peek_cstring_at(start)?;
Ok(decode_to_string(self.encoding, buf.as_bytes())?)
// Sometimes string has private use area characters, so we disable strict checking
Ok(decode_to_string(self.encoding, buf.as_bytes(), false)?)
}
pub fn handle_user_function_call(&mut self) -> Result<()> {

View File

@@ -17,7 +17,11 @@ impl BGIScriptBuilder {
impl ScriptBuilder for BGIScriptBuilder {
fn default_encoding(&self) -> Encoding {
Encoding::Cp932
#[cfg(not(windows))]
return Encoding::Cp932;
#[cfg(windows)]
// Use Windows API first, because encoding-rs does not support PRIVATE USE AREA characters
return Encoding::CodePage(932);
}
fn build_script(
@@ -101,7 +105,8 @@ impl BGIScript {
fn read_string(&self, offset: usize) -> Result<String> {
let start = self.offset + offset;
let string_data = self.data.cpeek_cstring_at(start)?;
let string = decode_to_string(self.encoding, string_data.as_bytes())?;
// sometimes string has private use area characters, so we disable strict checking
let string = decode_to_string(self.encoding, string_data.as_bytes(), false)?;
Ok(string)
}
}