Skip to content

Commit d29c2ae

Browse files
committed
add guardrails (lgf) and lane decals (llf)
1 parent df078fa commit d29c2ae

17 files changed

+453
-16
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
Cargo.lock
33
*.png
44
tmp.bin
5-
.vscode/
5+
.vscode/
6+
tmp/

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[workspace]
2-
members = ["crates/*"]
2+
members = ["crates/*"]
3+
resolver = "2"

crates/slidetown-cli/src/lbf.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fn process_obj(obj_opts: ObjOpts) -> anyhow::Result<()> {
7373
Err(e) => {
7474
println!(
7575
"Failed to parse NIF for block index {} unk {}: {:?}",
76-
block_object.index, block_object.unk, e
76+
block_object.block_index, block_object.unk, e
7777
);
7878
continue;
7979
}
@@ -83,7 +83,7 @@ fn process_obj(obj_opts: ObjOpts) -> anyhow::Result<()> {
8383
&nif,
8484
Some(format!(
8585
"Block{}Object{}",
86-
block_object.index, block_object.unk
86+
block_object.block_index, block_object.unk
8787
)),
8888
);
8989
}
@@ -128,7 +128,7 @@ fn process_gltf(gltf_opts: GltfOpts) -> anyhow::Result<()> {
128128
Err(e) => {
129129
println!(
130130
"Failed to parse NIF for block index {} unk {}: {:?}",
131-
block_object.index, block_object.unk, e
131+
block_object.block_index, block_object.unk, e
132132
);
133133
continue;
134134
}
@@ -137,7 +137,10 @@ fn process_gltf(gltf_opts: GltfOpts) -> anyhow::Result<()> {
137137
gltf.visit_nif(
138138
&nif,
139139
Some("Block Objects"),
140-
&format!("Block{}Object{}", block_object.index, block_object.unk),
140+
&format!(
141+
"Block{}Object{}",
142+
block_object.block_index, block_object.unk
143+
),
141144
);
142145
}
143146
}

