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" vec_mut_scan = "0.4"
webbrowser = "0.5.5" webbrowser = "0.5.5"
winit = { git = "https://github.com/alula/winit.git", rev = "6acf76ff192dd8270aaa119b9f35716c03685f9f", optional = true, default_features = false, features = ["x11"] } winit = { git = "https://github.com/alula/winit.git", rev = "6acf76ff192dd8270aaa119b9f35716c03685f9f", optional = true, default_features = false, features = ["x11"] }
xmltree = "0.10.3"
#[build-dependencies] #[build-dependencies]
#gl_generator = { version = "0.14.0", optional = true } #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 byteorder::{LE, ReadBytesExt};
use case_insensitive_hashmap::CaseInsensitiveHashMap; use case_insensitive_hashmap::CaseInsensitiveHashMap;
use xmltree::Element;
use crate::case_insensitive_hashmap; use crate::case_insensitive_hashmap;
use crate::common::{BulletFlag, Color, Rect}; use crate::common::{BulletFlag, Color, Rect};
@ -301,6 +302,7 @@ pub struct EngineConstants {
pub organya_paths: Vec<String>, pub organya_paths: Vec<String>,
pub credit_illustration_paths: Vec<String>, pub credit_illustration_paths: Vec<String>,
pub animated_face_table: Vec<AnimatedFace>, pub animated_face_table: Vec<AnimatedFace>,
pub string_table: HashMap<String, String>,
} }
impl Clone for EngineConstants { impl Clone for EngineConstants {
@ -329,6 +331,7 @@ impl Clone for EngineConstants {
organya_paths: self.organya_paths.clone(), organya_paths: self.organya_paths.clone(),
credit_illustration_paths: self.credit_illustration_paths.clone(), credit_illustration_paths: self.credit_illustration_paths.clone(),
animated_face_table: self.animated_face_table.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 "endpic/".to_owned(), // NXEngine
], ],
animated_face_table: vec![AnimatedFace { face_id: 0, anim_id: 0, anim_frames: vec![(0, 0)] }], 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; 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) {} pub fn apply_constant_json_files(&mut self) {}
/// Loads bullet.tbl and arms_level.tbl from CS+ files, /// 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::io::{BufRead, BufReader};
use std::iter::Peekable; use std::iter::Peekable;
use std::str::Chars; use std::str::Chars;
@ -11,6 +12,8 @@ pub struct ModInfo {
pub requirement: Requirement, pub requirement: Requirement,
pub priority: u32, pub priority: u32,
pub path: String, pub path: String,
pub name: String,
pub description: String,
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@ -32,7 +35,7 @@ pub struct ModList {
} }
impl 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(); let mut mods = Vec::new();
if let Ok(file) = filesystem::open(ctx, "/mods.txt") { 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)?; self.save_select_menu.init(state, ctx)?;
for mod_info in state.mod_list.mods.iter() { 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())); self.challenges_menu.push_entry(MenuEntry::Active("< Back".to_string()));

View File

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