From 5e2df678ab094e832349c11df7124cafef9ca49a Mon Sep 17 00:00:00 2001 From: Boris Nikolaev Date: Sun, 15 Feb 2026 22:45:57 +0300 Subject: [PATCH] add System.CommandLine argument parser --- README.md | 22 ++++--- dq8chr2glb/Converter/OutputFormat.cs | 7 ++ dq8chr2glb/Program.cs | 99 +++++++++------------------- dq8chr2glb/dq8chr2glb.csproj | 1 + 4 files changed, 52 insertions(+), 77 deletions(-) create mode 100644 dq8chr2glb/Converter/OutputFormat.cs diff --git a/README.md b/README.md index 5a99272..d8e15bf 100644 --- a/README.md +++ b/README.md @@ -19,25 +19,27 @@ A command-line tool for converting .CHR character model files from Dragon Quest | Option | Description | |--------|-------------| -| `-e` | Extract only - unpack `.chr` without conversion | -| `-t` | Output as `.glTF` (text) instead of `.glb` (binary) | -| `-b` | Batch mode - process all `.chr` files in directory | +| `-i`, `--input` | Input path | +| `-o`, `--output` | Output path | +| `-e`, `--extract` | Extract only - unpack `.chr` without conversion | +| `-f`, `--format` | Output format. `GLTF` for text format or `GLB` for binary (default: `GLB`) | +| `-b`, `--batch` | Batch mode - process all `.chr` files in directory | +| `-h`, `--help` | Show help | ## Usage ### Basic Syntax ``` -dq8chr2glb.exe [options] -dq8chr2glb.exe -b # Batch mode -dq8chr2glb.exe # No args for get help +dq8chr2glb.exe -i -o [options] +dq8chr2glb.exe -i -b # Batch mode ``` ### Examples ``` -dq8chr2glb.exe "C:\Games\DQ8\@DATA.DAT\chara\ap002.chr" "C:\Exports" -dq8chr2glb.exe "C:\Games\DQ8\@DATA.DAT\chara" -b -dq8chr2glb.exe "C:\Games\DQ8\@DATA.DAT\chara\ap002.chr" "C:\Exports" -e -dq8chr2glb.exe "C:\Games\DQ8\@DATA.DAT\chara" -b -e +dq8chr2glb.exe -i "C:\Games\DQ8\@DATA.DAT\chara\ap002.chr" -o "C:\Exports" +dq8chr2glb.exe -i "C:\Games\DQ8\@DATA.DAT\chara" -b +dq8chr2glb.exe -i "C:\Games\DQ8\@DATA.DAT\chara\ap002.chr" -o "C:\Exports" -e +dq8chr2glb.exe -i "C:\Games\DQ8\@DATA.DAT\chara" -b -t GLTF ``` diff --git a/dq8chr2glb/Converter/OutputFormat.cs b/dq8chr2glb/Converter/OutputFormat.cs new file mode 100644 index 0000000..6bbdee9 --- /dev/null +++ b/dq8chr2glb/Converter/OutputFormat.cs @@ -0,0 +1,7 @@ +namespace dq8chr2glb.Converter; + +public enum OutputFormat +{ + GLB, + GLTF, +} diff --git a/dq8chr2glb/Program.cs b/dq8chr2glb/Program.cs index 611ef71..2033b64 100644 --- a/dq8chr2glb/Program.cs +++ b/dq8chr2glb/Program.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.CommandLine; using System.IO; +using dq8chr2glb.Converter; using dq8chr2glb.Logger; namespace dq8chr2glb; @@ -9,57 +11,41 @@ public class Program { public static void Main(string[] args) { - if (args.Length < 2) + var rootCommand = new RootCommand("Converts .CHR files from Dragon Quest VIII (Playstation 2) to .glb/.glTF format.") { - ShowHelp(); - return; - } + new Option("-i", "--input") { Description = "Input path", HelpName = "input path"}, + new Option("-o", "--output") { Description = "Output path", HelpName = "output path"}, + new Option("-f", "--format") {Description = "Output format", DefaultValueFactory = _ => OutputFormat.GLB}, + new Option("-e", "--extract") {Description = "Extract only - unpack .chr without conversion"}, + new Option("-b", "--batch") {Description = "Batch mode - process all .chr files in the input directory"}, + new Option("-l", "--log") { Description = "Log level", DefaultValueFactory = _ => LogMode.MINIMAL }, + }; - var extractOnly = false; - var textFormat = false; - var batchMode = false; + var parser = rootCommand.Parse(args); - var processedArgs = new List(); - for (int i = 0; i < args.Length; i++) - { - var arg = args[i]; - if (arg == "-e") - extractOnly = true; - else if (arg == "-t") - textFormat = true; - else if (arg == "-b") - batchMode = true; - else - processedArgs.Add(arg); - } - - if (batchMode) - { - if (processedArgs.Count != 1) - { - Console.WriteLine("Error: Batch mode (-b) requires exactly one argument: "); - ShowHelp(); - return; - } - } - else - { - if (processedArgs.Count != 2) - { - Console.WriteLine("Error: Expected and "); - ShowHelp(); - return; - } - } - - var inputPath = processedArgs[0]; - var outputPath = batchMode ? inputPath : processedArgs[1]; + var inputPath = parser.GetValue("-i"); + var outputPath = parser.GetValue("-o"); + var extractOnly = parser.GetValue("-e"); + var textFormat = parser.GetValue("-f") == OutputFormat.GLTF; + var batchMode = parser.GetValue("-b"); var chrFile = new ChrFile(); chrFile.convert = !extractOnly; chrFile.extract = extractOnly; chrFile.textFormat = textFormat; + if (string.IsNullOrEmpty(inputPath)) + { + Console.WriteLine("Input path is required! Use -h to see help screen."); + return; + } + + if (string.IsNullOrEmpty(outputPath)) + { + var dirName = Path.GetFileNameWithoutExtension(inputPath); + outputPath = Path.Combine(Path.GetDirectoryName(inputPath), dirName); + } + if (batchMode) { var files = Directory.GetFiles(inputPath, "*.chr", SearchOption.TopDirectoryOnly); @@ -75,41 +61,20 @@ public class Program Console.WriteLine(e); throw; } - - chrFile.Clean(); } - Log.Line(files.Length == 0 ? "No .chr files found in the input directory." : "Done!", LogLevel.Info); + Console.WriteLine(files.Length == 0 ? "No .chr files found in the input directory." : "Done!"); } else { if (!File.Exists(inputPath)) { - Log.Line($"Input file not found: {inputPath}", LogLevel.Error); + Console.WriteLine($"Input file not found: {inputPath}"); return; } chrFile.Process(inputPath, outputPath); - Log.Line("Done!", LogLevel.Info); + Console.WriteLine("Done!"); } } - - private static void ShowHelp() - { - Console.WriteLine("Converts .CHR files from Dragon Quest VIII (Playstation 2) to .glb/.glTF format."); - Console.WriteLine(); - Console.WriteLine("Usage:"); - Console.WriteLine(" dq8chr2glb.exe [options]"); - Console.WriteLine(" dq8chr2glb.exe -b (batch mode: output files are saved in the )"); - Console.WriteLine("Examples:"); - Console.WriteLine(" dq8chr2glb.exe \"C:\\Users\\Boris\\Desktop\\ChrFormatTest\\ap002.chr\" \"C:\\Users\\Boris\\Desktop\\ChrFormatTest\" -e"); - Console.WriteLine(" dq8chr2glb.exe \"C:\\Users\\Boris\\Desktop\\ChrFormatTest\" -b"); - Console.WriteLine(); - Console.WriteLine("Options:"); - Console.WriteLine(" -e - Extract only - unpack .chr without conversion"); - Console.WriteLine(" -t - Output as .glTF (text) instead of .glb (binary)"); - Console.WriteLine(" -b - Batch mode - process all .chr files in the input directory"); - Console.WriteLine(); - var line = Console.ReadLine(); - } -} \ No newline at end of file +} diff --git a/dq8chr2glb/dq8chr2glb.csproj b/dq8chr2glb/dq8chr2glb.csproj index ba57cf5..eb3c05e 100644 --- a/dq8chr2glb/dq8chr2glb.csproj +++ b/dq8chr2glb/dq8chr2glb.csproj @@ -13,6 +13,7 @@ +