first commit
This commit is contained in:
commit
aa9356ab1d
4 changed files with 312 additions and 0 deletions
135
Cargo.lock
generated
Normal file
135
Cargo.lock
generated
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.38"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.217"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.217"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.138"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.98"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "trkconverter"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "trkconverter"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
regex = "1.5"
|
9
README.md
Normal file
9
README.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# trkconverter
|
||||||
|
|
||||||
|
tool to convert old trk format to new trk format for just dance
|
||||||
|
|
||||||
|
# usage
|
||||||
|
|
||||||
|
```
|
||||||
|
trkconverter <input_drum.trk> <output_new.trk>
|
||||||
|
```
|
159
src/main.rs
Normal file
159
src/main.rs
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
struct BuuTrack {
|
||||||
|
#[serde(rename = "$format")]
|
||||||
|
format: i32,
|
||||||
|
Markers: Vec<i32>,
|
||||||
|
Signatures: Vec<Signature>,
|
||||||
|
Sections: Vec<serde_json::Value>,
|
||||||
|
Comments: Vec<serde_json::Value>,
|
||||||
|
Ambiances: Vec<serde_json::Value>,
|
||||||
|
AudioFilePath: String,
|
||||||
|
StartBeat: i32,
|
||||||
|
EndBeat: i32,
|
||||||
|
VideoStartTime: String,
|
||||||
|
Volume: f32,
|
||||||
|
PreviewEntry: f32,
|
||||||
|
PreviewLoopStart: f32,
|
||||||
|
PreviewLoopEnd: f32,
|
||||||
|
FadeInDuration: f32,
|
||||||
|
FadeOutDuration: f32,
|
||||||
|
FadeStartBeat: f32,
|
||||||
|
FadeEndBeat: f32,
|
||||||
|
UseFadeStartBeat: bool,
|
||||||
|
UseFadeEndBeat: bool,
|
||||||
|
FadeInType: i32,
|
||||||
|
FadeOutType: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
struct Signature {
|
||||||
|
Comment: String,
|
||||||
|
Marker: f32,
|
||||||
|
Beat: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_drum_trk(content: &str) -> Result<BuuTrack, Box<dyn std::error::Error>> {
|
||||||
|
// Extract markers
|
||||||
|
let re_markers = Regex::new(r"\{\s*VAL\s*=\s*(\d+)\s*\}")?;
|
||||||
|
let markers: Vec<i32> = re_markers
|
||||||
|
.captures_iter(content)
|
||||||
|
.map(|cap| cap[1].parse().unwrap())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Extract signature data
|
||||||
|
let re_signature = Regex::new(r#"MusicSignature\s*=\s*\{\s*beats\s*=\s*(\d+),\s*marker\s*=\s*([0-9.]+),\s*comment\s*=\s*"(.*?)"\s*\}"#)?;
|
||||||
|
let mut signatures = Vec::new();
|
||||||
|
|
||||||
|
for cap in re_signature.captures_iter(content) {
|
||||||
|
let beat = cap[1].parse()?;
|
||||||
|
let marker = cap[2].parse()?;
|
||||||
|
let comment = cap[3].to_string();
|
||||||
|
|
||||||
|
signatures.push(Signature {
|
||||||
|
Comment: comment,
|
||||||
|
Marker: marker,
|
||||||
|
Beat: beat,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract start and end beats
|
||||||
|
let re_beats = Regex::new(r"startBeat\s*=\s*(\d+),\s*endBeat\s*=\s*(\d+)")?;
|
||||||
|
let (start_beat, end_beat) = if let Some(cap) = re_beats.captures(content) {
|
||||||
|
(cap[1].parse()?, cap[2].parse()?)
|
||||||
|
} else {
|
||||||
|
(0, 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extract video start time
|
||||||
|
let re_video_time = Regex::new(r"videoStartTime\s*=\s*([0-9.]+)")?;
|
||||||
|
let video_time = if let Some(cap) = re_video_time.captures(content) {
|
||||||
|
cap[1].parse::<f32>()?
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
|
||||||
|
// Format video time as HH:MM:SS
|
||||||
|
let hours = (video_time / 3600.0) as i32;
|
||||||
|
let minutes = ((video_time % 3600.0) / 60.0) as i32;
|
||||||
|
let seconds = (video_time % 60.0) as i32;
|
||||||
|
let video_time_str = format!("{:02}:{:02}:{:02}", hours, minutes, seconds);
|
||||||
|
|
||||||
|
// Extract volume
|
||||||
|
let re_volume = Regex::new(r"volume\s*=\s*([0-9.]+)")?;
|
||||||
|
let volume = if let Some(cap) = re_volume.captures(content) {
|
||||||
|
cap[1].parse()?
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extract preview values
|
||||||
|
let re_preview = Regex::new(r"previewEntry\s*=\s*([0-9.]+),\s*previewLoopStart\s*=\s*([0-9.]+),\s*previewLoopEnd\s*=\s*([0-9.]+)")?;
|
||||||
|
let (preview_entry, preview_loop_start, preview_loop_end) = if let Some(cap) = re_preview.captures(content) {
|
||||||
|
(cap[1].parse()?, cap[2].parse()?, cap[3].parse()?)
|
||||||
|
} else {
|
||||||
|
(0.0, 0.0, 0.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Construct the BuuTrack
|
||||||
|
let buu_track = BuuTrack {
|
||||||
|
format: 0,
|
||||||
|
Markers: markers,
|
||||||
|
Signatures: signatures,
|
||||||
|
Sections: Vec::new(),
|
||||||
|
Comments: Vec::new(),
|
||||||
|
Ambiances: Vec::new(),
|
||||||
|
AudioFilePath: "maps\\Drum\\audio\\Drum.wav".to_string(), // Default path
|
||||||
|
StartBeat: start_beat,
|
||||||
|
EndBeat: end_beat,
|
||||||
|
VideoStartTime: video_time_str,
|
||||||
|
Volume: volume,
|
||||||
|
PreviewEntry: preview_entry,
|
||||||
|
PreviewLoopStart: preview_loop_start,
|
||||||
|
PreviewLoopEnd: preview_loop_end,
|
||||||
|
FadeInDuration: 0.0,
|
||||||
|
FadeOutDuration: 0.0,
|
||||||
|
FadeStartBeat: 0.0,
|
||||||
|
FadeEndBeat: 0.0,
|
||||||
|
UseFadeStartBeat: false,
|
||||||
|
UseFadeEndBeat: false,
|
||||||
|
FadeInType: 0,
|
||||||
|
FadeOutType: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(buu_track)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
|
if args.len() != 3 {
|
||||||
|
eprintln!("Usage: {} <input_drum.trk> <output_6buu.trk>", args[0]);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let input_path = &args[1];
|
||||||
|
let output_path = &args[2];
|
||||||
|
|
||||||
|
// Read the input file
|
||||||
|
let content = fs::read_to_string(input_path)
|
||||||
|
.map_err(|e| format!("Failed to read input file: {}", e))?;
|
||||||
|
|
||||||
|
// Parse the Drum.trk content
|
||||||
|
let buu_track = parse_drum_trk(&content)?;
|
||||||
|
|
||||||
|
// Serialize to JSON
|
||||||
|
let json = serde_json::to_string_pretty(&buu_track)?;
|
||||||
|
|
||||||
|
// Write to output file
|
||||||
|
fs::write(output_path, json)
|
||||||
|
.map_err(|e| format!("Failed to write output file: {}", e))?;
|
||||||
|
|
||||||
|
println!("Successfully converted {} to {}", input_path, output_path);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue