discontinue single character file format
This commit is contained in:
parent
4ec6533971
commit
5d216840db
23 changed files with 56 additions and 244 deletions
14
USTConverter/USTConverter.Gtk/Program.cs
Normal file
14
USTConverter/USTConverter.Gtk/Program.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace USTConverter.Gtk
|
||||
{
|
||||
class Program
|
||||
{
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
new Application(Eto.Platforms.Gtk).Run(new MainForm());
|
||||
}
|
||||
}
|
||||
}
|
17
USTConverter/USTConverter.Gtk/USTConverter.Gtk.csproj
Normal file
17
USTConverter/USTConverter.Gtk/USTConverter.Gtk.csproj
Normal file
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\USTConverter\USTConverter.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Eto.Platform.Gtk" Version="2.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
BIN
USTConverter/USTConverter.Mac/Icon.icns
Normal file
BIN
USTConverter/USTConverter.Mac/Icon.icns
Normal file
Binary file not shown.
20
USTConverter/USTConverter.Mac/Info.plist
Normal file
20
USTConverter/USTConverter.Mac/Info.plist
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>USTConverter</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>me.kawaiizenbo.USTConverter</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.3</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.15</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>Icon.icns</string>
|
||||
</dict>
|
||||
</plist>
|
14
USTConverter/USTConverter.Mac/Program.cs
Normal file
14
USTConverter/USTConverter.Mac/Program.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace USTConverter.Mac
|
||||
{
|
||||
class Program
|
||||
{
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
new Application(Eto.Platforms.Mac64).Run(new MainForm());
|
||||
}
|
||||
}
|
||||
}
|
18
USTConverter/USTConverter.Mac/USTConverter.Mac.csproj
Normal file
18
USTConverter/USTConverter.Mac/USTConverter.Mac.csproj
Normal file
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
|
||||
<RuntimeIdentifiers>osx-x64;osx-arm64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\USTConverter\USTConverter.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Eto.Platform.Mac64" Version="2.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
14
USTConverter/USTConverter.Wpf/Program.cs
Normal file
14
USTConverter/USTConverter.Wpf/Program.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace USTConverter.Wpf
|
||||
{
|
||||
class Program
|
||||
{
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
new Application(Eto.Platforms.Wpf).Run(new MainForm());
|
||||
}
|
||||
}
|
||||
}
|
17
USTConverter/USTConverter.Wpf/USTConverter.Wpf.csproj
Normal file
17
USTConverter/USTConverter.Wpf/USTConverter.Wpf.csproj
Normal file
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\USTConverter\USTConverter.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Eto.Platform.Wpf" Version="2.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
366
USTConverter/USTConverter/MainForm.cs
Normal file
366
USTConverter/USTConverter/MainForm.cs
Normal file
|
@ -0,0 +1,366 @@
|
|||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
|
||||
using Eto.Forms;
|
||||
using Eto.Drawing;
|
||||
|
||||
namespace USTConverter
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
DropDown InputTypeSelector = new DropDown();
|
||||
DropDown OutputTypeSelector = new DropDown();
|
||||
TextBox FilePathTextBox = new TextBox();
|
||||
Button BrowseFileButton = new Button { Text = "Browse", Width = 100 };
|
||||
Button ConvertButton = new Button { Text = "Convert", Width = 100 };
|
||||
CheckBox CompressAudioCheckBox = new CheckBox { Text = "Compress Audio", Width = 100 };
|
||||
|
||||
string[] InputTypes = {
|
||||
"RSHW File (RR Engine)", "CSHW File (RR Engine)", "SSHW File (RR Engine)"/*,
|
||||
"3ST File (APS)", "ROA/R12/C&R File (APS)"*/
|
||||
};
|
||||
|
||||
string[] RAE3stOutputTypes = { "UST (Rock-afire Explosion/3-Stage)" , "UST (Cyberamics Rosetta)" };
|
||||
string[] CyberOutputTypes = { "UST (Cyberamics)" };
|
||||
string[] StudioCOutputTypes = { "UST (Studio C)" };
|
||||
|
||||
|
||||
int[] CyberBitMap = {
|
||||
1, 2, 3, 4, 8, 5, 6, 7,
|
||||
65, 66, 67, 68, 72, 69, 70, 71,
|
||||
49, 50, 51, 56, 53, 54, 55, 52,
|
||||
17, 18, 19, 20, 24, 21, 22, 23,
|
||||
33, 34, 35, 40, 37, 38, 39, 36,
|
||||
9, 46, 62, 10, 74, 75, 76, 77, 78,
|
||||
104, 102, 109, 107, 100, 123, 41,
|
||||
27, 28, 29, 30, 25, 26, 57, 58,
|
||||
120, 116, 127, 118, 117, 119,
|
||||
114, 113, 115,
|
||||
110, 108, 101, 106, 111,
|
||||
103, 105, 125, 121, 126, 99, 124, 122, 97, 98
|
||||
};
|
||||
|
||||
int[] CyberBitMapRosetta = {
|
||||
1, 6, 7, 8, 4, 5, 2, 19,
|
||||
185, 178, 179, 180, 183, 184, 181, 169,
|
||||
45, 54, 55, 43, 44, 41, 58, 59,
|
||||
166, 156, 157, 158, 156, 157, 151, 163,
|
||||
30, 25, 21, 28, 29, 26, 31, 35,
|
||||
0, 0, 0, 49, 0, 0, 0, 0, 0,
|
||||
88, 86, 85, 82, 84, 81, 0,
|
||||
93, 94, 91, 92, 91, 92, 0, 0,
|
||||
229, 228, 226, 224, 223, 221,
|
||||
235, 232, 234,
|
||||
67, 68, 71, 72, 73,
|
||||
220, 244, 245, 225, 77, 241, 240, 87, 222, 0
|
||||
};
|
||||
|
||||
int[] RAE3stBitMap = {
|
||||
1, 9, 10, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 17, 18, 19, 14, 15, 16, 20, 36, 37,
|
||||
185, 176, 177, 181, 182, 183, 184, 178, 179, 180, 173, 175, 174, 168, 170, 169, 186, 187, 188,
|
||||
45, 41, 42, 43, 44, 54, 55, 51, 52, 53, 57, 59, 58, 60, 61, 62,
|
||||
166, 151, 152, 153, 156, 157, 158, 161, 162, 163, 164, 154, 155, 159, 160, 165,
|
||||
30, 23, 24, 26, 27, 28, 29, 25, 21, 22, 33, 35, 34, 31, 32, 63, 64,
|
||||
196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 189, 190, 194, 211, 212, 213,
|
||||
167, 191, 192, 193, 171, 172, 48,
|
||||
39, 38, 47, 46, 49, 50,
|
||||
88, 86, 85, 82, 242, 84, 83, 81, 238, 239, 240, 87,
|
||||
93, 94, 91, 92, 89, 90,
|
||||
229, 228, 227, 226, 224, 223, 221, 219, 218, 217, 216, 222,
|
||||
235, 232, 231, 234, 236, 237, 233, 242, 243,
|
||||
67, 68, 69, 66, 71, 72, 73,
|
||||
78, 77, 76, 79, 80,
|
||||
220, 244, 245, 225, 230, 241
|
||||
};
|
||||
|
||||
int[] StudioCBitMap = {
|
||||
21, 28, 25, 24, 26, 27, 29, 30, 31, 18, 19, 23, 22, 20, 6, 7, 11, 8, 9, 10, 1, 2, 17, 3, 4, 5, 12, 16, 15, 13, 14, 32,
|
||||
33, 36, 34, 35, 40, 160, 161,
|
||||
177, 178,
|
||||
44, 45,
|
||||
151, 154, 152, 153, 155, 157, 156, 181, 180, 182,
|
||||
172, 174, 173, 171,
|
||||
166, 165, 164,
|
||||
159, 163, 167, 168, 176, 169, 170, 162, 179
|
||||
};
|
||||
|
||||
int[] CyberRosettaInvertedBits = { 2, 181, 41, 59, 58, 151, 163, 26, 35, 31 };
|
||||
int[] RAE3stAPSDescrambleTable = { 10, 11, 0, 1, 2, 3, 4, 12, 13, 5, 6, 7, 8, 9, 14, 15};
|
||||
|
||||
bool FullStage = false;
|
||||
bool Rosetta = false;
|
||||
const int USTVersion = 2;
|
||||
|
||||
public MainForm()
|
||||
{
|
||||
Title = "UST Showtape Converter";
|
||||
Size = new Size(500, 300);
|
||||
Maximizable = false;
|
||||
Resizable = false;
|
||||
|
||||
BrowseFileButton.Command = new Command((sender, e) => { Event_BrowseFileButton(); });
|
||||
ConvertButton.Command = new Command((sender, e) => { Event_ConvertFileButton(); });
|
||||
|
||||
InputTypeSelector.SelectedValueChanged += (sender, e) => Event_ChangeInputType();
|
||||
|
||||
foreach (string s in InputTypes)
|
||||
{
|
||||
InputTypeSelector.Items.Add(s);
|
||||
}
|
||||
|
||||
Content = BuildLayout();
|
||||
}
|
||||
|
||||
DynamicLayout BuildLayout()
|
||||
{
|
||||
DynamicLayout layout = new DynamicLayout { DefaultSpacing = new Size(10, 10), DefaultPadding = new Padding(5, 5, 5, 5) };
|
||||
|
||||
layout.BeginVertical();
|
||||
layout.BeginHorizontal();
|
||||
layout.Add(new Label { Text = "Input Format" });
|
||||
layout.EndHorizontal();
|
||||
|
||||
layout.BeginHorizontal();
|
||||
layout.Add(InputTypeSelector, true);
|
||||
layout.EndHorizontal();
|
||||
|
||||
layout.BeginHorizontal();
|
||||
layout.Add(new Label { Text = "Output Type" });
|
||||
layout.EndHorizontal();
|
||||
|
||||
layout.BeginHorizontal();
|
||||
layout.Add(OutputTypeSelector, true);
|
||||
layout.EndHorizontal();
|
||||
layout.EndVertical();
|
||||
|
||||
layout.BeginVertical();
|
||||
layout.BeginHorizontal();
|
||||
layout.Add(new Label { Text = "File to convert" });
|
||||
layout.EndHorizontal();
|
||||
|
||||
layout.BeginHorizontal();
|
||||
layout.Add(FilePathTextBox, true);
|
||||
layout.Add(BrowseFileButton);
|
||||
layout.EndHorizontal();
|
||||
layout.EndVertical();
|
||||
|
||||
layout.BeginVertical();
|
||||
layout.BeginHorizontal();
|
||||
layout.Add(null, true);
|
||||
layout.Add(CompressAudioCheckBox);
|
||||
layout.Add(ConvertButton);
|
||||
layout.EndHorizontal();
|
||||
layout.EndVertical();
|
||||
|
||||
layout.BeginVertical();
|
||||
layout.Add(null, true);
|
||||
layout.EndVertical();
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
string MakeHeader(string showName, string outputType)
|
||||
{
|
||||
string headerOut = $"UST,{USTVersion.ToString()},{showName.Replace(",", "_").Replace(";", "_")},";
|
||||
switch (outputType)
|
||||
{
|
||||
case "UST (Rock-afire Explosion/3-Stage)":
|
||||
headerOut += "Rockafire Explosion/3-Stage;";
|
||||
break;
|
||||
case "UST (Cyberamics Rosetta)":
|
||||
headerOut += "Cyberamics;";
|
||||
break;
|
||||
case "UST (Cyberamics)":
|
||||
headerOut += "Cyberamics;";
|
||||
break;
|
||||
case "UST (Studio C)":
|
||||
headerOut += "Studio C;";
|
||||
break;
|
||||
}
|
||||
return headerOut;
|
||||
}
|
||||
|
||||
void Event_ChangeInputType()
|
||||
{
|
||||
switch(InputTypeSelector.SelectedIndex)
|
||||
{
|
||||
case 0:
|
||||
OutputTypeSelector.Items.Clear();
|
||||
foreach (string s in RAE3stOutputTypes)
|
||||
{
|
||||
OutputTypeSelector.Items.Add(s);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
OutputTypeSelector.Items.Clear();
|
||||
foreach (string s in CyberOutputTypes)
|
||||
{
|
||||
OutputTypeSelector.Items.Add(s);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
OutputTypeSelector.Items.Clear();
|
||||
foreach (string s in StudioCOutputTypes)
|
||||
{
|
||||
OutputTypeSelector.Items.Add(s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Event_BrowseFileButton()
|
||||
{
|
||||
OpenFileDialog fileDialog = new OpenFileDialog();
|
||||
string[] showFiles = { ".rshw", ".cshw", ".sshw" };
|
||||
string[] allFiles = { ".*" };
|
||||
fileDialog.Filters.Add(new FileFilter("Show Files (.rshw, .cshw, .sshw)", showFiles));
|
||||
fileDialog.Filters.Add(new FileFilter("All Files", allFiles));
|
||||
fileDialog.Title = "Select Show File.";
|
||||
fileDialog.ShowDialog(this);
|
||||
if (File.Exists(fileDialog.FileName)) FilePathTextBox.Text = fileDialog.FileName;
|
||||
}
|
||||
|
||||
void Event_ConvertFileButton()
|
||||
{
|
||||
// safeties
|
||||
if (InputTypeSelector.SelectedIndex == -1)
|
||||
{
|
||||
MessageBox.Show("Fatal: You must select an input type.");
|
||||
return;
|
||||
}
|
||||
if (OutputTypeSelector.SelectedIndex == -1)
|
||||
{
|
||||
MessageBox.Show("Fatal: You must select an output type.");
|
||||
return;
|
||||
}
|
||||
if (FilePathTextBox.Text.Trim() == "")
|
||||
{
|
||||
MessageBox.Show("Fatal: You must select an input file.");
|
||||
return;
|
||||
}
|
||||
if (!File.Exists(FilePathTextBox.Text.Trim()))
|
||||
{
|
||||
MessageBox.Show("Fatal: Specified input file does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
SaveFileDialog fileDialog = new SaveFileDialog();
|
||||
fileDialog.Filters.Add(new FileFilter("UST Files (.ust)", new string[]{".ust"}));
|
||||
fileDialog.Title = "Select Show File.";
|
||||
fileDialog.ShowDialog(this);
|
||||
if (fileDialog.FileName.Trim() == "") return;
|
||||
string outFilePath = fileDialog.FileName;
|
||||
|
||||
// now its actually time to start doing some shit
|
||||
string inputType = InputTypeSelector.SelectedKey;
|
||||
string outputType = OutputTypeSelector.SelectedKey;
|
||||
string filePath = FilePathTextBox.Text.Trim();
|
||||
if (inputType == "RSHW File (RR Engine)" || inputType == "CSHW File (RR Engine)" || inputType == "SSHW File (RR Engine)")
|
||||
{
|
||||
// at some point there should be a warning displayed if the input type does not match the file extension but i dont feel like doing that right now
|
||||
|
||||
// rshw time
|
||||
RSHWFile file = RSHWLoader.Load(filePath);
|
||||
if (file.signalData == null)
|
||||
{
|
||||
MessageBox.Show("Fatal: This file contains no signal data.");
|
||||
return;
|
||||
}
|
||||
if (file.audioData == null)
|
||||
{
|
||||
MessageBox.Show("Fatal: This file contains no audio data.");
|
||||
return;
|
||||
}
|
||||
|
||||
List<BitArray> rshwBits = new List<BitArray>();
|
||||
int countlength = 0;
|
||||
if (file.signalData[0] != 0)
|
||||
{
|
||||
countlength = 1;
|
||||
BitArray bit = new BitArray(300);
|
||||
rshwBits.Add(bit);
|
||||
}
|
||||
for (int i = 0; i < file.signalData.Length; i++)
|
||||
{
|
||||
if (file.signalData[i] == 0)
|
||||
{
|
||||
countlength += 1;
|
||||
BitArray bit = new BitArray(300);
|
||||
rshwBits.Add(bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
rshwBits[countlength - 1].Set(file.signalData[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
// pick which target bits to use and how many bytes the output should be
|
||||
int bitsCount = 0;
|
||||
int[] targetBits = { 0 };
|
||||
switch (outputType)
|
||||
{
|
||||
case "UST (Rock-afire Explosion/3-Stage)":
|
||||
bitsCount = 256;
|
||||
targetBits = RAE3stBitMap;
|
||||
break;
|
||||
case "UST (Cyberamics Rosetta)":
|
||||
bitsCount = 256;
|
||||
targetBits = CyberBitMapRosetta;
|
||||
Rosetta = true;
|
||||
break;
|
||||
case "UST (Cyberamics)":
|
||||
bitsCount = 256;
|
||||
targetBits = CyberBitMap;
|
||||
break;
|
||||
case "UST (Studio C)":
|
||||
bitsCount = 256;
|
||||
targetBits = StudioCBitMap;
|
||||
break;
|
||||
}
|
||||
|
||||
List<string> writeOut = new List<string>();
|
||||
foreach (BitArray bits in rshwBits)
|
||||
{
|
||||
BigInteger frameByte = 0;
|
||||
for (int i = 0; i < targetBits.Length; i++)
|
||||
{
|
||||
if (Rosetta && CyberRosettaInvertedBits.Contains(targetBits[i]))
|
||||
{
|
||||
if (!bits.Get(targetBits[i])) frameByte += BigInteger.Pow(2, i);
|
||||
}
|
||||
else { if (bits.Get(targetBits[i])) frameByte += BigInteger.Pow(2, i); }
|
||||
}
|
||||
writeOut.Add(frameByte.ToString($"X{(bitsCount/4).ToString()}"));
|
||||
}
|
||||
writeOut[0] = (0).ToString($"X{(bitsCount/4).ToString()}");
|
||||
|
||||
byte[] audioOut = file.audioData;
|
||||
if ((bool)CompressAudioCheckBox.Checked)
|
||||
{
|
||||
if (File.Exists("tmp.mp3")) File.Delete("tmp.mp3");
|
||||
File.WriteAllBytes("tmp.wav", audioOut);
|
||||
Process ffmpegProcess = new Process();
|
||||
ffmpegProcess.StartInfo.FileName = "ffmpeg";
|
||||
ffmpegProcess.StartInfo.Arguments = "-i tmp.wav -c:a mp3 -b:a 128k tmp.mp3";
|
||||
ffmpegProcess.Start();
|
||||
ffmpegProcess.WaitForExit();
|
||||
audioOut = File.ReadAllBytes("tmp.mp3");
|
||||
File.Delete("tmp.wav");
|
||||
File.Delete("tmp.mp3");
|
||||
}
|
||||
|
||||
File.WriteAllText(outFilePath, MakeHeader(Path.GetFileNameWithoutExtension(outFilePath), outputType)+String.Join(",", writeOut.ToArray())+";"+Convert.ToBase64String(audioOut));
|
||||
}
|
||||
MessageBox.Show("Conversion complete!");
|
||||
}
|
||||
|
||||
int RRtoAPSBit(int rrBit) // aps lower drawer starts at 129 instead of 151
|
||||
{
|
||||
int outAPSBit = rrBit;
|
||||
if (rrBit > 150) outAPSBit = rrBit - 22;
|
||||
return outAPSBit;
|
||||
}
|
||||
}
|
||||
}
|
30
USTConverter/USTConverter/RSHWFile.cs
Normal file
30
USTConverter/USTConverter/RSHWFile.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
sealed class AntiUnityBinder : System.Runtime.Serialization.SerializationBinder
|
||||
{
|
||||
public override Type BindToType(string assemblyName, string typeName)
|
||||
{
|
||||
return Type.GetType(String.Format("RSHWFile, " + Assembly.GetExecutingAssembly().FullName));
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class RSHWFile
|
||||
{
|
||||
public byte[]? audioData { get; set; }
|
||||
public int[]? signalData { get; set; }
|
||||
public byte[]? videoData { get; set; }
|
||||
}
|
||||
|
||||
public class RSHWLoader
|
||||
{
|
||||
public static RSHWFile Load(string path)
|
||||
{
|
||||
BinaryFormatter formatter = new BinaryFormatter();
|
||||
formatter.Binder = new AntiUnityBinder();
|
||||
FileStream stream = File.OpenRead(path);
|
||||
return (RSHWFile)formatter.Deserialize(stream);
|
||||
}
|
||||
}
|
||||
|
14
USTConverter/USTConverter/USTConverter.csproj
Normal file
14
USTConverter/USTConverter/USTConverter.csproj
Normal file
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Eto.Forms" Version="2.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
Loading…
Add table
Add a link
Reference in a new issue