mirror of
https://github.com/Theaninova/mhlib.git
synced 2025-12-11 03:56:18 +00:00
Add install flow
This commit is contained in:
3
rust/Cargo.lock
generated
3
rust/Cargo.lock
generated
@@ -719,6 +719,9 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "renderwarelib"
|
name = "renderwarelib"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"binrw",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rgb"
|
name = "rgb"
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ pub enum MaterialProjectionMode {
|
|||||||
pub struct MaterialUvInfo {
|
pub struct MaterialUvInfo {
|
||||||
pub diffuse_projection: Option<MaterialProjectionMode>,
|
pub diffuse_projection: Option<MaterialProjectionMode>,
|
||||||
pub color_projection: Option<MaterialProjectionMode>,
|
pub color_projection: Option<MaterialProjectionMode>,
|
||||||
|
pub max_smoothing_angle: Option<f32>,
|
||||||
pub material: Gd<ShaderMaterial>,
|
pub material: Gd<ShaderMaterial>,
|
||||||
pub id: u16,
|
pub id: u16,
|
||||||
}
|
}
|
||||||
@@ -37,6 +38,7 @@ impl MaterialUvInfo {
|
|||||||
let mut m = MaterialUvInfo {
|
let mut m = MaterialUvInfo {
|
||||||
diffuse_projection: None,
|
diffuse_projection: None,
|
||||||
color_projection: None,
|
color_projection: None,
|
||||||
|
max_smoothing_angle: None,
|
||||||
material: ShaderMaterial::new(),
|
material: ShaderMaterial::new(),
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
@@ -244,6 +246,9 @@ impl MaterialUvInfo {
|
|||||||
}
|
}
|
||||||
.to_variant(),
|
.to_variant(),
|
||||||
),
|
),
|
||||||
|
SurfaceParameterSubChunk::MaxSmoothingAngle(it) => {
|
||||||
|
m.max_smoothing_angle = Some(it.max_smoothing_angle);
|
||||||
|
}
|
||||||
SurfaceParameterSubChunk::BaseShadingValueDiffuse(it) => {
|
SurfaceParameterSubChunk::BaseShadingValueDiffuse(it) => {
|
||||||
m.material
|
m.material
|
||||||
.set_shader_parameter("diffuse".into(), it.value.to_variant());
|
.set_shader_parameter("diffuse".into(), it.value.to_variant());
|
||||||
|
|||||||
@@ -107,21 +107,31 @@ impl SurfaceInfo {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (id, poly) in surface_polygons {
|
for (id, poly) in surface_polygons {
|
||||||
for index in triangulate(&poly.vert) {
|
let tri = triangulate(&poly.vert);
|
||||||
|
/*let edge0 = layer.points[tri[1] as usize] - layer.points[tri[0] as usize];
|
||||||
|
let edge1 = layer.points[tri[tri.len() - 2] as usize]
|
||||||
|
- layer.points[tri[tri.len() - 1] as usize];
|
||||||
|
let normal = edge0.cross(edge1);*/
|
||||||
|
|
||||||
|
for index in tri {
|
||||||
let uv = uv_subset
|
let uv = uv_subset
|
||||||
.iter()
|
.iter()
|
||||||
.map(|it| it.and_then(|(_, it)| find_mapping(it, id, index)))
|
.map(|it| it.and_then(|(_, it)| find_mapping(it, id, index)))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
// TODO: let weight = find_mapping(weight_mappings, id, vert);
|
// TODO: let weight = find_mapping(weight_mappings, id, vert);
|
||||||
let vert = layer.points.get(index as usize).unwrap();
|
let vert = layer.points[index as usize];
|
||||||
|
|
||||||
surface_info.push_index(vert, &uv, 0f32);
|
surface_info.push_index(&vert, &uv, 0f32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
surface_info
|
surface_info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn surface_normals(&mut self) {
|
||||||
|
let normals: HashMap<i32, Vector3> = HashMap::with_capacity(self.vertices.len());
|
||||||
|
}
|
||||||
|
|
||||||
fn push_index(&mut self, vert: &Vector3, uvs: &[Option<Vector2>], weight: f32) {
|
fn push_index(&mut self, vert: &Vector3, uvs: &[Option<Vector2>], weight: f32) {
|
||||||
let index = *self
|
let index = *self
|
||||||
.vertex_map
|
.vertex_map
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::starforce::sar_archive::{sarc_path_to_gd, SarLoader, GAMES_PATH};
|
use crate::starforce::sar_archive::{sarc_path_to_gd, SarLoader, INSTALL_PATH};
|
||||||
use godot::bind::godot_api;
|
use godot::bind::godot_api;
|
||||||
use godot::builtin::GodotString;
|
use godot::builtin::{GodotString, ToVariant, Variant};
|
||||||
use godot::engine::file_access::ModeFlags;
|
use godot::engine::file_access::ModeFlags;
|
||||||
use godot::engine::global::Error;
|
use godot::engine::global::Error;
|
||||||
use godot::engine::{try_load, DirAccess, FileAccess, PckPacker, Resource, ResourceLoader};
|
use godot::engine::{try_load, FileAccess, PckPacker, Resource, ResourceLoader};
|
||||||
use godot::log::godot_print;
|
use godot::log::godot_print;
|
||||||
use godot::obj::{Gd, Share};
|
use godot::obj::{Gd, Share};
|
||||||
use godot::prelude::GodotClass;
|
use godot::prelude::GodotClass;
|
||||||
@@ -11,8 +11,7 @@ use itertools::Itertools;
|
|||||||
use starforcelib::sarc::SarcArchive;
|
use starforcelib::sarc::SarcArchive;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::iter::{Chain, FlatMap};
|
use std::iter::Enumerate;
|
||||||
use std::path::Iter;
|
|
||||||
use std::vec::IntoIter;
|
use std::vec::IntoIter;
|
||||||
|
|
||||||
/// This is supposedly to be the default.
|
/// This is supposedly to be the default.
|
||||||
@@ -20,18 +19,41 @@ const KEY: &str = "0000000000000000000000000000000000000000000000000000000000000
|
|||||||
|
|
||||||
#[derive(GodotClass)]
|
#[derive(GodotClass)]
|
||||||
#[class(init)]
|
#[class(init)]
|
||||||
pub struct Mhk3Map {}
|
pub struct Mhk3Map {
|
||||||
|
#[export]
|
||||||
|
pub progress: f32,
|
||||||
|
pub total_files: i32,
|
||||||
|
files_to_convert: Option<Enumerate<IntoIter<String>>>,
|
||||||
|
loader: Option<Gd<SarLoader>>,
|
||||||
|
game: GodotString,
|
||||||
|
}
|
||||||
|
|
||||||
#[godot_api]
|
#[godot_api]
|
||||||
impl Mhk3Map {
|
impl Mhk3Map {
|
||||||
#[func]
|
#[func]
|
||||||
pub fn get_available_maps() {}
|
pub fn tick_install(&mut self) -> Variant {
|
||||||
|
self.files_to_convert
|
||||||
|
.as_mut()
|
||||||
|
.map(|it| {
|
||||||
|
it.next()
|
||||||
|
.map(|(i, file)| {
|
||||||
|
godot_print!("Loading {}", file);
|
||||||
|
try_load::<Resource>(&file);
|
||||||
|
self.progress = i as f32 / self.total_files as f32;
|
||||||
|
file.strip_prefix(INSTALL_PATH)
|
||||||
|
.unwrap()
|
||||||
|
.rsplit_once('.')
|
||||||
|
.unwrap()
|
||||||
|
.0
|
||||||
|
.to_variant()
|
||||||
|
})
|
||||||
|
.unwrap_or_else(Variant::nil)
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| Error::FAILED.to_variant())
|
||||||
|
}
|
||||||
|
|
||||||
#[func]
|
#[func]
|
||||||
pub fn test() {}
|
pub fn start_install(&mut self, path: GodotString, game: GodotString) -> Error {
|
||||||
|
|
||||||
#[func]
|
|
||||||
pub fn install(path: GodotString, game: GodotString) -> Error {
|
|
||||||
let file = if let Some(file) = FileAccess::open(path, ModeFlags::READ) {
|
let file = if let Some(file) = FileAccess::open(path, ModeFlags::READ) {
|
||||||
file
|
file
|
||||||
} else {
|
} else {
|
||||||
@@ -78,18 +100,34 @@ impl Mhk3Map {
|
|||||||
base,
|
base,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.total_files = files_to_convert.len() as i32;
|
||||||
|
self.files_to_convert = Some(files_to_convert.into_iter().sorted().enumerate());
|
||||||
|
|
||||||
ResourceLoader::singleton().add_resource_format_loader(sar_loader.share().upcast(), true);
|
ResourceLoader::singleton().add_resource_format_loader(sar_loader.share().upcast(), true);
|
||||||
for (i, file) in files_to_convert.into_iter().sorted().enumerate() {
|
self.loader = Some(sar_loader);
|
||||||
godot_print!("{}x Next up: {}", i, file);
|
self.game = game;
|
||||||
try_load::<Resource>(file);
|
Error::OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[func]
|
||||||
|
pub fn end_install(&mut self) -> Error {
|
||||||
|
let sar_loader = if let Some(loader) = self.loader.take() {
|
||||||
|
loader
|
||||||
|
} else {
|
||||||
|
return Error::FAILED;
|
||||||
|
};
|
||||||
ResourceLoader::singleton().remove_resource_format_loader(sar_loader.upcast());
|
ResourceLoader::singleton().remove_resource_format_loader(sar_loader.upcast());
|
||||||
|
|
||||||
let mut packer = PckPacker::new();
|
let mut packer = PckPacker::new();
|
||||||
packer.pck_start(format!("user://{}.pck", game).into(), 32, KEY.into(), false);
|
packer.pck_start(
|
||||||
|
format!("user://{}.pck", self.game).into(),
|
||||||
|
32,
|
||||||
|
KEY.into(),
|
||||||
|
false,
|
||||||
|
);
|
||||||
for file in SarLoader::list_installed_files() {
|
for file in SarLoader::list_installed_files() {
|
||||||
packer.add_file(
|
packer.add_file(
|
||||||
SarLoader::resource_path_at(file.clone(), &game),
|
SarLoader::resource_path_at(file.clone(), &self.game),
|
||||||
file.clone().into(),
|
file.clone().into(),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "renderwarelib"
|
name = "renderwarelib"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
binrw = "0.11.2"
|
||||||
|
|||||||
9
rust/renderwarelib/src/chunks/clump.rs
Normal file
9
rust/renderwarelib/src/chunks/clump.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
use binrw::binread;
|
||||||
|
|
||||||
|
#[binread]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RpClump {
|
||||||
|
pub num_atomics: i32,
|
||||||
|
pub num_lights: i32,
|
||||||
|
pub num_cameras: i32,
|
||||||
|
}
|
||||||
40
rust/renderwarelib/src/chunks/mod.rs
Normal file
40
rust/renderwarelib/src/chunks/mod.rs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
use binrw::{binread, NullString};
|
||||||
|
|
||||||
|
pub mod clump;
|
||||||
|
|
||||||
|
#[binread]
|
||||||
|
#[br(little)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RwStream {
|
||||||
|
pub kind: u32,
|
||||||
|
pub size: u32,
|
||||||
|
pub library_id_stamp: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[binread]
|
||||||
|
#[br(little)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum RwSection {
|
||||||
|
#[br(magic(0x1u32))]
|
||||||
|
Struct {},
|
||||||
|
#[br(magic(0x2u32))]
|
||||||
|
String(#[br(align_after = 4)] NullString),
|
||||||
|
// TODO: extension
|
||||||
|
// TODO: camera
|
||||||
|
// TODO: texture
|
||||||
|
// TODO: material
|
||||||
|
// TODO: material list
|
||||||
|
// TODO: atomic section
|
||||||
|
// TODO: plane section
|
||||||
|
// TODO: world
|
||||||
|
// TODO: spline
|
||||||
|
// TODO: matrix
|
||||||
|
// TODO: frame list
|
||||||
|
// TODO: geometry
|
||||||
|
#[br(magic(0x10u32))]
|
||||||
|
Clump {
|
||||||
|
num_atomics: u32,
|
||||||
|
num_lights: u32,
|
||||||
|
num_cameras: u32,
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
pub mod chunks;
|
||||||
|
|
||||||
pub fn add(left: usize, right: usize) -> usize {
|
pub fn add(left: usize, right: usize) -> usize {
|
||||||
left + right
|
left + right
|
||||||
}
|
}
|
||||||
|
|||||||
11
rust/renderwarelib/src/main.rs
Normal file
11
rust/renderwarelib/src/main.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use binrw::BinRead;
|
||||||
|
use renderwarelib::chunks::RwSection;
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let mut file = File::open("/run/media/theaninova/Heart Drive/Games/Moorhuhn Kart 2/data/data/mk2/level01/objects/collision_border.dff")
|
||||||
|
.unwrap();
|
||||||
|
let data = RwSection::read(&mut file).unwrap();
|
||||||
|
|
||||||
|
println!("{:?}", data)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user