From bbaf7b965adb245f474e7c0a6767f96d32cb13d5 Mon Sep 17 00:00:00 2001
From: miku-666 <74728189+NessieHax@users.noreply.github.com>
Date: Sun, 8 Jan 2023 00:53:43 +0100
Subject: [PATCH] Refactor Bink class, Rename Bink.cs -> Binka.cs
---
PCK-Studio/Classes/FileTypes/Bink.cs | 179 -------------------------
PCK-Studio/Classes/FileTypes/Binka.cs | 144 ++++++++++++++++++++
PCK-Studio/Forms/Editor/AudioEditor.cs | 24 ++--
PCK-Studio/PckStudio.csproj | 2 +-
4 files changed, 158 insertions(+), 191 deletions(-)
delete mode 100644 PCK-Studio/Classes/FileTypes/Bink.cs
create mode 100644 PCK-Studio/Classes/FileTypes/Binka.cs
diff --git a/PCK-Studio/Classes/FileTypes/Bink.cs b/PCK-Studio/Classes/FileTypes/Bink.cs
deleted file mode 100644
index db79fafa..00000000
--- a/PCK-Studio/Classes/FileTypes/Bink.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-namespace PckStudio.Classes
-{
- internal class Bink
- {
- [DllImport("kernel32.dll")]
- public static extern IntPtr LoadLibrary(string lpFileName);
-
- [DllImport("kernel32.dll")]
- public static extern IntPtr FreeLibrary(IntPtr library);
-
- public int temp_error_code;
- string binka_enc_loc;
- string mss32_loc;
- string binkawin_loc;
- public string working = null;
-
- public async void WavToBinka(string infile, string outFile, int compression)
- {
- var process = Process.Start(new ProcessStartInfo
- {
- FileName = binka_enc_loc,
- Arguments = $"\"{infile}\" \"{outFile}\" -s -b{compression}",
- UseShellExecute = true,
- CreateNoWindow = true,
- WindowStyle = ProcessWindowStyle.Hidden
- });
- process.WaitForExit();
- temp_error_code = process.ExitCode;
- }
-
- public unsafe void BinkaToWav(string infile, string outFile)
- {
- string[] array2 = createArg(infile, outFile);
- byte[] array3 = File.ReadAllBytes(array2[0]);
- Console.WriteLine(array3.Length);
- uint num = 0U;
- AIL_set_redist_directory(".");
- AIL_startup();
- IntPtr intPtr;
- // crash happens in AIL_decompress_ASI
- if (AIL_decompress_ASI(array3, (uint)array3.Length, ".binka", &intPtr, &num, 0U) == 0)
- throw new Exception("AIL ERROR");
- byte[] array4 = new byte[num];
- Marshal.Copy(intPtr, array4, 0, array4.Length);
- AIL_mem_free_lock(intPtr);
- AIL_shutdown();
- File.WriteAllBytes(array2[1], array4);
- }
-
- public void SetUpBinka()
- {
- if (working == null)
- {
- working = (Path.GetTempPath() + "PCKStudio").Replace("\\","/");
- Directory.CreateDirectory(working);
- binka_enc_loc = ExtractResource("binka_encode.exe", working);
- mss32_loc = ExtractResource("mss32.dll", working);
- binkawin_loc = ExtractResource("binkawin.asi", working);
- library = LoadLibrary(mss32_loc);
- }
- else
- {
- binka_enc_loc = working + "\\binka_encode.exe";
- mss32_loc = working + "\\mss32.dll";
- binkawin_loc = working + "\\binkawin.asi";
- }
- }
-
- public void CleanUpBinka()
- {
- File.Delete(binka_enc_loc);
- File.Delete(binkawin_loc);
- while (File.Exists(mss32_loc))
- {
- try
- {
- File.Delete(mss32_loc);
- }
- catch
- {
- FreeLibrary(library);
- }
- }
- Directory.Delete(working);
- }
-
- private static string getType(string loc)
- {
- string a = Path.GetExtension(loc).ToLower();
- bool flag = a == ".binka";
- string result;
- if (flag)
- {
- result = "BINKA";
- }
- else
- {
- bool flag2 = !(a == ".wav");
- if (flag2)
- {
- throw new Exception("File type not valid. To use MP3 or other audio formats, convert to wav format before using this tool");
- }
- result = "WAV";
- }
- return result;
- }
-
- private static string[] createArg(string inFile, string outdir = null)
- {
- string[] array = new string[2];
- array[0] = inFile;
- string[] array2 = array;
- string type = getType(inFile);
- bool flag = type == "BINKA";
- if (flag)
- {
- array2[1] = ((outdir.Length <= 3) ? Path.GetFullPath(inFile.Replace(".binka", ".wav")) : (outdir + "\\" + Path.GetFileName(inFile.Replace(".binka", ".wav"))));
- }
- else
- {
- bool flag2 = type == "WAV";
- if (flag2)
- {
- array2[1] = ((outdir.Length <= 3) ? Path.GetFullPath(inFile.Replace(".wav", ".binka")) : (outdir + "\\" + Path.GetFileName(inFile.Replace(".wav", ".binka"))));
- }
- }
- bool flag3 = !Directory.Exists(Path.GetDirectoryName(array2[1]));
- if (flag3)
- {
- Directory.CreateDirectory(Path.GetDirectoryName(array2[1]));
- }
- return array2;
- }
-
- internal static string ExtractResource(string resource, string working)
- {
- object ob = Properties.Resources.ResourceManager.GetObject(Path.GetFileNameWithoutExtension(resource));
- byte[] myResBytes = (byte[])ob;
- if(File.Exists(Path.Combine(working, resource))) File.Delete(Path.Combine(working, resource));
- using (FileStream fsDst = new FileStream(Path.Combine(working, resource), FileMode.CreateNew, FileAccess.Write))
- {
- fsDst.Write(myResBytes, 0, myResBytes.Length);
- fsDst.Close();
- fsDst.Dispose();
- }
- return "\"" + working + "/" + resource + "\"";
- }
-
- [DllImport("mss32.dll", EntryPoint = "_AIL_decompress_ASI@24")]
- private unsafe static extern int AIL_decompress_ASI([MarshalAs(UnmanagedType.LPArray)] byte[] indata, uint insize, [MarshalAs(UnmanagedType.LPStr)] string ext, IntPtr* result, uint* resultsize, uint zero);
-
- [DllImport("mss32.dll", EntryPoint = "_AIL_last_error@0")]
- private static extern IntPtr AIL_last_error();
-
- [DllImport("mss32.dll", EntryPoint = "_AIL_set_redist_directory@4")]
- private static extern IntPtr AIL_set_redist_directory([MarshalAs(UnmanagedType.LPStr)] string redistDir);
-
- [DllImport("mss32.dll", EntryPoint = "_AIL_mem_free_lock@4")]
- private static extern void AIL_mem_free_lock(IntPtr ptr);
-
- [DllImport("mss32.dll", EntryPoint = "_AIL_startup@0")]
- private static extern int AIL_startup();
-
- [DllImport("mss32.dll", EntryPoint = "_AIL_shutdown@0")]
- private static extern int AIL_shutdown();
-
- public Bink()
- {
- }
-
- private static IntPtr library;
- }
-}
diff --git a/PCK-Studio/Classes/FileTypes/Binka.cs b/PCK-Studio/Classes/FileTypes/Binka.cs
new file mode 100644
index 00000000..8db5f609
--- /dev/null
+++ b/PCK-Studio/Classes/FileTypes/Binka.cs
@@ -0,0 +1,144 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace PckStudio.Classes
+{
+ internal static class Binka
+ {
+ private class LibHandle
+ {
+ [DllImport("kernel32.dll")]
+ public static extern IntPtr LoadLibrary(string lpFileName);
+
+ [DllImport("kernel32.dll")]
+ public static extern int FreeLibrary(IntPtr library);
+
+ private IntPtr libHandle;
+
+ public IntPtr Handle => libHandle;
+
+ public LibHandle(string libraryPath)
+ {
+ libHandle = LoadLibrary(libraryPath);
+ }
+
+ ~LibHandle()
+ {
+ FreeLibrary(libHandle);
+ }
+ }
+
+ private static string dataCache = Program.AppDataCache;
+
+ public static uint LastAILErrorCode = 0xffffffff;
+
+ public static int FromWav(string inputFilepath, string outputFilepath, int compressionLevel)
+ {
+ var process = Process.Start(new ProcessStartInfo
+ {
+ FileName = GetAndCacheResource("binka_encode.exe"),
+ Arguments = $"\"{inputFilepath}\" \"{outputFilepath}\" -s -b{compressionLevel}",
+ UseShellExecute = true,
+ CreateNoWindow = true,
+ WindowStyle = ProcessWindowStyle.Hidden
+ });
+ process.WaitForExit();
+ return process.ExitCode;
+ }
+
+ public static unsafe void ToWav(string inputFilename, string outputFilepath)
+ {
+ // handle should be closed when function gets out of scope
+ LibHandle mss32LibHandle = new LibHandle(GetAndCacheResource("mss32.dll"));
+
+ string ext = Path.GetExtension(inputFilename).ToLower();
+ switch (ext)
+ {
+ case ".binka":
+ inputFilename = inputFilename.Replace(".binka", ".wav");
+ break;
+ case ".wav":
+ inputFilename = inputFilename.Replace(".wav", ".binka");
+ break;
+ default:
+ throw new NotSupportedException(nameof(ext)+":"+ext);
+ }
+ string outputDirectory = Path.GetDirectoryName(outputFilepath);
+ Directory.CreateDirectory(outputDirectory);
+ string destinationFilepath = Path.Combine(outputDirectory, Path.GetFileName(inputFilename));
+
+ byte[] inputFiledata = File.ReadAllBytes(inputFilename);
+ Debug.WriteLine($"{nameof(inputFiledata)}: {inputFiledata.Length}");
+
+ AILInternalCalls.SetRedistDirectory(".");
+ AILInternalCalls.Startup(); // __fastcall
+
+ int resultBufferSize = 0;
+ IntPtr resultBuffer = new IntPtr();
+ // crash happens in AIL_decompress_ASI
+ LastAILErrorCode = (uint)AILInternalCalls.DecompressASI(inputFiledata, inputFiledata.Length, ".binka", resultBuffer, &resultBufferSize);
+ Debug.WriteLine("AIL Error Code: " + LastAILErrorCode.ToString());
+
+ byte[] buffer = new byte[resultBufferSize];
+ Marshal.Copy(resultBuffer, buffer, 0, resultBufferSize);
+ AILInternalCalls.MemFreeLock(resultBuffer);
+ AILInternalCalls.Shutdown();
+ File.WriteAllBytes(destinationFilepath, buffer);
+ }
+
+ // Move to a cache class ?
+ private static string GetAndCacheResource(string resourceName)
+ {
+ _ = resourceName ?? throw new ArgumentNullException(nameof(resourceName));
+ string destinationFilepath = Path.Combine(dataCache, resourceName);
+ if (!File.Exists(destinationFilepath))
+ {
+ byte[] resourceData = ExtractResource(resourceName);
+ using (FileStream fsDst = File.OpenWrite(destinationFilepath))
+ {
+ fsDst.Write(resourceData, 0, resourceData.Length);
+ }
+ }
+ return destinationFilepath;
+ }
+
+ internal static byte[] ExtractResource(string resourceName)
+ {
+ byte[] resourceData = (byte[])Properties.Resources.ResourceManager.GetObject(Path.GetFileNameWithoutExtension(resourceName));
+ return resourceData;
+ }
+
+ private class AILInternalCalls
+ {
+ public delegate int AIL_decomp_func();
+
+ [DllImport("mss32.dll", EntryPoint = "_AIL_decompress_ASI@24")]
+ public unsafe static extern int DecompressASI(
+ [MarshalAs(UnmanagedType.LPArray)] byte[] indata,
+ int insize,
+ [MarshalAs(UnmanagedType.LPStr)] string ext,
+ IntPtr result,
+ int *resultSize,
+ [MarshalAs(UnmanagedType.FunctionPtr)] AIL_decomp_func func = null);
+
+ [DllImport("mss32.dll", EntryPoint = "_AIL_last_error@0")]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string LastError();
+
+ [DllImport("mss32.dll", EntryPoint = "_AIL_set_redist_directory@4")]
+ [return: MarshalAs(UnmanagedType.LPStr)]
+ public static extern string SetRedistDirectory([MarshalAs(UnmanagedType.LPStr)] string redistDir);
+
+ [DllImport("mss32.dll", EntryPoint = "_AIL_mem_free_lock@4")]
+ public static extern void MemFreeLock(IntPtr ptr);
+
+ [DllImport("mss32.dll", EntryPoint = "_AIL_startup@0")]
+ public static extern int Startup();
+
+ [DllImport("mss32.dll", EntryPoint = "_AIL_shutdown@0")]
+ public static extern int Shutdown();
+ }
+ }
+}
diff --git a/PCK-Studio/Forms/Editor/AudioEditor.cs b/PCK-Studio/Forms/Editor/AudioEditor.cs
index 4b38e025..3340a54d 100644
--- a/PCK-Studio/Forms/Editor/AudioEditor.cs
+++ b/PCK-Studio/Forms/Editor/AudioEditor.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using MetroFramework.Forms;
+using PckStudio.Classes;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.PCK;
using PckStudio.Forms.Additional_Popups.Audio;
@@ -18,7 +19,6 @@ namespace PckStudio.Forms.Editor
public partial class AudioEditor : MetroForm
{
public string defaultType = "yes";
- Classes.Bink BINK = new Classes.Bink();
PCKAudioFile audioFile = null;
PCKFile.FileData audioPCK;
LOCFile loc;
@@ -55,8 +55,6 @@ namespace PckStudio.Forms.Editor
loc = locFile;
_isLittleEndian = isLittleEndian;
- BINK.SetUpBinka();
-
audioPCK = file;
using (var stream = new MemoryStream(file.data))
{
@@ -185,7 +183,8 @@ namespace PckStudio.Forms.Editor
async void ProcessEntries(string[] FileList)
{
- foreach (string file in FileList)
+ int exitCode = 0;
+ foreach (string file in FileList)
{
if (Path.GetExtension(file) == ".binka" || Path.GetExtension(file) == ".wav")
{
@@ -214,14 +213,14 @@ namespace PckStudio.Forms.Editor
await Task.Run(() =>
{
- BINK.WavToBinka(file, new_loc, (int)compressionUpDown.Value);
+ exitCode = Binka.FromWav(file, new_loc, (int)compressionUpDown.Value);
});
waitDiag.Close();
waitDiag.Dispose();
Cursor.Current = Cursors.Default;
- if (BINK.temp_error_code != 0) continue;
+ if (exitCode != 0) continue;
}
else if (!duplicate_song)
{
@@ -404,7 +403,10 @@ namespace PckStudio.Forms.Editor
{
if (!parent.CreateDataFolder()) return;
- OpenFileDialog ofn = new OpenFileDialog();
+ int exitCode = 0;
+
+
+ OpenFileDialog ofn = new OpenFileDialog();
ofn.Multiselect = true;
ofn.Filter = "Supported audio files (*.binka,*.wav)|*.binka;*.wav";
ofn.Title = "Please choose WAV or BINKA files to replace existing track files";
@@ -436,16 +438,16 @@ namespace PckStudio.Forms.Editor
await Task.Run(() =>
{
- BINK.WavToBinka(file, new_loc, (int)compressionUpDown.Value);
+ exitCode = Binka.FromWav(file, new_loc, (int)compressionUpDown.Value);
});
waitDiag.Close();
waitDiag.Dispose();
Cursor.Current = Cursors.Default;
- if (BINK.temp_error_code != 0) continue;
+ if (exitCode != 0) continue;
}
- else if(file_ext == ".binka") File.Copy(file, Path.Combine(parent.GetDataPath(), Path.GetFileName(file)));
+ else if(file_ext == ".binka") File.Copy(file, Path.Combine(parent.GetDataPath(), Path.GetFileName(file)));
}
}
@@ -453,7 +455,7 @@ namespace PckStudio.Forms.Editor
{
if (treeView2.SelectedNode != null && treeView1.SelectedNode.Tag is PCKAudioFile.AudioCategory)
{
- BINK.BinkaToWav(Path.Combine(parent.GetDataPath(), treeView2.SelectedNode.Text + ".binka"), Path.Combine(parent.GetDataPath()));
+ Binka.ToWav(Path.Combine(parent.GetDataPath(), treeView2.SelectedNode.Text + ".binka"), Path.Combine(parent.GetDataPath()));
}
}
}
diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj
index e62d00a1..de59ee2d 100644
--- a/PCK-Studio/PckStudio.csproj
+++ b/PCK-Studio/PckStudio.csproj
@@ -141,7 +141,7 @@
-
+