2024-02-23 02:58:01 +00:00
|
|
|
# nod [![Build Status]][actions] [![Latest Version]][crates.io] [![Api Rustdoc]][rustdoc] ![Rust Version]
|
2021-08-23 13:48:35 +00:00
|
|
|
|
2024-10-18 06:09:18 +00:00
|
|
|
[Build Status]: https://github.com/encounter/nod/actions/workflows/build.yaml/badge.svg
|
|
|
|
[actions]: https://github.com/encounter/nod/actions
|
2021-08-23 13:48:35 +00:00
|
|
|
[Latest Version]: https://img.shields.io/crates/v/nod.svg
|
|
|
|
[crates.io]: https://crates.io/crates/nod
|
|
|
|
[Api Rustdoc]: https://img.shields.io/badge/api-rustdoc-blue.svg
|
|
|
|
[rustdoc]: https://docs.rs/nod
|
2024-11-22 07:11:48 +00:00
|
|
|
[Rust Version]: https://img.shields.io/badge/rust-1.81+-blue.svg?maxAge=3600
|
2021-08-23 13:48:35 +00:00
|
|
|
|
2024-11-22 07:33:51 +00:00
|
|
|
Library for reading and writing Nintendo Optical Disc (GameCube and Wii) images.
|
2021-08-23 13:48:35 +00:00
|
|
|
|
2024-02-17 05:53:37 +00:00
|
|
|
Originally based on the C++ library [nod](https://github.com/AxioDL/nod),
|
2024-11-22 07:33:51 +00:00
|
|
|
but with extended format support and many additional features.
|
2021-08-23 13:48:35 +00:00
|
|
|
|
|
|
|
Currently supported file formats:
|
2024-09-11 05:19:19 +00:00
|
|
|
|
2024-02-02 23:17:35 +00:00
|
|
|
- ISO (GCM)
|
|
|
|
- WIA / RVZ
|
2024-02-21 07:04:23 +00:00
|
|
|
- WBFS (+ NKit 2 lossless)
|
|
|
|
- CISO (+ NKit 2 lossless)
|
2024-11-22 07:33:51 +00:00
|
|
|
- NFS (Wii U VC, read-only)
|
2024-02-23 02:58:01 +00:00
|
|
|
- GCZ
|
2024-09-04 05:34:05 +00:00
|
|
|
- TGC
|
2021-08-23 13:48:35 +00:00
|
|
|
|
2024-02-17 05:53:37 +00:00
|
|
|
## CLI tool
|
2021-08-23 13:48:35 +00:00
|
|
|
|
2024-09-05 02:26:19 +00:00
|
|
|
This crate includes a command-line tool called `nodtool`.
|
|
|
|
|
|
|
|
Download the latest release from the [releases page](https://github.com/encounter/nod-rs/releases),
|
|
|
|
or install it using Cargo:
|
|
|
|
|
|
|
|
```shell
|
|
|
|
cargo install --locked nodtool
|
|
|
|
```
|
2024-02-17 05:53:37 +00:00
|
|
|
|
|
|
|
### info
|
|
|
|
|
|
|
|
Displays information about a disc image.
|
|
|
|
|
|
|
|
```shell
|
|
|
|
nodtool info /path/to/game.iso
|
|
|
|
```
|
|
|
|
|
|
|
|
### extract
|
|
|
|
|
|
|
|
Extracts the contents of a disc image to a directory.
|
2021-08-23 13:48:35 +00:00
|
|
|
|
|
|
|
```shell
|
|
|
|
nodtool extract /path/to/game.iso [outdir]
|
|
|
|
```
|
|
|
|
|
2024-02-17 05:53:37 +00:00
|
|
|
For Wii U VC titles, use `content/hif_000000.nfs`:
|
2021-08-23 13:48:35 +00:00
|
|
|
|
|
|
|
```shell
|
|
|
|
nodtool extract /path/to/game/content/hif_000000.nfs [outdir]
|
|
|
|
```
|
|
|
|
|
2024-02-17 05:53:37 +00:00
|
|
|
### convert
|
|
|
|
|
2024-11-22 07:33:51 +00:00
|
|
|
Converts a disc image to any supported format.
|
|
|
|
|
|
|
|
See `nodtool convert --help` for more information.
|
2024-02-17 05:53:37 +00:00
|
|
|
|
|
|
|
```shell
|
2024-11-22 07:33:51 +00:00
|
|
|
nodtool convert /path/to/game.iso /path/to/game.rvz
|
2024-09-11 05:19:19 +00:00
|
|
|
```
|
2024-02-17 05:53:37 +00:00
|
|
|
|
2024-02-22 06:47:13 +00:00
|
|
|
### verify
|
|
|
|
|
2024-11-22 07:33:51 +00:00
|
|
|
Verifies a disc image against an internal Redump database.
|
2024-02-22 06:47:13 +00:00
|
|
|
|
|
|
|
```shell
|
|
|
|
nodtool verify /path/to/game.iso
|
|
|
|
```
|
|
|
|
|
2024-02-17 05:53:37 +00:00
|
|
|
## Library example
|
2021-08-23 13:48:35 +00:00
|
|
|
|
|
|
|
Opening a disc image and reading a file:
|
2024-02-02 23:17:35 +00:00
|
|
|
|
2021-08-23 13:48:35 +00:00
|
|
|
```rust
|
|
|
|
use std::io::Read;
|
|
|
|
|
2024-02-24 19:35:41 +00:00
|
|
|
// Open a disc image and the first data partition.
|
|
|
|
let disc = nod::Disc::new("path/to/file.iso")
|
|
|
|
.expect("Failed to open disc");
|
|
|
|
let mut partition = disc.open_partition_kind(nod::PartitionKind::Data)
|
|
|
|
.expect("Failed to open data partition");
|
|
|
|
|
|
|
|
// Read partition metadata and the file system table.
|
|
|
|
let meta = partition.meta()
|
|
|
|
.expect("Failed to read partition metadata");
|
|
|
|
let fst = meta.fst()
|
|
|
|
.expect("File system table is invalid");
|
|
|
|
|
|
|
|
// Find a file by path and read it into a string.
|
|
|
|
if let Some((_, node)) = fst.find("/MP3/Worlds.txt") {
|
|
|
|
let mut s = String::new();
|
|
|
|
partition
|
|
|
|
.open_file(node)
|
|
|
|
.expect("Failed to open file stream")
|
|
|
|
.read_to_string(&mut s)
|
|
|
|
.expect("Failed to read file");
|
|
|
|
println!("{}", s);
|
2021-08-23 13:48:35 +00:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-02-24 19:35:41 +00:00
|
|
|
Converting a disc image to raw ISO:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
// Enable `rebuild_encryption` to ensure the output is a valid ISO.
|
|
|
|
let options = nod::OpenOptions { rebuild_encryption: true, ..Default::default() };
|
|
|
|
let mut disc = nod::Disc::new_with_options("path/to/file.rvz", &options)
|
|
|
|
.expect("Failed to open disc");
|
|
|
|
|
|
|
|
// Read directly from the open disc and write to the output file.
|
|
|
|
let mut out = std::fs::File::create("output.iso")
|
|
|
|
.expect("Failed to create output file");
|
|
|
|
std::io::copy(&mut disc, &mut out)
|
|
|
|
.expect("Failed to write data");
|
|
|
|
```
|
|
|
|
|
2024-02-17 05:53:37 +00:00
|
|
|
## License
|
2021-08-23 13:48:35 +00:00
|
|
|
|
|
|
|
Licensed under either of
|
|
|
|
|
2024-09-11 05:19:19 +00:00
|
|
|
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
|
|
|
|
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
|
2021-08-23 13:48:35 +00:00
|
|
|
|
|
|
|
at your option.
|
|
|
|
|
|
|
|
### Contribution
|
|
|
|
|
|
|
|
Unless you explicitly state otherwise, any contribution intentionally submitted
|
|
|
|
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
|
|
|
|
additional terms or conditions.
|