crates/slidetown-cli/src/lgf.rs

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
use std::{
2+
fs::File,
3+
io::{Cursor, Read, Seek, SeekFrom},
4+
};
5+
6+
use clap::{Parser, Subcommand};
7+
use slidetown::parsers::lgf;
8+
9+
use crate::nif_obj;
10+
11+
#[derive(Parser)]
12+
pub struct LgfOpts {
13+
#[command(subcommand)]
14+
cmd: Command,
15+
}
16+
17+
#[derive(Subcommand)]
18+
enum Command {
19+
/// display info about archive contents
20+
Info(InfoOpts),
21+
22+
/// export preview obj with terrain guardrails
23+
Obj(ObjOpts),
24+
25+
/// export preview gltf with terrain guardrails
26+
Gltf(GltfOpts),
27+
}
28+
29+
#[derive(Parser)]
30+
struct InfoOpts {
31+
/// input file
32+
#[arg(short, long)]
33+
input_path: String,
34+
}
35+
36+
fn process_info(info_opts: InfoOpts) -> anyhow::Result<()> {
37+
let mut file = File::open(&info_opts.input_path)?;
38+
let lgf: lgf::Lgf = lgf::Lgf::read(&mut file)?;
39+
40+
println!("Block count: {}", lgf.blocks.len());
41+
42+
Ok(())
43+
}
44+
45+
#[derive(Parser)]
46+
struct ObjOpts {
47+
/// input file
48+
#[arg(short, long)]
49+
input_path: String,
50+
51+
/// output file
52+
#[arg(short, long)]
53+
output_path: String,
54+
}
55+
56+
fn process_obj(obj_opts: ObjOpts) -> anyhow::Result<()> {
57+
let mut file = File::open(&obj_opts.input_path)?;
58+
let lgf: lgf::Lgf = lgf::Lgf::read(&mut file)?;
59+
60+
let mut obj = nif_obj::Obj::default();
61+
62+
for block in lgf.blocks {
63+
file.seek(SeekFrom::Start(block.file_offset as u64))?;
64+
65+
let mut nif_buf = vec![0u8; block.file_length as usize];
66+
file.read_exact(&mut nif_buf)?;
67+
68+
let mut nif_cursor = Cursor::new(nif_buf);
69+
70+
let nif = match nif::Nif::parse(&mut nif_cursor) {
71+
Ok(nif) => nif,
72+
Err(e) => {
73+
println!(
74+
"Failed to parse NIF for block index {}: {:?}",
75+
block.block_index, e
76+
);
77+
continue;
78+
}
79+
};
80+
81+
obj.visit_nif(&nif, Some(format!("Block{}Guardrail", block.block_index)));
82+
}
83+
84+
let obj_path = std::path::PathBuf::from(obj_opts.output_path);
85+
let mtl_path = obj_path.with_extension("mtl");
86+
87+
obj.write_to_files(obj_path, mtl_path)?;
88+
89+
Ok(())
90+
}
91+
92+
#[derive(Parser)]
93+
struct GltfOpts {
94+
/// input file
95+
#[arg(short, long)]
96+
input_path: String,
97+
98+
/// output file
99+
#[arg(short, long)]
100+
output_path: String,
101+
}
102+
103+
fn process_gltf(gltf_opts: GltfOpts) -> anyhow::Result<()> {
104+
let mut file = File::open(&gltf_opts.input_path)?;
105+
let lgf: lgf::Lgf = lgf::Lgf::read(&mut file)?;
106+
107+
let mut gltf = nif::collectors::gltf::Gltf::new();
108+
109+
for block in lgf.blocks {
110+
file.seek(SeekFrom::Start(block.file_offset as u64))?;
111+
112+
let mut nif_buf = vec![0u8; block.file_length as usize];
113+
file.read_exact(&mut nif_buf)?;
114+
115+
let mut nif_cursor = Cursor::new(nif_buf);
116+
117+
let nif = match nif::Nif::parse(&mut nif_cursor) {
118+
Ok(nif) => nif,
119+
Err(e) => {
120+
println!(
121+
"Failed to parse NIF for block index {} : {:?}",
122+
block.block_index, e
123+
);
124+
continue;
125+
}
126+
};
127+
128+
gltf.visit_nif(
129+
&nif,
130+
Some("Block Guardrails"),
131+
&format!("Block{}Guardrail", block.block_index),
132+
);
133+
}
134+
135+
let gltf_path = std::path::PathBuf::from(gltf_opts.output_path);
136+
gltf.write_to_files(gltf_path)?;
137+
138+
Ok(())
139+
}
140+
141+
pub fn process_lgf(lgf_opts: LgfOpts) -> anyhow::Result<()> {
142+
match lgf_opts.cmd {
143+
Command::Info(info_opts) => process_info(info_opts),
144+
Command::Obj(obj_opts) => process_obj(obj_opts),
145+
Command::Gltf(gltf_opts) => process_gltf(gltf_opts),
146+
}
147+
}

