first commit

This commit is contained in:
Andrea Moro 2025-02-16 16:12:13 +01:00
commit aa9356ab1d
4 changed files with 312 additions and 0 deletions

135
Cargo.lock generated Normal file
View 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
View 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
View 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
View 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(())
}