diff --git a/bff-cli/src/cps.rs b/bff-cli/src/cps.rs index 4a1230a..5f9a4bc 100644 --- a/bff-cli/src/cps.rs +++ b/bff-cli/src/cps.rs @@ -16,12 +16,12 @@ fn collect_cps_names(cps: &Cps, name_context: &NameContext) -> HashSet { for (path, script) in &cps.tscs { if let Some(stem) = path.file_stem().and_then(|stem| stem.to_str()) { - names.insert(name_context.parse_or_hash_name(stem)); + names.insert(name_context.parse_i32_or_hash_name(stem)); } for line in script.lines() { if let Some(command_name) = line.split_whitespace().next() { if !command_name.is_empty() { - names.insert(name_context.parse_or_hash_name(command_name)); + names.insert(name_context.parse_i32_or_hash_name(command_name)); } } } diff --git a/bff/src/names/mod.rs b/bff/src/names/mod.rs index 83c795d..561da78 100644 --- a/bff/src/names/mod.rs +++ b/bff/src/names/mod.rs @@ -938,7 +938,7 @@ impl NameContext { self.names.lock().unwrap().name_from_i32(value) } - pub fn parse_or_hash_name(&self, token: &str) -> Name { + pub fn parse_i32_or_hash_name(&self, token: &str) -> Name { self.names.lock().unwrap().parse_i32_or_hash_name(token) } diff --git a/bff/src/tsc/cps.rs b/bff/src/tsc/cps.rs index 09067b3..a09871f 100644 --- a/bff/src/tsc/cps.rs +++ b/bff/src/tsc/cps.rs @@ -166,7 +166,7 @@ fn encode_cps_script( 0u8.write_options(writer, endian, ())?; continue; } - let command_name = name_context.parse_or_hash_name(&command_name_token); + let command_name = name_context.parse_i32_or_hash_name(&command_name_token); let mut params: Vec = Vec::new(); loop { chars @@ -323,8 +323,20 @@ impl BinWrite for Cps { copy_repeat(writer, 0, 0x10 * script_count as u64)?; writer.seek(SeekFrom::Start(pos))?; - for (path, script) in self.tscs.iter() { - let name = name_context.parse_or_hash_name(path.file_stem().unwrap().to_str().unwrap()); + let mut scripts = self + .tscs + .iter() + .map(|(path, script)| { + let name = + name_context.parse_i32_or_hash_name(path.file_stem().unwrap().to_str().unwrap()); + // Sort by unsigned hash value for deterministic CPS ordering. + let sort_key = name.get_value() as u64; + (sort_key, name, path, script) + }) + .collect::>(); + scripts.sort_by(|a, b| a.0.cmp(&b.0).then_with(|| a.2.cmp(b.2))); + + for (_, name, _, script) in scripts { let mut encoded_data = Cursor::new(Vec::new()); encode_cps_script(script, &mut encoded_data, endian, name_context)?; let encoded_data = encoded_data.into_inner();