From fd085848e60831a8582c24de8f30ad4528f9d490 Mon Sep 17 00:00:00 2001 From: Treeki Date: Sat, 26 Mar 2011 03:45:34 +0100 Subject: unfinished console interface to NW4RTools added --- ConsoleApp/AssemblyInfo.cs | 27 ++++++++ ConsoleApp/Command.cs | 15 ++++ ConsoleApp/ConsoleApp.csproj | 51 ++++++++++++++ ConsoleApp/Main.cs | 84 +++++++++++++++++++++++ ConsoleApp/ModelCommands.cs | 118 ++++++++++++++++++++++++++++++++ ConsoleApp/ResFileCommands.cs | 89 ++++++++++++++++++++++++ ConsoleApp/TextureCommands.cs | 75 ++++++++++++++++++++ ConsoleApp/bin/Debug/ConsoleApp.exe | Bin 0 -> 12288 bytes ConsoleApp/bin/Debug/ConsoleApp.exe.mdb | Bin 0 -> 2945 bytes ConsoleApp/bin/Debug/NW4RTools.dll | Bin 0 -> 239104 bytes ConsoleApp/bin/Debug/NW4RTools.dll.mdb | Bin 0 -> 114935 bytes ConsoleApp/bin/Debug/OpenTK.dll | Bin 0 -> 2719744 bytes ConsoleApp/bin/Debug/OpenTK.dll.config | 12 ++++ NW4RTools.sln | 9 ++- NW4RTools/BrresReader.cs | 14 +++- NW4RTools/Logger.cs | 20 ++++++ NW4RTools/ResFile.cs | 2 +- NW4RTools/bin/Debug/NW4RTools.dll | Bin 238592 -> 239104 bytes NW4RTools/bin/Debug/NW4RTools.dll.mdb | Bin 114661 -> 114935 bytes TestApp/bin/Debug/NW4RTools.dll | Bin 238592 -> 239104 bytes TestApp/bin/Debug/NW4RTools.dll.mdb | Bin 114661 -> 114935 bytes TestApp/bin/Debug/TestApp.exe | Bin 6656 -> 6656 bytes TestApp/bin/Debug/TestApp.exe.mdb | Bin 1181 -> 1181 bytes 23 files changed, 510 insertions(+), 6 deletions(-) create mode 100644 ConsoleApp/AssemblyInfo.cs create mode 100644 ConsoleApp/Command.cs create mode 100644 ConsoleApp/ConsoleApp.csproj create mode 100644 ConsoleApp/Main.cs create mode 100644 ConsoleApp/ModelCommands.cs create mode 100644 ConsoleApp/ResFileCommands.cs create mode 100644 ConsoleApp/TextureCommands.cs create mode 100755 ConsoleApp/bin/Debug/ConsoleApp.exe create mode 100644 ConsoleApp/bin/Debug/ConsoleApp.exe.mdb create mode 100755 ConsoleApp/bin/Debug/NW4RTools.dll create mode 100644 ConsoleApp/bin/Debug/NW4RTools.dll.mdb create mode 100644 ConsoleApp/bin/Debug/OpenTK.dll create mode 100644 ConsoleApp/bin/Debug/OpenTK.dll.config diff --git a/ConsoleApp/AssemblyInfo.cs b/ConsoleApp/AssemblyInfo.cs new file mode 100644 index 0000000..0e0b4ae --- /dev/null +++ b/ConsoleApp/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("ConsoleApp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/ConsoleApp/Command.cs b/ConsoleApp/Command.cs new file mode 100644 index 0000000..dcb6def --- /dev/null +++ b/ConsoleApp/Command.cs @@ -0,0 +1,15 @@ +using System; +namespace ConsoleApp { + public abstract class Command { + public readonly string Description; + + public Command(string description) { + Description = description; + } + + + public abstract void Execute(string[] args); + public abstract string GetHelp(string[] args); + } +} + diff --git a/ConsoleApp/ConsoleApp.csproj b/ConsoleApp/ConsoleApp.csproj new file mode 100644 index 0000000..451221d --- /dev/null +++ b/ConsoleApp/ConsoleApp.csproj @@ -0,0 +1,51 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {0EDC614B-9673-48A3-BB48-3D6CC54D20ED} + Exe + ConsoleApp + ConsoleApp + v3.5 + + + true + full + false + bin\Debug + DEBUG + prompt + 4 + true + + + none + false + bin\Release + prompt + 4 + true + + + + + + + + + + + + + + + + + {A9C9FABD-0A5F-4DAB-979D-9F288F96866F} + NW4RTools + + + \ No newline at end of file diff --git a/ConsoleApp/Main.cs b/ConsoleApp/Main.cs new file mode 100644 index 0000000..322d277 --- /dev/null +++ b/ConsoleApp/Main.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; + +namespace ConsoleApp { + class MainClass { + private static Dictionary CommandLookup; + + private static void SetupCommands() { + CommandLookup = new Dictionary(); + + CommandLookup.Add("init", new InitCommand()); + CommandLookup.Add("list", new ListCommand()); + CommandLookup.Add("import-obj", new ImportObjCommand()); + CommandLookup.Add("export-obj", new ExportObjCommand()); + CommandLookup.Add("export-collada", new ExportColladaCommand()); + CommandLookup.Add("export-textures", new ExportTexturesCommand()); + } + + public static void Main(string[] args) { + Console.WriteLine("NW4RTools by Treeki"); + Console.WriteLine(); + + SetupCommands(); + + // process the command line + string cmd; + string[] cmdArgs; + + if (args.Length == 0) { + cmd = "help"; + cmdArgs = new string[0]; + } else { + cmd = args[0]; + cmdArgs = new string[args.Length - 1]; + + for (int i = 1; i < args.Length; i++) { + cmdArgs[i - 1] = args[i]; + } + } + + // handle Help if needed + if (cmd == "help") { + Help(cmdArgs); + return; + } + + // otherwise, pass it on + if (CommandLookup.ContainsKey(cmd)) { + CommandLookup[cmd].Execute(cmdArgs); + } else { + Console.WriteLine("Unknown command {0}. Try \"help\" for a list of usable commands", cmd); + } + } + + private static void Help(string[] args) { + if (args.Length == 0) { + Console.WriteLine("Available commands:"); + + foreach (var cmd in CommandLookup) { + Console.WriteLine("- {0}: {1}", cmd.Key, cmd.Value.Description); + } + + Console.WriteLine(); + Console.WriteLine("For additional info, try: help "); + + } else { + if (CommandLookup.ContainsKey(args[0])) { + Console.WriteLine("Help for {0}:", args[0]); + string[] helpArgs = new string[args.Length - 1]; + + for (int i = 1; i < args.Length; i++) { + helpArgs[i - 1] = args[i]; + } + + Console.WriteLine(CommandLookup[args[0]].GetHelp(helpArgs)); + + } else { + Console.WriteLine("Unknown command {0}. Try \"help\" for a list of usable commands", args[0]); + } + } + } + } +} + diff --git a/ConsoleApp/ModelCommands.cs b/ConsoleApp/ModelCommands.cs new file mode 100644 index 0000000..9bbf1f3 --- /dev/null +++ b/ConsoleApp/ModelCommands.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.IO; +using NW4RTools; + +namespace ConsoleApp { + public class ImportObjCommand : ResFileCommand { + public ImportObjCommand() : base("import an .obj model and associated textures") { + } + + protected override void OperateOnFile(string[] args) { + if (args.Length < 2 || args.Length > 3) { + Console.WriteLine("invalid syntax.\n" + GetHelp(null)); + return; + } + + string currentDir = Directory.GetCurrentDirectory(); + string objPath = Path.Combine(currentDir, args[0]); + string objDir = Path.GetDirectoryName(objPath); + + ObjImporter.LightmapType lmType = ObjImporter.LightmapType.None; + if (args.Length == 3 && args[2] != "none") { + switch (args[2]) { + case "map": + lmType = ObjImporter.LightmapType.Map; + break; + case "mapobj": + lmType = ObjImporter.LightmapType.MapObj; + break; + default: + Console.WriteLine("warning: unknown lightmap type {0}", args[2]); + break; + } + } + + + Console.WriteLine("importing model..."); + + ObjImporter.ImportModel(objDir, new StreamReader(objPath), TargetFile, args[1], lmType); + + Console.WriteLine("saving file..."); + + SaveFile(); + + Console.WriteLine("done!"); + } + + public override string GetHelp(string[] args) { + return "syntax: import-obj [lightmap-mode]\n" + + " imports an .obj model and the associated textures.\n\n" + + " model-name will be the name of the ResMdl.\n" + + " lightmap-mode may be: none (default), map, mapobj"; + } + } + + + + public class ExportObjCommand : ResFileCommand { + public ExportObjCommand() : base("export an .obj model") { + } + + protected override void OperateOnFile(string[] args) { + if (args.Length != 2) { + Console.WriteLine("invalid syntax.\n" + GetHelp(null)); + return; + } + + string currentDir = Directory.GetCurrentDirectory(); + string objPath = Path.Combine(currentDir, args[0]); + string objDir = Path.GetDirectoryName(objPath); + + Console.WriteLine("exporting model..."); + + ObjExporter.WriteModel(new StreamWriter(objPath), TargetFile, args[1]); + + Console.WriteLine("done!"); + } + + public override string GetHelp(string[] args) { + return "syntax: export-obj \n" + + " exports a model as .obj.\n\n" + + " model-name will be the name of the ResMdl.\n" + + " more settings will be added later."; + } + } + + + + public class ExportColladaCommand : ResFileCommand { + public ExportColladaCommand() : base("export a COLLADA (.dae) model") { + } + + protected override void OperateOnFile(string[] args) { + if (args.Length != 2) { + Console.WriteLine("invalid syntax.\n" + GetHelp(null)); + return; + } + + string currentDir = Directory.GetCurrentDirectory(); + string daePath = Path.Combine(currentDir, args[0]); + string daeDir = Path.GetDirectoryName(daePath); + + Console.WriteLine("exporting model..."); + + ColladaExporter.WriteModel(File.OpenWrite(daePath), TargetFile, args[1]); + + Console.WriteLine("done!"); + } + + public override string GetHelp(string[] args) { + return "syntax: export-collada \n" + + " exports a model as COLLADA (.dae).\n\n" + + " model-name will be the name of the ResMdl.\n" + + " more settings will be added later."; + } + } +} + diff --git a/ConsoleApp/ResFileCommands.cs b/ConsoleApp/ResFileCommands.cs new file mode 100644 index 0000000..ac734e4 --- /dev/null +++ b/ConsoleApp/ResFileCommands.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using NW4RTools; + +namespace ConsoleApp { + public abstract class ResFileCommand : Command { + public ResFileCommand(string description) : base(description) { + } + + public ResFile TargetFile { get; private set; } + public string TargetPath { get; private set; } + + public override void Execute(string[] args) { + if (args.Length == 0) { + Console.WriteLine("No path entered"); + return; + } + + // don't override this + var newArgs = new string[args.Length - 1]; + + for (int i = 1; i < args.Length; i++) { + newArgs[i - 1] = args[i]; + } + + + var data = System.IO.File.ReadAllBytes(args[0]); + TargetFile = BrresReader.LoadFile(data, false); + TargetPath = args[0]; + + OperateOnFile(newArgs); + } + + protected abstract void OperateOnFile(string[] args); + + protected void SaveFile() { + var data = BrresWriter.WriteFile(TargetFile); + System.IO.File.WriteAllBytes(TargetPath, data); + } + } + + + public class InitCommand : Command { + // this class doesn't inherit from ResFileCommand because it is a special case: + // instead of operating on an existing file, it creates one + + public InitCommand() : base("create an empty .brres file") { + } + + + public override void Execute(string[] args) { + if (args.Length == 0) { + Console.WriteLine("No path entered"); + return; + } + + var rf = new ResFile(); + System.IO.File.WriteAllBytes(args[0], BrresWriter.WriteFile(rf)); + } + + public override string GetHelp(string[] args) { + return "syntax: init -- creates an empty .brres file"; + } + } + + + public class ListCommand : ResFileCommand { + public ListCommand() : base("list the resources in a .brres file") { + } + + protected override void OperateOnFile(string[] args) { + foreach (var g in TargetFile) { + Console.WriteLine("{0}", g.Key); + + // time to try hackishness + var dict = g.Value as System.Collections.Specialized.IOrderedDictionary; + + foreach (var e in dict.Keys) { + Console.WriteLine(" - {0}", e); + } + } + } + + public override string GetHelp(string[] args) { + return "syntax: list -- lists the contents of a .brres file"; + } + } +} + diff --git a/ConsoleApp/TextureCommands.cs b/ConsoleApp/TextureCommands.cs new file mode 100644 index 0000000..3fad0c7 --- /dev/null +++ b/ConsoleApp/TextureCommands.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.IO; +using NW4RTools; + +namespace ConsoleApp { + public class ExportTexturesCommand : ResFileCommand { + public ExportTexturesCommand() : base("export texture(s) to PNG") { + } + + protected override void OperateOnFile(string[] args) { + if (args.Length < 1) { + Console.WriteLine("invalid syntax.\n" + GetHelp(null)); + return; + } + + bool exportAll = (args.Length == 1); + var list = new List(); + + for (int i = 1; i < args.Length; i++) { + list.Add(args[i]); + } + + + var texDict = TargetFile.GetTextureGroup(); + if (texDict == null || texDict.Count == 0) { + Console.WriteLine("this file has no textures."); + return; + } + + int exportCount = 0; + + string currentDir = Directory.GetCurrentDirectory(); + string imgDir = Path.Combine(currentDir, args[0]); + + // one last check + if (!Directory.Exists(imgDir)) { + Console.WriteLine("the destination directory does not exist:\n {0}", imgDir); + return; + } + + foreach (var kv in texDict) { + if (exportAll || list.Contains(kv.Key)) { + for (int i = 0; i < kv.Value.Images.Length; i++) { + var img = kv.Value.Images[i]; + + string imgName; + if (i == 0) { + // first (possibly only?) mipmap + imgName = String.Format("{0}.png", kv.Key); + } else { + imgName = String.Format("{0}__{1}.png", kv.Key, i); + } + + Console.WriteLine("{0}[{4}] {1}x{2} {3}", kv.Key, img.Width, img.Height, kv.Value.Format, i); + + img.Save(Path.Combine(imgDir, imgName)); + } + + exportCount++; + } + } + + Console.WriteLine("done! {0} textures exported", exportCount); + } + + public override string GetHelp(string[] args) { + return "syntax: export-textures [texture-names...]\n" + + " exports texture(s) as .png files.\n\n" + + " dest-path will be the folder in which the textures are placed (eg. images).\n" + + " texture-names is a list of textures. if not specified, every texture is exported."; + } + } +} + diff --git a/ConsoleApp/bin/Debug/ConsoleApp.exe b/ConsoleApp/bin/Debug/ConsoleApp.exe new file mode 100755 index 0000000..0b677f2 Binary files /dev/null and b/ConsoleApp/bin/Debug/ConsoleApp.exe differ diff --git a/ConsoleApp/bin/Debug/ConsoleApp.exe.mdb b/ConsoleApp/bin/Debug/ConsoleApp.exe.mdb new file mode 100644 index 0000000..fa4218f Binary files /dev/null and b/ConsoleApp/bin/Debug/ConsoleApp.exe.mdb differ diff --git a/ConsoleApp/bin/Debug/NW4RTools.dll b/ConsoleApp/bin/Debug/NW4RTools.dll new file mode 100755 index 0000000..3e86a0a Binary files /dev/null and b/ConsoleApp/bin/Debug/NW4RTools.dll differ diff --git a/ConsoleApp/bin/Debug/NW4RTools.dll.mdb b/ConsoleApp/bin/Debug/NW4RTools.dll.mdb new file mode 100644 index 0000000..1bff220 Binary files /dev/null and b/ConsoleApp/bin/Debug/NW4RTools.dll.mdb differ diff --git a/ConsoleApp/bin/Debug/OpenTK.dll b/ConsoleApp/bin/Debug/OpenTK.dll new file mode 100644 index 0000000..afff0dd Binary files /dev/null and b/ConsoleApp/bin/Debug/OpenTK.dll differ diff --git a/ConsoleApp/bin/Debug/OpenTK.dll.config b/ConsoleApp/bin/Debug/OpenTK.dll.config new file mode 100644 index 0000000..99aef86 --- /dev/null +++ b/ConsoleApp/bin/Debug/OpenTK.dll.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/NW4RTools.sln b/NW4RTools.sln index 224f5e3..953e643 100644 --- a/NW4RTools.sln +++ b/NW4RTools.sln @@ -5,12 +5,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NW4RTools", "NW4RTools\NW4R EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApp", "TestApp\TestApp.csproj", "{3A064CD8-CFAD-412D-986F-ED7D2D54CDB1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "ConsoleApp\ConsoleApp.csproj", "{0EDC614B-9673-48A3-BB48-3D6CC54D20ED}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0EDC614B-9673-48A3-BB48-3D6CC54D20ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0EDC614B-9673-48A3-BB48-3D6CC54D20ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0EDC614B-9673-48A3-BB48-3D6CC54D20ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0EDC614B-9673-48A3-BB48-3D6CC54D20ED}.Release|Any CPU.Build.0 = Release|Any CPU {3A064CD8-CFAD-412D-986F-ED7D2D54CDB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3A064CD8-CFAD-412D-986F-ED7D2D54CDB1}.Debug|Any CPU.Build.0 = Debug|Any CPU {3A064CD8-CFAD-412D-986F-ED7D2D54CDB1}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -38,12 +44,11 @@ Global $3.MethodBraceStyle = EndOfLine $3.ConstructorBraceStyle = EndOfLine $3.DestructorBraceStyle = EndOfLine - $3.BeforeMethodDeclarationParentheses = False $3.BeforeMethodCallParentheses = False + $3.BeforeMethodDeclarationParentheses = False $3.BeforeConstructorDeclarationParentheses = False $3.BeforeDelegateDeclarationParentheses = False $3.NewParentheses = False - $3.SpacesBeforeBrackets = False $3.inheritsSet = Mono $3.inheritsScope = text/x-csharp $3.scope = text/x-csharp diff --git a/NW4RTools/BrresReader.cs b/NW4RTools/BrresReader.cs index d5db720..aa54437 100644 --- a/NW4RTools/BrresReader.cs +++ b/NW4RTools/BrresReader.cs @@ -7,7 +7,11 @@ using NW4RTools.Models; namespace NW4RTools { public class BrresReader { public static ResFile LoadFile(byte[] data) { - return new BrresReader().Load(new InputStream(data, ByteEndian.BigEndian)); + return LoadFile(data, true); + } + + public static ResFile LoadFile(byte[] data, bool debug) { + return new BrresReader(debug).Load(new InputStream(data, ByteEndian.BigEndian)); } @@ -21,8 +25,12 @@ namespace NW4RTools { private ILogger Debug; private SortedDictionary OffsetMap; - private BrresReader() { - Debug = new ConsoleLogger(); + private BrresReader(bool debug) { + if (debug) + Debug = new ConsoleLogger(); + else + Debug = new NullLogger(); + OffsetMap = new SortedDictionary(); } diff --git a/NW4RTools/Logger.cs b/NW4RTools/Logger.cs index a6fbb70..9f7d063 100644 --- a/NW4RTools/Logger.cs +++ b/NW4RTools/Logger.cs @@ -24,6 +24,26 @@ namespace NW4RTools { void Unblock(); } + public class NullLogger : ILogger { + public NullLogger() { } + + public void Send(string format, params object[] args) { + } + + public LogContext Push(string format, params object[] args) { + return new LogContext(this); + } + + public void Pop() { + } + + public void Block() { + } + + public void Unblock() { + } + } + public class ConsoleLogger : ILogger { private List PrefixElements; private List Names; diff --git a/NW4RTools/ResFile.cs b/NW4RTools/ResFile.cs index 4f4a1b8..aae0038 100644 --- a/NW4RTools/ResFile.cs +++ b/NW4RTools/ResFile.cs @@ -19,7 +19,7 @@ namespace NW4RTools { } public ResDict GetGroup(string name) { - return this[name] as ResDict; + return ContainsKey(name) ? (this[name] as ResDict) : null; } diff --git a/NW4RTools/bin/Debug/NW4RTools.dll b/NW4RTools/bin/Debug/NW4RTools.dll index 9b33424..3e86a0a 100755 Binary files a/NW4RTools/bin/Debug/NW4RTools.dll and b/NW4RTools/bin/Debug/NW4RTools.dll differ diff --git a/NW4RTools/bin/Debug/NW4RTools.dll.mdb b/NW4RTools/bin/Debug/NW4RTools.dll.mdb index 183dfbb..1bff220 100644 Binary files a/NW4RTools/bin/Debug/NW4RTools.dll.mdb and b/NW4RTools/bin/Debug/NW4RTools.dll.mdb differ diff --git a/TestApp/bin/Debug/NW4RTools.dll b/TestApp/bin/Debug/NW4RTools.dll index 9b33424..3e86a0a 100755 Binary files a/TestApp/bin/Debug/NW4RTools.dll and b/TestApp/bin/Debug/NW4RTools.dll differ diff --git a/TestApp/bin/Debug/NW4RTools.dll.mdb b/TestApp/bin/Debug/NW4RTools.dll.mdb index 183dfbb..1bff220 100644 Binary files a/TestApp/bin/Debug/NW4RTools.dll.mdb and b/TestApp/bin/Debug/NW4RTools.dll.mdb differ diff --git a/TestApp/bin/Debug/TestApp.exe b/TestApp/bin/Debug/TestApp.exe index 90719af..cb2f6f1 100755 Binary files a/TestApp/bin/Debug/TestApp.exe and b/TestApp/bin/Debug/TestApp.exe differ diff --git a/TestApp/bin/Debug/TestApp.exe.mdb b/TestApp/bin/Debug/TestApp.exe.mdb index b688c06..3f1eb72 100644 Binary files a/TestApp/bin/Debug/TestApp.exe.mdb and b/TestApp/bin/Debug/TestApp.exe.mdb differ -- cgit v1.2.3