Parse mod names and string table

This commit is contained in:
dawnDus 2022-02-13 14:39:28 -05:00
parent dfcf2e2f3f
commit d7a25f2681
No known key found for this signature in database
GPG Key ID: 972AABDE81848F21
5 changed files with 49 additions and 4 deletions

View File

@ -85,6 +85,7 @@ tokio = { version = "1.12.0", features = ["net"], optional = true }
vec_mut_scan = "0.4"
webbrowser = "0.5.5"
winit = { git = "https://github.com/alula/winit.git", rev = "6acf76ff192dd8270aaa119b9f35716c03685f9f", optional = true, default_features = false, features = ["x11"] }
xmltree = "0.10.3"
#[build-dependencies]
#gl_generator = { version = "0.14.0", optional = true }

View File

@ -3,6 +3,7 @@ use std::io::{BufRead, BufReader, Cursor, Read};
use byteorder::{LE, ReadBytesExt};
use case_insensitive_hashmap::CaseInsensitiveHashMap;
use xmltree::Element;
use crate::case_insensitive_hashmap;
use crate::common::{BulletFlag, Color, Rect};
@ -301,6 +302,7 @@ pub struct EngineConstants {
pub organya_paths: Vec<String>,
pub credit_illustration_paths: Vec<String>,
pub animated_face_table: Vec<AnimatedFace>,
pub string_table: HashMap<String, String>,
}
impl Clone for EngineConstants {
@ -329,6 +331,7 @@ impl Clone for EngineConstants {
organya_paths: self.organya_paths.clone(),
credit_illustration_paths: self.credit_illustration_paths.clone(),
animated_face_table: self.animated_face_table.clone(),
string_table: self.string_table.clone(),
}
}
}
@ -1601,6 +1604,7 @@ impl EngineConstants {
"endpic/".to_owned(), // NXEngine
],
animated_face_table: vec![AnimatedFace { face_id: 0, anim_id: 0, anim_frames: vec![(0, 0)] }],
string_table: HashMap::new(),
}
}
@ -1727,6 +1731,27 @@ impl EngineConstants {
self.game.new_game_player_pos = pos;
}
pub fn load_nx_stringtable(&mut self, ctx: &mut Context) -> GameResult {
if let Ok(file) = filesystem::open(ctx, "/base/stringtable.sta") {
let mut reader = BufReader::new(file);
let _ = reader.read_exact(&mut [0; 3]);
if let Ok(xml) = Element::parse(reader) {
for node in &xml.get_child("category").unwrap().children {
let element = node.as_element().unwrap();
let key = element.attributes.get_key_value("name").unwrap().1.to_string();
let english = element
.get_child("string")
.unwrap()
.get_text()
.unwrap_or(std::borrow::Cow::Borrowed(""))
.to_string();
self.string_table.insert(key, english);
}
}
}
Ok(())
}
pub fn apply_constant_json_files(&mut self) {}
/// Loads bullet.tbl and arms_level.tbl from CS+ files,

View File

@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::io::{BufRead, BufReader};
use std::iter::Peekable;
use std::str::Chars;
@ -11,6 +12,8 @@ pub struct ModInfo {
pub requirement: Requirement,
pub priority: u32,
pub path: String,
pub name: String,
pub description: String,
}
#[derive(Debug, Copy, Clone)]
@ -32,7 +35,7 @@ pub struct ModList {
}
impl ModList {
pub fn load(ctx: &mut Context) -> GameResult<ModList> {
pub fn load(ctx: &mut Context, string_table: &HashMap<String, String>) -> GameResult<ModList> {
let mut mods = Vec::new();
if let Ok(file) = filesystem::open(ctx, "/mods.txt") {
@ -132,7 +135,22 @@ impl ModList {
}
}
mods.push(ModInfo { id, requirement, priority, path })
let mut name = String::new();
let mut description = String::new();
if let Ok(file) = filesystem::open(ctx, [&path, "/mod.txt"].join("")) {
let reader = BufReader::new(file);
let mut lines = reader.lines();
if let Some(line) = lines.nth(2) {
let read_name = line.unwrap_or("No Mod Name".to_string()).to_string();
name = string_table.get(&read_name).unwrap_or(&read_name).to_string();
}
if let Some(line) = lines.next() {
description = line.unwrap_or("No Description".to_string()).to_string();
}
}
mods.push(ModInfo { id, requirement, priority, path, name, description })
}
}

View File

@ -162,7 +162,7 @@ impl Scene for TitleScene {
self.save_select_menu.init(state, ctx)?;
for mod_info in state.mod_list.mods.iter() {
self.challenges_menu.push_entry(MenuEntry::Active(mod_info.path.clone()));
self.challenges_menu.push_entry(MenuEntry::Active(mod_info.name.clone()));
}
self.challenges_menu.push_entry(MenuEntry::Active("< Back".to_string()));

View File

@ -201,6 +201,7 @@ impl SharedGameState {
ctx.size_hint = (854, 480);
constants.apply_csplus_patches(&sound_manager);
constants.apply_csplus_nx_patches();
constants.load_nx_stringtable(ctx)?;
} else if filesystem::exists(ctx, "/base/Nicalis.bmp") || filesystem::exists(ctx, "/base/Nicalis.png") {
info!("Cave Story+ (PC) data files detected.");
constants.apply_csplus_patches(&sound_manager);
@ -218,7 +219,7 @@ impl SharedGameState {
BMFontRenderer::load(&vec!["/".to_owned()], "/builtin/builtin_font.fnt", ctx)
})?;
let mut mod_list = ModList::load(ctx)?;
let mut mod_list = ModList::load(ctx, &constants.string_table)?;
for i in 0..0xffu8 {
let path = format!("/pxt/fx{:02x}.pxt", i);