crates/slidetown-cli/src/llf.rs

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
use std::{
2+
fs::File,
3+
io::{Cursor, Read, Seek, SeekFrom},
4+
};
5+
6+
use clap::{Parser, Subcommand};
7+
use slidetown::parsers::llf;
8+
9+
use crate::nif_obj;
10+
11+
#[derive(Parser)]
12+
pub struct LlfOpts {
13+
#[command(subcommand)]
14+
cmd: Command,
15+
}
16+
17+
#[derive(Subcommand)]
18+
enum Command {
19+
/// display info about archive contents
20+
Info(InfoOpts),
21+
22+
/// export preview obj with terrain lane decals
23+
Obj(ObjOpts),
24+
25+
/// export preview gltf with terrain lane decals
26+
Gltf(GltfOpts),
27+
}
28+
29+
#[derive(Parser)]
30+
struct InfoOpts {
31+
/// input file
32+
#[arg(short, long)]
33+
input_path: String,
34+
}
35+
36+
fn process_info(info_opts: InfoOpts) -> anyhow::Result<()> {
37+
let mut file = File::open(&info_opts.input_path)?;
38+
let llf: llf::Llf = llf::Llf::read(&mut file)?;
39+
40+
println!("Block count: {}", llf.blocks.len());
41+
42+
Ok(())
43+
}
44+
45+
#[derive(Parser)]
46+
struct ObjOpts {
47+
/// input file
48+
#[arg(short, long)]
49+
input_path: String,
50+
51+
/// output file
52+
#[arg(short, long)]
53+
output_path: String,
54+
}
55+
56+
fn process_obj(obj_opts: ObjOpts) -> anyhow::Result<()> {
57+
let mut file = File::open(&obj_opts.input_path)?;
58+
let llf: llf::Llf = llf::Llf::read(&mut file)?;
59+
60+
let mut obj = nif_obj::Obj::default();
61+
62+
for block in llf.blocks {
63+
file.seek(SeekFrom::Start(block.file_offset as u64))?;
64+
65+
let mut nif_buf = vec![0u8; block.file_length as usize];
66+
file.read_exact(&mut nif_buf)?;
67+
68+
let mut nif_cursor = Cursor::new(nif_buf);
69+
70+
let nif = match nif::Nif::parse(&mut nif_cursor) {
71+
Ok(nif) => nif,
72+
Err(e) => {
73+
println!(
74+
"Failed to parse NIF for block index {}: {:?}",
75+
block.block_index, e
76+
);
77+
continue;
78+
}
79+
};
80+
81+
obj.visit_nif(&nif, Some(format!("Block{}Lane", block.block_index)));
82+
}
83+
84+
let obj_path = std::path::PathBuf::from(obj_opts.output_path);
85+
let mtl_path = obj_path.with_extension("mtl");
86+
87+
obj.write_to_files(obj_path, mtl_path)?;
88+
89+
Ok(())
90+
}
91+
92+
#[derive(Parser)]
93+
struct GltfOpts {
94+
/// input file
95+
#[arg(short, long)]
96+
input_path: String,
97+
98+
/// output file
99+
#[arg(short, long)]
100+
output_path: String,
101+
}
102+
103+
fn process_gltf(gltf_opts: GltfOpts) -> anyhow::Result<()> {
104+
let mut file = File::open(&gltf_opts.input_path)?;
105+
let llf: llf::Llf = llf::Llf::read(&mut file)?;
106+
107+
let mut gltf = nif::collectors::gltf::Gltf::new();
108+
109+
for block in llf.blocks {
110+
file.seek(SeekFrom::Start(block.file_offset as u64))?;
111+
112+
let mut nif_buf = vec![0u8; block.file_length as usize];
113+
file.read_exact(&mut nif_buf)?;
114+
115+
let mut nif_cursor = Cursor::new(nif_buf);
116+
117+
let nif = match nif::Nif::parse(&mut nif_cursor) {
118+
Ok(nif) => nif,
119+
Err(e) => {
120+
println!(
121+
"Failed to parse NIF for block index {} : {:?}",
122+
block.block_index, e
123+
);
124+
continue;
125+
}
126+
};
127+
128+
gltf.visit_nif(
129+
&nif,
130+
Some("Block Lane Decals"),
131+
&format!("Block{}Lane", block.block_index),
132+
);
133+
}
134+
135+
let gltf_path = std::path::PathBuf::from(gltf_opts.output_path);
136+
gltf.write_to_files(gltf_path)?;
137+
138+
Ok(())
139+
}
140+
141+
pub fn process_llf(llf_opts: LlfOpts) -> anyhow::Result<()> {
142+
match llf_opts.cmd {
143+
Command::Info(info_opts) => process_info(info_opts),
144+
Command::Obj(obj_opts) => process_obj(obj_opts),
145+
Command::Gltf(gltf_opts) => process_gltf(gltf_opts),
146+
}
147+
}

crates/slidetown/Cargo.toml

+21-3
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,31 @@ repository = "https://github.com/amPerl/slidetown"
1010
license = "MIT"
1111

1212
[features]
13-
default = ["agt", "hit", "lbf", "levelmodifier", "lf", "lif", "lof", "loi", "nui", "chpath", "xlt", "tdf", "ntx"]
13+
default = [
14+
"agt",
15+
"hit",
16+
"levelmodifier",
17+
"lf",
18+
"lbf",
19+
"lgf",
20+
"lif",
21+
"llf",
22+
"lof",
23+
"loi",
24+
"nui",
25+
"chpath",
26+
"xlt",
27+
"tdf",
28+
"ntx",
29+
]
1430
agt = ["flate2"]
1531
hit = []
16-
lbf = []
1732
levelmodifier = []
1833
lf = []
34+
lbf = []
35+
lgf = []
1936
lif = []
37+
llf = []
2038
lof = []
2139
loi = []
2240
nui = ["quick-xml"]
@@ -32,7 +50,7 @@ serde = { version = "1.0.127", features = ["derive"] }
3250
thiserror = "1.0.26"
3351
binrw = "0.11.2"
3452
flate2 = { version = "1.0.24", optional = true }
35-
quick-xml = { version = "0.22.0", features = ["encoding"], optional = true }
53+
quick-xml = { version = "0.23.1", features = ["encoding"], optional = true }
3654

3755
[dev-dependencies]
3856
chrono = "0.4.19"
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)