This commit is contained in:
parent
312afabfdc
commit
4eb2d47adf
6 changed files with 422 additions and 18 deletions
|
@ -10,20 +10,7 @@
|
||||||
Title="Install Game"
|
Title="Install Game"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
Loaded="Control_OnLoaded"
|
Loaded="Control_OnLoaded"
|
||||||
Background="#201c29"
|
Background="#201c29">
|
||||||
SystemDecorations="None">
|
|
||||||
<Grid RowDefinitions="20, *">
|
|
||||||
<Grid Grid.Row="0">
|
|
||||||
<Border Background="#35313d"
|
|
||||||
PointerPressed="WindowDrag">
|
|
||||||
<Grid ColumnDefinitions="*, 20">
|
|
||||||
<TextBlock Name="WindowTitle" FontSize="12" Text="Install Game" Padding="8,0,0,0" VerticalAlignment="Center"/>
|
|
||||||
<Border Grid.Column="1" Background="#4b4753" PointerPressed="WindowClose">
|
|
||||||
<TextBlock FontSize="12" Text="×" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
|
||||||
</Border>
|
|
||||||
</Grid>
|
|
||||||
</Border>
|
|
||||||
</Grid>
|
|
||||||
<Grid Grid.Row="1" ColumnDefinitions="Auto,Auto,*" Margin="20">
|
<Grid Grid.Row="1" ColumnDefinitions="Auto,Auto,*" Margin="20">
|
||||||
<!-- PS2 Cover -->
|
<!-- PS2 Cover -->
|
||||||
<Border Width="205" Height="292" Background="Black" CornerRadius="5" HorizontalAlignment="Left"
|
<Border Width="205" Height="292" Background="Black" CornerRadius="5" HorizontalAlignment="Left"
|
||||||
|
@ -60,6 +47,4 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
|
||||||
|
|
||||||
</Window>
|
</Window>
|
||||||
|
|
31
PS2_Manager/ConvertGameWindow.axaml
Normal file
31
PS2_Manager/ConvertGameWindow.axaml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
x:Class="PS2_Manager.ConvertGameWindow"
|
||||||
|
Title="Convert BIN to ISO"
|
||||||
|
Height="349"
|
||||||
|
Width="598"
|
||||||
|
CanResize="False"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
Background="#201c29"
|
||||||
|
Loaded="Control_OnLoaded"
|
||||||
|
Closing="Window_OnClosing">
|
||||||
|
<Grid RowDefinitions="80, *, 80">
|
||||||
|
<TextBlock Name="Label_1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
|
<Border Grid.Row="1" CornerRadius="10" Background="#35313d" Margin="10, 0">
|
||||||
|
<Grid ColumnDefinitions="*,*,*">
|
||||||
|
<Border Grid.Column="0" Background="#201c29" Margin="10" CornerRadius="7">
|
||||||
|
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
|
||||||
|
<Border Grid.Column="2" Background="#201c29" Margin="10" CornerRadius="7">
|
||||||
|
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
<Button Click="ConvertButton_OnClick" Name="ConvertButton" Grid.Row="2" Content="Convert" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0"/>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
69
PS2_Manager/ConvertGameWindow.axaml.cs
Normal file
69
PS2_Manager/ConvertGameWindow.axaml.cs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.Threading;
|
||||||
|
using PS2_Manager.Core.IO.DiscImage;
|
||||||
|
using PS2_Manager.Core.IO.DiscImage.Type;
|
||||||
|
|
||||||
|
namespace PS2_Manager;
|
||||||
|
|
||||||
|
public partial class ConvertGameWindow : Window
|
||||||
|
{
|
||||||
|
public bool PreventClose { get; set; } = false;
|
||||||
|
public string binPath { get; set; }
|
||||||
|
public string isoPath { get; set; }
|
||||||
|
public BackgroundWorker Worker { get; set; }
|
||||||
|
public ConvertGameWindow(string path)
|
||||||
|
{
|
||||||
|
this.binPath = path;
|
||||||
|
this.isoPath = Path.ChangeExtension(path, ".iso");
|
||||||
|
InitializeComponent();
|
||||||
|
Worker = new BackgroundWorker();
|
||||||
|
Worker.RunWorkerCompleted += WorkerOnRunWorkerCompleted;
|
||||||
|
Worker.DoWork += WorkerOnDoWork;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WorkerOnDoWork(object? sender, DoWorkEventArgs e)
|
||||||
|
{
|
||||||
|
Console.Info("Worker has started");
|
||||||
|
Iso9660Conv conv = new Iso9660Conv();
|
||||||
|
conv.DiscImage = new BinType(this.binPath);
|
||||||
|
conv.Convert(this.isoPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WorkerOnRunWorkerCompleted(object? sender, RunWorkerCompletedEventArgs e)
|
||||||
|
{
|
||||||
|
Console.Info("File Converted");
|
||||||
|
OpenInstallWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenInstallWindow()
|
||||||
|
{
|
||||||
|
Console.Success("Converted Successfully");
|
||||||
|
this.PreventClose = false;
|
||||||
|
new AddGameWindow(this.isoPath).Show();
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Control_OnLoaded(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.Label_1.Text = Path.GetFileName(this.binPath) + " needs to be converted into a ISO file";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Window_OnClosing(object? sender, WindowClosingEventArgs e)
|
||||||
|
{
|
||||||
|
if(this.PreventClose)
|
||||||
|
e.Cancel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConvertButton_OnClick(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.PreventClose = true;
|
||||||
|
ConvertButton.Content = "Converting...";
|
||||||
|
Console.Warning("Converting " + this.binPath + " to ISO");
|
||||||
|
Worker.RunWorkerAsync();
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ public static class Globals
|
||||||
{
|
{
|
||||||
public static FilePickerFileType PS2Game { get; } = new("PS2 Game")
|
public static FilePickerFileType PS2Game { get; } = new("PS2 Game")
|
||||||
{
|
{
|
||||||
Patterns = new[] { "*.iso" }
|
Patterns = new[] { "*.iso", "*.bin" }
|
||||||
};
|
};
|
||||||
public static FilePickerFileType PS2Cover { get; } = new("PS2 Cover")
|
public static FilePickerFileType PS2Cover { get; } = new("PS2 Cover")
|
||||||
{
|
{
|
||||||
|
|
310
PS2_Manager/Core/IsoConverter.cs
Normal file
310
PS2_Manager/Core/IsoConverter.cs
Normal file
|
@ -0,0 +1,310 @@
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
namespace PS2_Manager.Core.IO.DiscImage.Type
|
||||||
|
{
|
||||||
|
public class BinType : IDiscImage
|
||||||
|
{
|
||||||
|
private SectorStructure _sector;
|
||||||
|
private string _imagePath;
|
||||||
|
|
||||||
|
public string ImagePath => this._imagePath;
|
||||||
|
|
||||||
|
public BinType(string imagePath)
|
||||||
|
{
|
||||||
|
this._imagePath = imagePath;
|
||||||
|
this._sector = new SectorStructure();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long FirstDumpSector() => 0;
|
||||||
|
|
||||||
|
public SectorStructure GetSectorStucture()
|
||||||
|
{
|
||||||
|
this._sector = new SectorStructure();
|
||||||
|
FileStream input = (FileStream) null;
|
||||||
|
BinaryReader binaryReader = (BinaryReader) null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
input = new FileStream(this._imagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
|
binaryReader = new BinaryReader((Stream) input);
|
||||||
|
byte[] numArray = new byte[16];
|
||||||
|
binaryReader.Read(numArray, 0, numArray.Length);
|
||||||
|
if (BytesHelper.CompareBytesArray(BytesHelper.CopyRange(numArray, 0, Iso9660Conv.SYNC_HEADER.Length), Iso9660Conv.SYNC_HEADER))
|
||||||
|
{
|
||||||
|
switch (numArray[15])
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
this._sector.sectorLength = 2352;
|
||||||
|
this._sector.userDataOffset = 16;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this._sector.sectorLength = 2352;
|
||||||
|
this._sector.userDataOffset = 24;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._sector.sectorLength = 2336;
|
||||||
|
this._sector.userDataOffset = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
binaryReader?.Close();
|
||||||
|
if (input != null)
|
||||||
|
{
|
||||||
|
input.Close();
|
||||||
|
input.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this._sector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace PS2_Manager.Core.IO.DiscImage
|
||||||
|
{
|
||||||
|
public interface IDiscImage
|
||||||
|
{
|
||||||
|
string ImagePath { get; }
|
||||||
|
|
||||||
|
long FirstDumpSector();
|
||||||
|
|
||||||
|
SectorStructure GetSectorStucture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace PS2_Manager.Core.IO.DiscImage
|
||||||
|
{
|
||||||
|
public struct SectorStructure(int length, int dataOffset)
|
||||||
|
{
|
||||||
|
public int sectorLength = length;
|
||||||
|
public int userDataOffset = dataOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
namespace PS2_Manager.Core.IO.DiscImage
|
||||||
|
{
|
||||||
|
public class Iso9660Conv
|
||||||
|
{
|
||||||
|
private const int ISO_SECTOR_SIZE = 2048;
|
||||||
|
private const int BUFFER_LENGTH_FACTOR = 64;
|
||||||
|
private const uint FAT32_DISK_LIMIT = 4294967295;
|
||||||
|
private SectorStructure _sectorStruct;
|
||||||
|
private long _startFirstSector;
|
||||||
|
private IDiscImage _discImage;
|
||||||
|
private FileStream _fsSrc = (FileStream) null;
|
||||||
|
private FileStream _fsDst = (FileStream) null;
|
||||||
|
private BinaryReader _brSrc = (BinaryReader) null;
|
||||||
|
private BinaryWriter _wrDst = (BinaryWriter) null;
|
||||||
|
internal static byte[] SYNC_HEADER = new byte[12]
|
||||||
|
{
|
||||||
|
(byte) 0,
|
||||||
|
byte.MaxValue,
|
||||||
|
byte.MaxValue,
|
||||||
|
byte.MaxValue,
|
||||||
|
byte.MaxValue,
|
||||||
|
byte.MaxValue,
|
||||||
|
byte.MaxValue,
|
||||||
|
byte.MaxValue,
|
||||||
|
byte.MaxValue,
|
||||||
|
byte.MaxValue,
|
||||||
|
byte.MaxValue,
|
||||||
|
(byte) 0
|
||||||
|
};
|
||||||
|
|
||||||
|
public event EventHandler<Iso9660CreatorEventArgs> Progression;
|
||||||
|
|
||||||
|
public event EventHandler Terminate;
|
||||||
|
|
||||||
|
public IDiscImage DiscImage
|
||||||
|
{
|
||||||
|
get => this._discImage;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this._discImage = value;
|
||||||
|
this.SetDiscImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iso9660Conv()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iso9660Conv(IDiscImage converter)
|
||||||
|
{
|
||||||
|
this._discImage = converter;
|
||||||
|
this.SetDiscImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
if (this._brSrc != null)
|
||||||
|
this._brSrc.Close();
|
||||||
|
if (this._wrDst != null)
|
||||||
|
this._wrDst.Close();
|
||||||
|
if (this._fsSrc != null)
|
||||||
|
{
|
||||||
|
this._fsSrc.Close();
|
||||||
|
this._fsSrc.Dispose();
|
||||||
|
}
|
||||||
|
if (this._fsDst == null)
|
||||||
|
return;
|
||||||
|
this._fsDst.Close();
|
||||||
|
this._fsDst.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Convert(IDiscImage discImage, string isoDestination)
|
||||||
|
{
|
||||||
|
this._discImage = discImage != null ? discImage : throw new ArgumentNullException(nameof (discImage), "The IDiscImage interface is null.");
|
||||||
|
this.SetDiscImage();
|
||||||
|
this.Convert(isoDestination);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Convert(string isoDestination)
|
||||||
|
{
|
||||||
|
if (this._discImage == null)
|
||||||
|
throw new ArgumentNullException("The IDiscImage interface is null. You can specified an instance from DiscImage propertie.");
|
||||||
|
if (isoDestination == string.Empty)
|
||||||
|
throw new ArgumentNullException("output", "The output file path must not be null.");
|
||||||
|
if (this._sectorStruct.sectorLength == 0)
|
||||||
|
throw new IOException("The source image file format is unknown.");
|
||||||
|
if (!File.Exists(this._discImage.ImagePath))
|
||||||
|
throw new FileNotFoundException("The souce image file does not exists.");
|
||||||
|
DriveInfo driveInfo = new DriveInfo(Path.GetPathRoot(isoDestination));
|
||||||
|
long num1 = new FileInfo(this._discImage.ImagePath).Length / (long) this._sectorStruct.sectorLength * 2048L - this._startFirstSector;
|
||||||
|
if (driveInfo.DriveFormat.Equals("FAT32") && num1 > (long) uint.MaxValue)
|
||||||
|
throw new IOException("Not enough space on FAT32 destination drive.");
|
||||||
|
if (driveInfo.TotalSize < num1)
|
||||||
|
throw new IOException("Not enough space on the destination drive.");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this._fsSrc = new FileStream(this._discImage.ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
|
this._brSrc = new BinaryReader((Stream) this._fsSrc);
|
||||||
|
this._fsDst = new FileStream(isoDestination, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||||
|
this._wrDst = new BinaryWriter((Stream) this._fsDst);
|
||||||
|
this._brSrc.BaseStream.Seek(this._startFirstSector, SeekOrigin.Begin);
|
||||||
|
byte[] numArray = new byte[this._sectorStruct.sectorLength * 64];
|
||||||
|
int num2;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
num2 = this._brSrc.Read(numArray, 0, numArray.Length);
|
||||||
|
if (num2 == this._sectorStruct.sectorLength * 64)
|
||||||
|
this._wrDst.Write(this.CleanUserDataBuffer(numArray, 131072U));
|
||||||
|
else if (num2 > 0)
|
||||||
|
{
|
||||||
|
uint uint32 = System.Convert.ToUInt32(num2 / this._sectorStruct.sectorLength * 2048);
|
||||||
|
this._wrDst.Write(this.CleanUserDataBuffer(numArray, uint32));
|
||||||
|
}
|
||||||
|
if (this.Progression != null)
|
||||||
|
this.Progression((object) null, new Iso9660CreatorEventArgs(this._wrDst.BaseStream.Position, this._brSrc.BaseStream.Length));
|
||||||
|
}
|
||||||
|
while (num2 > 0 && this._wrDst.BaseStream.Position != num1);
|
||||||
|
if (this.Terminate == null)
|
||||||
|
return;
|
||||||
|
this.Terminate((object) null, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception(ex.Message, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] CleanUserDataBuffer(byte[] source, uint dataSize)
|
||||||
|
{
|
||||||
|
byte[] dst = new byte[(int) dataSize];
|
||||||
|
int num = 0;
|
||||||
|
for (int index = 0; (long) index < (long) dataSize; index += 2048)
|
||||||
|
{
|
||||||
|
if ((long) dataSize - (long) index >= 2048L)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy((Array) source, num * this._sectorStruct.sectorLength + this._sectorStruct.userDataOffset, (Array) dst, num * 2048, 2048);
|
||||||
|
++num;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Buffer.BlockCopy((Array) source, this._sectorStruct.sectorLength * num + this._sectorStruct.userDataOffset, (Array) dst, num * 2048, (int) ((long) dataSize - (long) index));
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetDiscImage()
|
||||||
|
{
|
||||||
|
this._sectorStruct = this._discImage.GetSectorStucture();
|
||||||
|
this._startFirstSector = this._discImage.FirstDumpSector();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
namespace PS2_Manager.Core
|
||||||
|
{
|
||||||
|
internal static class BytesHelper
|
||||||
|
{
|
||||||
|
public static bool CompareBytesArray(byte[] a, byte[] b)
|
||||||
|
{
|
||||||
|
if (a == null || b == null || a.Length != b.Length)
|
||||||
|
return false;
|
||||||
|
for (int index = 0; index < a.Length; ++index)
|
||||||
|
{
|
||||||
|
if ((int) a[index] != (int) b[index])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] CopyRange(byte[] source, int srcOffset, int length)
|
||||||
|
{
|
||||||
|
byte[] dst = new byte[length];
|
||||||
|
if (source.Length < length)
|
||||||
|
return (byte[]) null;
|
||||||
|
Buffer.BlockCopy((Array) source, srcOffset, (Array) dst, 0, dst.Length);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
namespace PS2_Manager.Core.IO.DiscImage
|
||||||
|
{
|
||||||
|
public class Iso9660CreatorEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
private long _bytesWritted;
|
||||||
|
private long _discLength;
|
||||||
|
|
||||||
|
public long DiscLength => this._discLength;
|
||||||
|
|
||||||
|
public long BytesWritted => this._bytesWritted;
|
||||||
|
|
||||||
|
public Iso9660CreatorEventArgs()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iso9660CreatorEventArgs(long writted, long discLength)
|
||||||
|
{
|
||||||
|
this._bytesWritted = writted;
|
||||||
|
this._discLength = discLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,16 @@ public partial class MainWindow : Window
|
||||||
if (files.Count >= 1)
|
if (files.Count >= 1)
|
||||||
{
|
{
|
||||||
Console.Info("AddGameWindow was called for " + files[0].Path.LocalPath);
|
Console.Info("AddGameWindow was called for " + files[0].Path.LocalPath);
|
||||||
new AddGameWindow(files[0].Path.LocalPath).Show();
|
string ext = Path.GetExtension(files[0].Path.LocalPath);
|
||||||
|
if (ext == ".bin")
|
||||||
|
{
|
||||||
|
new ConvertGameWindow(files[0].Path.LocalPath).Show();
|
||||||
|
}
|
||||||
|
else if (ext == ".iso")
|
||||||
|
{
|
||||||
|
new AddGameWindow(files[0].Path.LocalPath).Show();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue