diff --git a/.gitignore b/.gitignore
index ac6b652..77208fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -62,3 +62,9 @@ fastlane/screenshots/**/*.png
fastlane/test_output
**/.DS_Store
+*.suo
+*.user
+.vs
+bin
+obj
+packages
diff --git a/Windows/PS Classics fPKG Builder.sln b/Windows/PS Classics fPKG Builder.sln
new file mode 100644
index 0000000..9121555
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.10.35122.118
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "PS Classics fPKG Builder", "PS Classics fPKG Builder\PS Classics fPKG Builder.vbproj", "{39038E46-FDF1-4E8E-9524-427F8B5A7BD2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {39038E46-FDF1-4E8E-9524-427F8B5A7BD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {39038E46-FDF1-4E8E-9524-427F8B5A7BD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {39038E46-FDF1-4E8E-9524-427F8B5A7BD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {39038E46-FDF1-4E8E-9524-427F8B5A7BD2}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {09F10D6B-375A-41E1-9C86-04D9BABC2310}
+ EndGlobalSection
+EndGlobal
diff --git a/Windows/PS Classics fPKG Builder/App.config b/Windows/PS Classics fPKG Builder/App.config
new file mode 100644
index 0000000..aee9adf
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Windows/PS Classics fPKG Builder/Application.xaml b/Windows/PS Classics fPKG Builder/Application.xaml
new file mode 100644
index 0000000..2268017
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/Application.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/Windows/PS Classics fPKG Builder/Application.xaml.vb b/Windows/PS Classics fPKG Builder/Application.xaml.vb
new file mode 100644
index 0000000..084cbe9
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/Application.xaml.vb
@@ -0,0 +1,6 @@
+Class Application
+
+ ' Application-level events, such as Startup, Exit, and DispatcherUnhandledException
+ ' can be handled in this file.
+
+End Class
diff --git a/Windows/PS Classics fPKG Builder/My Project/AssemblyInfo.vb b/Windows/PS Classics fPKG Builder/My Project/AssemblyInfo.vb
new file mode 100644
index 0000000..003309a
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/My Project/AssemblyInfo.vb
@@ -0,0 +1,59 @@
+Imports System
+Imports System.Globalization
+Imports System.Reflection
+Imports System.Resources
+Imports System.Runtime.InteropServices
+Imports System.Windows
+
+' General Information about an assembly is controlled through the following
+' set of attributes. Change these attribute values to modify the information
+' associated with an assembly.
+
+' Review the values of the assembly attributes
+
+
+
+
+
+
+
+
+
+'In order to begin building localizable applications, set
+'CultureYouAreCodingWith in your .vbproj file
+'inside a . For example, if you are using US english
+'in your source files, set the to "en-US". Then uncomment the
+'NeutralResourceLanguage attribute below. Update the "en-US" in the line
+'below to match the UICulture setting in the project file.
+
+'
+
+
+'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found.
+'1st parameter: where theme specific resource dictionaries are located
+'(used if a resource is not found in the page,
+' or application resource dictionaries)
+
+'2nd parameter: where the generic resource dictionary is located
+'(used if a resource is not found in the page,
+'app, and any theme specific resource dictionaries)
+
+
+
+
+'The following GUID is for the ID of the typelib if this project is exposed to COM
+
+
+' Version information for an assembly consists of the following four values:
+'
+' Major Version
+' Minor Version
+' Build Number
+' Revision
+'
+' You can specify all the values or you can default the Build and Revision Numbers
+' by using the '*' as shown below:
+'
+
+
+
diff --git a/Windows/PS Classics fPKG Builder/My Project/MyExtensions/MyWpfExtension.vb b/Windows/PS Classics fPKG Builder/My Project/MyExtensions/MyWpfExtension.vb
new file mode 100644
index 0000000..22f84b7
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/My Project/MyExtensions/MyWpfExtension.vb
@@ -0,0 +1,121 @@
+#If _MyType <> "Empty" Then
+
+Namespace My
+ '''
+ ''' Module used to define the properties that are available in the My Namespace for WPF
+ '''
+ '''
+ _
+ Module MyWpfExtension
+ Private s_Computer As New ThreadSafeObjectProvider(Of Global.Microsoft.VisualBasic.Devices.Computer)
+ Private s_User As New ThreadSafeObjectProvider(Of Global.Microsoft.VisualBasic.ApplicationServices.User)
+ Private s_Windows As New ThreadSafeObjectProvider(Of MyWindows)
+ Private s_Log As New ThreadSafeObjectProvider(Of Global.Microsoft.VisualBasic.Logging.Log)
+ '''
+ ''' Returns the application object for the running application
+ '''
+ _
+ Friend ReadOnly Property Application() As Application
+ Get
+ Return CType(Global.System.Windows.Application.Current, Application)
+ End Get
+ End Property
+ '''
+ ''' Returns information about the host computer.
+ '''
+ _
+ Friend ReadOnly Property Computer() As Global.Microsoft.VisualBasic.Devices.Computer
+ Get
+ Return s_Computer.GetInstance()
+ End Get
+ End Property
+ '''
+ ''' Returns information for the current user. If you wish to run the application with the current
+ ''' Windows user credentials, call My.User.InitializeWithWindowsUser().
+ '''
+ _
+ Friend ReadOnly Property User() As Global.Microsoft.VisualBasic.ApplicationServices.User
+ Get
+ Return s_User.GetInstance()
+ End Get
+ End Property
+ '''
+ ''' Returns the application log. The listeners can be configured by the application's configuration file.
+ '''
+ _
+ Friend ReadOnly Property Log() As Global.Microsoft.VisualBasic.Logging.Log
+ Get
+ Return s_Log.GetInstance()
+ End Get
+ End Property
+
+ '''
+ ''' Returns the collection of Windows defined in the project.
+ '''
+ _
+ Friend ReadOnly Property Windows() As MyWindows
+ _
+ Get
+ Return s_Windows.GetInstance()
+ End Get
+ End Property
+ _
+ _
+ Friend NotInheritable Class MyWindows
+ _
+ Private Shared Function Create__Instance__(Of T As {New, Global.System.Windows.Window})(ByVal Instance As T) As T
+ If Instance Is Nothing Then
+ If s_WindowBeingCreated IsNot Nothing Then
+ If s_WindowBeingCreated.ContainsKey(GetType(T)) = True Then
+ Throw New Global.System.InvalidOperationException("The window cannot be accessed via My.Windows from the Window constructor.")
+ End If
+ Else
+ s_WindowBeingCreated = New Global.System.Collections.Hashtable()
+ End If
+ s_WindowBeingCreated.Add(GetType(T), Nothing)
+ Return New T()
+ s_WindowBeingCreated.Remove(GetType(T))
+ Else
+ Return Instance
+ End If
+ End Function
+ _
+ _
+ Private Sub Dispose__Instance__(Of T As Global.System.Windows.Window)(ByRef instance As T)
+ instance = Nothing
+ End Sub
+ _
+ _
+ Public Sub New()
+ MyBase.New()
+ End Sub
+ Private Shared s_WindowBeingCreated As Global.System.Collections.Hashtable
+ Public Overrides Function Equals(ByVal o As Object) As Boolean
+ Return MyBase.Equals(o)
+ End Function
+ Public Overrides Function GetHashCode() As Integer
+ Return MyBase.GetHashCode
+ End Function
+ _
+ _
+ Friend Overloads Function [GetType]() As Global.System.Type
+ Return GetType(MyWindows)
+ End Function
+ Public Overrides Function ToString() As String
+ Return MyBase.ToString
+ End Function
+ End Class
+ End Module
+End Namespace
+Partial Class Application
+ Inherits Global.System.Windows.Application
+ _
+ _
+ Friend ReadOnly Property Info() As Global.Microsoft.VisualBasic.ApplicationServices.AssemblyInfo
+ _
+ Get
+ Return New Global.Microsoft.VisualBasic.ApplicationServices.AssemblyInfo(Global.System.Reflection.Assembly.GetExecutingAssembly())
+ End Get
+ End Property
+End Class
+#End If
\ No newline at end of file
diff --git a/Windows/PS Classics fPKG Builder/My Project/Resources.Designer.vb b/Windows/PS Classics fPKG Builder/My Project/Resources.Designer.vb
new file mode 100644
index 0000000..e7ecddc
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/My Project/Resources.Designer.vb
@@ -0,0 +1,62 @@
+'------------------------------------------------------------------------------
+'
+' This code was generated by a tool.
+' Runtime Version:$clrversion$
+'
+' Changes to this file may cause incorrect behavior and will be lost if
+' the code is regenerated.
+'
+'------------------------------------------------------------------------------
+
+Option Strict On
+Option Explicit On
+
+
+Namespace My.Resources
+
+ 'This class was auto-generated by the StronglyTypedResourceBuilder
+ 'class via a tool like ResGen or Visual Studio.
+ 'To add or remove a member, edit your .ResX file then rerun ResGen
+ 'with the /str option, or rebuild your VS project.
+ '''
+ ''' A strongly-typed resource class, for looking up localized strings, etc.
+ '''
+ _
+ Friend Module Resources
+
+ Private resourceMan As Global.System.Resources.ResourceManager
+
+ Private resourceCulture As Global.System.Globalization.CultureInfo
+
+ '''
+ ''' Returns the cached ResourceManager instance used by this class.
+ '''
+ _
+ Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
+ Get
+ If Object.ReferenceEquals(resourceMan, Nothing) Then
+ Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("$safeprojectname$.Resources", GetType(Resources).Assembly)
+ resourceMan = temp
+ End If
+ Return resourceMan
+ End Get
+ End Property
+
+ '''
+ ''' Overrides the current thread's CurrentUICulture property for all
+ ''' resource lookups using this strongly typed resource class.
+ '''
+ _
+ Friend Property Culture() As Global.System.Globalization.CultureInfo
+ Get
+ Return resourceCulture
+ End Get
+ Set(ByVal value As Global.System.Globalization.CultureInfo)
+ resourceCulture = value
+ End Set
+ End Property
+ End Module
+End Namespace
diff --git a/Windows/PS Classics fPKG Builder/My Project/Resources.resx b/Windows/PS Classics fPKG Builder/My Project/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/My Project/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Windows/PS Classics fPKG Builder/My Project/Settings.Designer.vb b/Windows/PS Classics fPKG Builder/My Project/Settings.Designer.vb
new file mode 100644
index 0000000..cb87530
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/My Project/Settings.Designer.vb
@@ -0,0 +1,73 @@
+'------------------------------------------------------------------------------
+'
+' This code was generated by a tool.
+' Runtime Version:4.0.30319.42000
+'
+' Changes to this file may cause incorrect behavior and will be lost if
+' the code is regenerated.
+'
+'------------------------------------------------------------------------------
+
+Option Strict On
+Option Explicit On
+
+
+Namespace My
+
+ _
+ Partial Friend NotInheritable Class MySettings
+ Inherits Global.System.Configuration.ApplicationSettingsBase
+
+ Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings)
+
+#Region "My.Settings Auto-Save Functionality"
+#If _MyType = "WindowsForms" Then
+ Private Shared addedHandler As Boolean
+
+ Private Shared addedHandlerLockObject As New Object
+
+ _
+ Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs)
+ If My.Application.SaveMySettingsOnExit Then
+ My.Settings.Save()
+ End If
+ End Sub
+#End If
+#End Region
+
+ Public Shared ReadOnly Property [Default]() As MySettings
+ Get
+
+#If _MyType = "WindowsForms" Then
+ If Not addedHandler Then
+ SyncLock addedHandlerLockObject
+ If Not addedHandler Then
+ AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
+ addedHandler = True
+ End If
+ End SyncLock
+ End If
+#End If
+ Return defaultInstance
+ End Get
+ End Property
+ End Class
+End Namespace
+
+Namespace My
+
+ _
+ Friend Module MySettingsProperty
+
+ _
+ Friend ReadOnly Property Settings() As Global.PS_Classics_fPKG_Builder.My.MySettings
+ Get
+ Return Global.PS_Classics_fPKG_Builder.My.MySettings.Default
+ End Get
+ End Property
+ End Module
+End Namespace
diff --git a/Windows/PS Classics fPKG Builder/My Project/Settings.settings b/Windows/PS Classics fPKG Builder/My Project/Settings.settings
new file mode 100644
index 0000000..40ed9fd
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/My Project/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Windows/PS Classics fPKG Builder/PS Classics fPKG Builder.vbproj b/Windows/PS Classics fPKG Builder/PS Classics fPKG Builder.vbproj
new file mode 100644
index 0000000..18a5e3b
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/PS Classics fPKG Builder.vbproj
@@ -0,0 +1,163 @@
+
+
+
+ Debug
+ AnyCPU
+ {39038E46-FDF1-4E8E-9524-427F8B5A7BD2}
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}
+ WinExe
+ PS_Classics_fPKG_Builder
+ PS Classics fPKG Builder
+ v4.8.1
+ Custom
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ true
+ true
+ true
+ bin\Debug\
+ PS Classics fPKG Builder.xml
+ 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314
+ false
+
+
+ AnyCPU
+ pdbonly
+ false
+ false
+ true
+ false
+ true
+ bin\Release\
+ PS Classics fPKG Builder.xml
+ 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036,42314
+ false
+
+
+ On
+
+
+ Binary
+
+
+ Off
+
+
+ On
+
+
+ v14Icon.ico
+
+
+
+ ..\packages\DiscUtils.Core.0.16.13\lib\net45\DiscUtils.Core.dll
+
+
+ ..\packages\DiscUtils.Iso9660.0.16.13\lib\net45\DiscUtils.Iso9660.dll
+
+
+ ..\packages\DiscUtils.Streams.0.16.13\lib\net45\DiscUtils.Streams.dll
+
+
+ ..\packages\DiscUtils.Udf.0.16.13\lib\net45\DiscUtils.Udf.dll
+
+
+ ..\..\..\..\Desktop\Classics\PS2\LibOrbisPkg.dll
+
+
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+
+ PSClassicsfPKGBuilder.xaml
+
+
+ Application.xaml
+ Code
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Code
+
+
+ Microsoft.VisualBasic.WPF.MyExtension
+ 1.0.0.0
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+ VbMyResourcesResXFileCodeGenerator
+ Resources.Designer.vb
+ My.Resources
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.vb
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Windows/PS Classics fPKG Builder/PS1Game.vb b/Windows/PS Classics fPKG Builder/PS1Game.vb
new file mode 100644
index 0000000..55b4bb9
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/PS1Game.vb
@@ -0,0 +1,35 @@
+Imports System.IO
+
+Public Class PS1Game
+
+ Public Shared Function GetPS1GameTitleFromDatabaseList(GameID As String) As String
+ Dim FoundGameTitle As String = ""
+
+ For Each GameTitle As String In File.ReadLines(My.Computer.FileSystem.CurrentDirectory + "\Tools\ps1ids.txt")
+ If GameTitle.Contains(GameID) Then
+ FoundGameTitle = GameTitle.Split(";"c)(1)
+ Exit For
+ End If
+ Next
+
+ If String.IsNullOrEmpty(FoundGameTitle) Then
+ Return ""
+ Else
+ Return FoundGameTitle
+ End If
+ End Function
+
+ Public Shared Function IsGameProtected(GameID As String) As String
+ Dim FoundValue As String = ""
+
+ For Each GameIDInFile As String In File.ReadLines(My.Computer.FileSystem.CurrentDirectory + "\Tools\libcrypt.txt")
+ If GameIDInFile.Contains(GameID) Then
+ FoundValue = GameIDInFile.Split(" "c)(1)
+ Exit For
+ End If
+ Next
+
+ Return FoundValue
+ End Function
+
+End Class
diff --git a/Windows/PS Classics fPKG Builder/PS2Game.vb b/Windows/PS Classics fPKG Builder/PS2Game.vb
new file mode 100644
index 0000000..669b3c0
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/PS2Game.vb
@@ -0,0 +1,61 @@
+Imports System.IO
+
+Public Class PS2Game
+
+ Public Shared Function GetPS2GameID(GameISO As String) As String
+ Dim GameID As String = ""
+
+ Using SevenZip As New Process()
+ SevenZip.StartInfo.FileName = My.Computer.FileSystem.CurrentDirectory + "\Tools\7z.exe"
+ SevenZip.StartInfo.Arguments = "l -ba """ + GameISO + """"
+ SevenZip.StartInfo.RedirectStandardOutput = True
+ SevenZip.StartInfo.UseShellExecute = False
+ SevenZip.StartInfo.CreateNoWindow = True
+ SevenZip.Start()
+
+ 'Read the output
+ Dim OutputReader As StreamReader = SevenZip.StandardOutput
+ Dim ProcessOutput As String() = OutputReader.ReadToEnd().Split(New String() {vbCrLf}, StringSplitOptions.None)
+
+ If ProcessOutput.Length > 0 Then
+ For Each Line As String In ProcessOutput
+ If Line.Contains("SLES_") Or Line.Contains("SLUS_") Or Line.Contains("SCES_") Or Line.Contains("SCUS_") Then
+ If Line.Contains("Volume:") Then 'ID found in the ISO Header
+ If Line.Split(New String() {"Volume: "}, StringSplitOptions.RemoveEmptyEntries).Length > 0 Then
+ GameID = Line.Split(New String() {"Volume: "}, StringSplitOptions.RemoveEmptyEntries)(1)
+ Exit For
+ End If
+ Else 'ID found in the ISO files
+ If String.Join(" ", Line.Split(New Char() {}, StringSplitOptions.RemoveEmptyEntries)).Split(" "c).Length > 4 Then
+ GameID = String.Join(" ", Line.Split(New Char() {}, StringSplitOptions.RemoveEmptyEntries)).Split(" "c)(5).Trim()
+ Exit For
+ End If
+ End If
+ End If
+ Next
+ End If
+
+ End Using
+
+ Return GameID
+ End Function
+
+ Public Shared Function GetPS2GameTitleFromDatabaseList(GameID As String) As String
+ Dim FoundGameTitle As String = ""
+ GameID = GameID.Replace("-", "")
+
+ For Each GameTitle As String In File.ReadLines(My.Computer.FileSystem.CurrentDirectory + "\Tools\ps2ids.txt")
+ If GameTitle.Contains(GameID) Then
+ FoundGameTitle = GameTitle.Split(";"c)(1)
+ Exit For
+ End If
+ Next
+
+ If String.IsNullOrEmpty(FoundGameTitle) Then
+ Return "Unknown PS2 game"
+ Else
+ Return FoundGameTitle
+ End If
+ End Function
+
+End Class
diff --git a/Windows/PS Classics fPKG Builder/PSClassicsfPKGBuilder.xaml b/Windows/PS Classics fPKG Builder/PSClassicsfPKGBuilder.xaml
new file mode 100644
index 0000000..b039536
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/PSClassicsfPKGBuilder.xaml
@@ -0,0 +1,185 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Windows/PS Classics fPKG Builder/PSClassicsfPKGBuilder.xaml.vb b/Windows/PS Classics fPKG Builder/PSClassicsfPKGBuilder.xaml.vb
new file mode 100644
index 0000000..5066423
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/PSClassicsfPKGBuilder.xaml.vb
@@ -0,0 +1,1217 @@
+Imports System.Drawing.Imaging
+Imports System.IO
+Imports System.Runtime.CompilerServices
+Imports System.Text.RegularExpressions
+Imports System.Windows.Forms
+Imports DiscUtils
+Imports LibOrbisPkg.SFO
+
+Public Class PSClassicsfPKGBuilder
+
+#Region "PS1"
+
+ Dim CurrentPS1GameID As String = ""
+
+ Private Sub BrowsePS1Disc1Button_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS1Disc1Button.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS1 BIN file.", .Multiselect = False, .Filter = "BIN (*.bin)|*.bin"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+
+ Dim GameID As String = ""
+ Dim GameTitle As String = ""
+
+ 'Get the game ID from the BIN file using strings
+ Using WindowsCMD As New Process()
+ WindowsCMD.StartInfo.FileName = "cmd"
+ WindowsCMD.StartInfo.Arguments = "/c strings.exe /accepteula -nobanner -b 7340032 """ + OFD.FileName + """ | findstr BOOT"
+ WindowsCMD.StartInfo.RedirectStandardOutput = True
+ WindowsCMD.StartInfo.UseShellExecute = False
+ WindowsCMD.StartInfo.CreateNoWindow = True
+ WindowsCMD.Start()
+ WindowsCMD.WaitForExit()
+
+ Dim OutputReader As StreamReader = WindowsCMD.StandardOutput
+ Dim ProcessOutput As String() = OutputReader.ReadToEnd().Split(New String() {vbCrLf}, StringSplitOptions.RemoveEmptyEntries)
+
+ If ProcessOutput.Length > 0 Then
+ For Each OutputLine In ProcessOutput
+ If OutputLine.Contains("BOOT =") Or OutputLine.Contains("BOOT=") Then
+
+ GameID = OutputLine.Replace("BOOT = cdrom:\", "").Replace("BOOT=cdrom:\", "").Replace("BOOT = cdrom:", "").Replace(";1", "").Replace("_", "-").Replace(".", "").Replace("MGS\", "").Trim()
+ GameID = UCase(GameID).Trim()
+
+ 'Try to get a game title from the master list
+ If GameID.Length = 10 Then
+ GameTitle = PS1Game.GetPS1GameTitleFromDatabaseList(GameID)
+ End If
+
+ Exit For
+ End If
+ Next
+ End If
+ End Using
+
+ If Not String.IsNullOrEmpty(GameID) Then
+ CurrentPS1GameID = GameID.Trim()
+ PS1NPTitleTextBox.Text = GameID.Replace("-"c, "").Trim()
+ PS1SelectedDisc1TextBox.Text = OFD.FileName
+ Else
+ If MsgBox("Cannot find the game ID within the PS1 BIN file, do you want to use this file anyway ?" + vbCrLf + "Do not forget to specify a NP title and title if you do so.", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
+ PS1SelectedDisc1TextBox.Text = OFD.FileName
+ End If
+ End If
+ If Not String.IsNullOrEmpty(GameTitle) Then
+ PS1TitleTextBox.Text = GameTitle
+ End If
+ Else
+ MsgBox("Aborted.", MsgBoxStyle.Information)
+ End If
+ End Sub
+
+ Private Sub BrowsePS1IconButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS1IconButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PNG icon file.", .Multiselect = False, .Filter = "PNG (*.png)|*.png"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPS1IconTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS1StartupImageButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS1StartupImageButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PNG Startup Background file.", .Multiselect = False, .Filter = "PNG (*.png)|*.png"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPS1BGTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS1Disc2Button_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS1Disc2Button.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS1 BIN file.", .Multiselect = False, .Filter = "BIN (*.bin)|*.bin"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ PS1SelectedDisc2TextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS1Disc3Button_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS1Disc3Button.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS1 BIN file.", .Multiselect = False, .Filter = "BIN (*.bin)|*.bin"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ PS1SelectedDisc3TextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS1Disc4Button_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS1Disc4Button.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS1 BIN file.", .Multiselect = False, .Filter = "BIN (*.bin)|*.bin"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ PS1SelectedDisc4TextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS1TXTConfigButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS1TXTConfigButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a TXT config file.", .Multiselect = False, .Filter = "TXT (*.txt)|*.txt"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPS1TXTConfigTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS1LUAConfigButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS1LUAConfigButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a LUA config file.", .Multiselect = False, .Filter = "LUA (*.lua)|*.lua"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPS1LUAConfigTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BuildPS1fPKGButton_Click(sender As Object, e As RoutedEventArgs) Handles BuildPS1fPKGButton.Click
+
+ 'Checks before fPKG creation
+ If String.IsNullOrEmpty(PS1SelectedDisc1TextBox.Text) Then
+ MsgBox("No disc 1 specified, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+ If String.IsNullOrEmpty(PS1TitleTextBox.Text) Then
+ MsgBox("No game title specified, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+ If String.IsNullOrEmpty(PS1NPTitleTextBox.Text) Then
+ MsgBox("No NP title specified, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+ If PS1NPTitleTextBox.Text.Length <> 9 Then
+ MsgBox("'NP Title' length mismatching, only 9 characters are allowed, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+
+ Dim FBD As New FolderBrowserDialog() With {.Description = "Please select an output folder", .ShowNewFolderButton = True}
+ If FBD.ShowDialog() = Forms.DialogResult.OK Then
+
+ Dim PKGOutputFolder As String = FBD.SelectedPath
+ Dim GameCacheDirectory As String = My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG"
+
+ 'Remove previous fPKG creation & re-create the PS1fPKG cache folder
+ If Directory.Exists(GameCacheDirectory) Then
+ Directory.Delete(GameCacheDirectory, True)
+ End If
+ If File.Exists(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4") Then
+ File.Delete(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4")
+ End If
+ Directory.CreateDirectory(GameCacheDirectory)
+
+ 'Copy the PS1 emulator to the cache directory
+ My.Computer.FileSystem.CopyDirectory(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\emus\ps1hd", GameCacheDirectory, True)
+
+ 'Copy the selected icon and background to the cache directory
+ If Not Directory.Exists(GameCacheDirectory + "\sce_sys") Then
+ Directory.CreateDirectory(GameCacheDirectory + "\sce_sys")
+ End If
+ If Not String.IsNullOrEmpty(SelectedPS1IconTextBox.Text) Then
+ Using NewFileStream As New FileStream(SelectedPS1IconTextBox.Text, FileMode.Open, FileAccess.Read)
+ Utils.ConvertTo24bppPNG(Utils.ResizeAsImage(System.Drawing.Image.FromStream(NewFileStream), 512, 512)).Save(GameCacheDirectory + "\sce_sys\icon0.png", ImageFormat.Png)
+ End Using
+ End If
+ If Not String.IsNullOrEmpty(SelectedPS1BGTextBox.Text) Then
+ Using NewFileStream As New FileStream(SelectedPS1BGTextBox.Text, FileMode.Open, FileAccess.Read)
+ Utils.ConvertTo24bppPNG(Utils.ResizeAsImage(System.Drawing.Image.FromStream(NewFileStream), 1920, 1080)).Save(GameCacheDirectory + "\sce_sys\pic0.png", ImageFormat.Png)
+ End Using
+ End If
+
+ Dim Disc1CueFile As String = ""
+ Dim Disc2CueFile As String = ""
+ Dim Disc3CueFile As String = ""
+ Dim Disc4CueFile As String = ""
+
+ 'PS1 Emulator configuration
+ Using ConfigWriter As New StreamWriter(GameCacheDirectory + "\config-title.txt", False)
+ ConfigWriter.WriteLine("--ps4-trophies=0")
+ ConfigWriter.WriteLine("--ps5-uds=0")
+ ConfigWriter.WriteLine("--trophies=0")
+
+ 'Add disc information
+ Disc1CueFile = PS1SelectedDisc1TextBox.Text.Replace(".bin", ".cue")
+ ConfigWriter.WriteLine("--image=""data/disc1.bin""")
+
+ If Not String.IsNullOrEmpty(PS1SelectedDisc2TextBox.Text) Then
+ Disc2CueFile = PS1SelectedDisc2TextBox.Text.Replace(".bin", ".cue")
+ ConfigWriter.WriteLine("--image=""data/disc2.bin""")
+ End If
+ If Not String.IsNullOrEmpty(PS1SelectedDisc3TextBox.Text) Then
+ Disc3CueFile = PS1SelectedDisc3TextBox.Text.Replace(".bin", ".cue")
+ ConfigWriter.WriteLine("--image=""data/disc3.bin""")
+ End If
+ If Not String.IsNullOrEmpty(PS1SelectedDisc4TextBox.Text) Then
+ Disc4CueFile = PS1SelectedDisc4TextBox.Text.Replace(".bin", ".cue")
+ ConfigWriter.WriteLine("--image=""data/disc4.bin""")
+ End If
+
+ 'Check for libcrypt protection
+ Dim FormattedGameID As String = ""
+ If String.IsNullOrEmpty(CurrentPS1GameID) Then
+ FormattedGameID = PS1NPTitleTextBox.Text.Insert(4, "_").Insert(8, ".")
+ Else
+ FormattedGameID = CurrentPS1GameID.Replace("-", "_").Insert(8, ".")
+ End If
+ Dim ProtectionValue As String = PS1Game.IsGameProtected(FormattedGameID)
+ If Not String.IsNullOrEmpty(ProtectionValue) Then
+ If MsgBox("This game is Libcrypt protected. Do you want to add --libcrypt to the configuration file ?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
+ ConfigWriter.WriteLine("--libcrypt=" + ProtectionValue)
+ End If
+ End If
+
+ 'Check for LUA config
+ If Not String.IsNullOrEmpty(SelectedPS1LUAConfigTextBox.Text) Then
+ ConfigWriter.WriteLine("--ps1-title-id=" + PS1NPTitleTextBox.Text)
+ File.Copy(SelectedPS1LUAConfigTextBox.Text, GameCacheDirectory + "\scripts\" + PS1NPTitleTextBox.Text + ".lua", True)
+ End If
+
+ 'Graphics & other configs
+ ConfigWriter.WriteLine("--scale=" + PS1UpscalingComboBox.Text)
+ If PS1SkipBootlogoCheckBox.IsChecked Then
+ ConfigWriter.WriteLine("--bios-hide-sce-osd=1")
+ End If
+ If PS1GunconCheckBox.IsChecked Then
+ ConfigWriter.WriteLine("--guncon")
+ End If
+ If PS1Force60HzCheckBox.IsChecked Then
+ ConfigWriter.WriteLine("--gpu-scanout-fps-override=60")
+ End If
+ If PS1EmulateAnalogSticksCheckBox.IsChecked Then
+ ConfigWriter.WriteLine("--sim-analog-pad=0x2020")
+ End If
+
+ 'Check for TXT config
+ If Not String.IsNullOrEmpty(SelectedPS1TXTConfigTextBox.Text) Then
+ ConfigWriter.WriteLine("#User imported config")
+ ConfigWriter.WriteLine(File.ReadAllText(SelectedPS1TXTConfigTextBox.Text))
+ End If
+ End Using
+
+ 'Create a new PARAM.SFO file
+ Dim NewPS4ParamSFO As New ParamSfo()
+ NewPS4ParamSFO.SetValue("APP_TYPE", SfoEntryType.Integer, "1", 4)
+ NewPS4ParamSFO.SetValue("APP_VER", SfoEntryType.Utf8, "01.00", 8)
+ NewPS4ParamSFO.SetValue("ATTRIBUTE", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("CATEGORY", SfoEntryType.Utf8, "gd", 4)
+ NewPS4ParamSFO.SetValue("CONTENT_ID", SfoEntryType.Utf8, "UP9000-" + PS1NPTitleTextBox.Text + "_00-" + PS1NPTitleTextBox.Text + "PS1FPKG", 48)
+ NewPS4ParamSFO.SetValue("DOWNLOAD_DATA_SIZE", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("FORMAT", SfoEntryType.Utf8, "obs", 4)
+ NewPS4ParamSFO.SetValue("PARENTAL_LEVEL", SfoEntryType.Integer, "5", 4)
+ NewPS4ParamSFO.SetValue("SYSTEM_VER", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("TITLE", SfoEntryType.Utf8, PS1TitleTextBox.Text, 128)
+ NewPS4ParamSFO.SetValue("TITLE_ID", SfoEntryType.Utf8, PS1NPTitleTextBox.Text, 12)
+ NewPS4ParamSFO.SetValue("VERSION", SfoEntryType.Utf8, "01.00", 8)
+
+ File.WriteAllBytes(GameCacheDirectory + "\sce_sys\param.sfo", NewPS4ParamSFO.Serialize)
+
+ 'Create TOC file
+ Dim CUE2TOCProcess As New Process()
+ CUE2TOCProcess.StartInfo.FileName = My.Computer.FileSystem.CurrentDirectory + "\Tools\cue2toc.exe"
+ CUE2TOCProcess.StartInfo.Arguments = """" + Disc1CueFile + """"
+ CUE2TOCProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(Disc1CueFile)
+ CUE2TOCProcess.StartInfo.UseShellExecute = False
+ CUE2TOCProcess.StartInfo.CreateNoWindow = True
+ CUE2TOCProcess.Start()
+ CUE2TOCProcess.WaitForExit()
+
+ File.Move(Path.GetDirectoryName(PS1SelectedDisc1TextBox.Text) + "\" + Path.GetFileNameWithoutExtension(PS1SelectedDisc1TextBox.Text) + ".toc", GameCacheDirectory + "\data\disc1.toc")
+
+ 'Generate GP4 project
+ Dim NewProcess As New Process()
+ NewProcess.StartInfo.FileName = My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\gengp4_patch.exe"
+ NewProcess.StartInfo.Arguments = """" + GameCacheDirectory + """"
+ NewProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
+ NewProcess.StartInfo.CreateNoWindow = True
+ NewProcess.Start()
+ NewProcess.WaitForExit()
+
+ 'Modify the GP4 project and add disc info
+ Dim Disc1CuePath As String = vbCrLf + " "
+ Dim Disc1BinPath As String = vbCrLf + " "
+ File.WriteAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4", File.ReadAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4").Replace("", ""))
+ File.WriteAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4", File.ReadAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4").Replace("", Disc1CuePath + Disc1BinPath + vbCrLf + ""))
+
+ If Not String.IsNullOrEmpty(PS1SelectedDisc2TextBox.Text) Then
+ Dim Disc2CuePath As String = vbCrLf + " "
+ Dim Disc2BinPath As String = vbCrLf + " "
+ File.WriteAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4", File.ReadAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4").Replace("", Disc2CuePath + Disc2BinPath + vbCrLf + ""))
+ End If
+ If Not String.IsNullOrEmpty(PS1SelectedDisc2TextBox.Text) Then
+ Dim Disc3CuePath As String = vbCrLf + " "
+ Dim Disc3BinPath As String = vbCrLf + " "
+ File.WriteAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4", File.ReadAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4").Replace("", Disc3CuePath + Disc3BinPath + vbCrLf + ""))
+ End If
+ If Not String.IsNullOrEmpty(PS1SelectedDisc2TextBox.Text) Then
+ Dim Disc4CuePath As String = vbCrLf + " "
+ Dim Disc4BinPath As String = vbCrLf + " "
+ File.WriteAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4", File.ReadAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4").Replace("", Disc4CuePath + Disc4BinPath + vbCrLf + ""))
+ End If
+
+ MsgBox("All files ready for PKG creation.", MsgBoxStyle.Information)
+
+ 'Create the fPKG
+ Dim PKGBuilderProcessOutput As String
+ Dim PKGBuilderProcess As New Process()
+ PKGBuilderProcess.StartInfo.FileName = My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\mod-pub\orbis-pub-cmd-3.38.exe"
+ PKGBuilderProcess.StartInfo.Arguments = "img_create --oformat pkg --skip_digest --no_progress_bar """ + My.Computer.FileSystem.CurrentDirectory + "\Cache\PS1fPKG.gp4"" """ + PKGOutputFolder + """"
+ PKGBuilderProcess.StartInfo.UseShellExecute = False
+ PKGBuilderProcess.StartInfo.RedirectStandardOutput = True
+ PKGBuilderProcess.StartInfo.CreateNoWindow = True
+ PKGBuilderProcess.Start()
+ PKGBuilderProcess.WaitForExit()
+
+ Using NewStreamReader As StreamReader = PKGBuilderProcess.StandardOutput
+ PKGBuilderProcessOutput = NewStreamReader.ReadToEnd()
+ End Using
+ If PKGBuilderProcessOutput.Contains("Create image Process finished with warning") Then
+ If MsgBox("PKG created!" + vbCrLf + "Do you want to open the output folder ?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
+ Process.Start("explorer", FBD.SelectedPath)
+ End If
+ Else
+ MsgBox("PKG creation failed!", MsgBoxStyle.Information)
+ MsgBox(PKGBuilderProcessOutput)
+ End If
+ Else
+ MsgBox("Aborted", MsgBoxStyle.Information)
+ End If
+
+ End Sub
+
+#End Region
+
+#Region "PS2"
+
+ Dim CurrentPS2GameID As String = ""
+ Dim CurrentPS2GameCRC As String = ""
+
+ Private Sub BrowsePS2Disc1Button_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2Disc1Button.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS2 ISO file.", .Multiselect = False, .Filter = "ISO (*.iso)|*.iso"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+
+ Dim PS2GameID As String = PS2Game.GetPS2GameID(OFD.FileName)
+ Dim ExtractedPS2GameELFPath As String = GetELFfromISO(OFD.FileName, PS2GameID)
+ CurrentPS2GameID = PS2GameID
+
+ Dim PS2GameCRC As String = GetGameCRC(ExtractedPS2GameELFPath)
+ PS2GameCRC = Regex.Replace(PS2GameCRC, "[^a-zA-Z0-9]", "")
+ CurrentPS2GameCRC = PS2GameCRC
+
+ If Not String.IsNullOrEmpty(PS2GameID) AndAlso Not String.IsNullOrEmpty(PS2GameCRC) Then
+
+ If IsConfigAvailable(PS2GameID, My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\configs_txt.dat") Then
+ PS2AddTXTConfigFromDatabaseCheckBox.IsChecked = True
+ PS2AddTXTConfigFromDatabaseCheckBox.Visibility = Visibility.Visible
+ Else
+ PS2AddTXTConfigFromDatabaseCheckBox.IsChecked = False
+ PS2AddTXTConfigFromDatabaseCheckBox.Visibility = Visibility.Hidden
+ End If
+
+ If IsConfigAvailable(PS2GameID, My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\configs_lua.dat") Then
+ PS2AddLUAConfigFromDatabaseCheckBox.IsChecked = True
+ PS2AddLUAConfigFromDatabaseCheckBox.Visibility = Visibility.Visible
+ Else
+ PS2AddLUAConfigFromDatabaseCheckBox.IsChecked = False
+ PS2AddLUAConfigFromDatabaseCheckBox.Visibility = Visibility.Hidden
+ End If
+
+ If IsConfigAvailable(PS2GameID + ".CONFIG", My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\configs_ps3.dat") Then
+ PS2AddPS3ConfigFromDatabaseCheckBox.IsChecked = True
+ PS2AddPS3ConfigFromDatabaseCheckBox.Visibility = Visibility.Visible
+ Else
+ PS2AddPS3ConfigFromDatabaseCheckBox.IsChecked = False
+ PS2AddPS3ConfigFromDatabaseCheckBox.Visibility = Visibility.Hidden
+ End If
+
+ If IsConfigAvailable(PS2GameCRC + ".lua", My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\widescreen.dat") Then
+ PS2UseWidescreenPatchCheckBox.IsChecked = True
+ PS2UseWidescreenPatchCheckBox.IsEnabled = True
+ Else
+ PS2UseWidescreenPatchCheckBox.IsEnabled = False
+ End If
+
+ PS2TitleTextBox.Text = PS2Game.GetPS2GameTitleFromDatabaseList(PS2GameID.Replace(".", "").Replace("_", "-").Trim())
+ PS2NPTitleTextBox.Text = PS2GameID.Replace(".", "").Replace("_", "").Trim()
+ SelectedDisc1TextBox.Text = OFD.FileName
+ Else
+ If MsgBox("Could not find the PS2 game ID within the ISO file." + vbCrLf + "Do you want to use this file anyway ?", MsgBoxStyle.YesNo, "PS2 Game ID not found") = MsgBoxResult.Yes Then
+ SelectedDisc1TextBox.Text = OFD.FileName
+ End If
+ End If
+
+ End If
+ End Sub
+
+ Public Shared Function IsConfigAvailable(GameID As String, ConfigDatabaseFile As String) As Boolean
+ Dim Exists As Boolean
+ Try
+ Using NewFileStream As New FileStream(ConfigDatabaseFile, FileMode.Open, FileAccess.Read)
+ Dim NewUdfReader As New Udf.UdfReader(NewFileStream, 2048)
+ Try
+ NewUdfReader.OpenFile(GameID, FileMode.Open)
+ Exists = True
+ Catch ex As Exception
+ Exists = False
+ End Try
+ End Using
+ Catch ex As Exception
+ MessageBox.Show(ex.Message)
+ Exists = False
+ End Try
+ Return Exists
+ End Function
+
+ Public Shared Function GetELFfromISO(GameISOFile As String, GameELFName As String) As String
+ Dim ExtractedELFPath As String = ""
+
+ Dim CacheDir As String = My.Computer.FileSystem.CurrentDirectory + "\Cache"
+ If Not Directory.Exists(CacheDir) Then
+ Directory.CreateDirectory(CacheDir)
+ End If
+
+ Try
+ Using NewFileStream As New FileStream(GameISOFile, FileMode.Open, FileAccess.Read)
+ Dim NewCDReader As New Iso9660.CDReader(NewFileStream, True)
+ Try
+ Dim ELFExtractionFileStream As New FileStream(CacheDir + "\" + GameELFName, FileMode.Create)
+ NewCDReader.OpenFile(GameELFName, FileMode.Open).CopyTo(ELFExtractionFileStream)
+
+ ExtractedELFPath = CacheDir + "\" + GameELFName
+ Catch ex As Exception
+ ExtractedELFPath = ""
+ End Try
+ End Using
+ Catch ex As Exception
+ Return ExtractedELFPath
+ End Try
+ Return ExtractedELFPath
+ End Function
+
+ Public Shared Function GetGameCRC(PS2GamePath As String) As String
+ Dim NewProcessStartInfo As New ProcessStartInfo(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\crc.exe", PS2GamePath) With {.UseShellExecute = False, .RedirectStandardOutput = True, .CreateNoWindow = True, .Arguments = """" + PS2GamePath + """"}
+ Dim NewProcess As New Process With {.StartInfo = NewProcessStartInfo}
+ NewProcess.Start()
+ Using NewStreamReader As StreamReader = NewProcess.StandardOutput
+ Return NewStreamReader.ReadToEnd().Replace("crc:", "").Trim()
+ End Using
+ End Function
+
+ Public Shared Function ExtractFileFromISO(GameISOFile As String, FileToExtract As String, FileDestinationPath As String) As String
+ Dim ReturnedFileDestinationPath As String
+ Try
+ Using NewFileStream As New FileStream(GameISOFile, FileMode.Open, FileAccess.Read)
+ Dim NewUdfReader As New Udf.UdfReader(NewFileStream, &H800)
+ Try
+ Dim NewFileStream2 As New FileStream(FileDestinationPath, FileMode.Create)
+ NewUdfReader.OpenFile(FileToExtract, FileMode.Open).CopyTo(NewFileStream2)
+ NewFileStream2.Close()
+ ReturnedFileDestinationPath = FileDestinationPath
+ Catch exception1 As Exception
+ ReturnedFileDestinationPath = ""
+ End Try
+ End Using
+ Catch exception3 As Exception
+ ReturnedFileDestinationPath = ""
+ End Try
+ Return ReturnedFileDestinationPath
+ End Function
+
+ Public Shared Function GetPNACHFromDAT(DATFile As String, FileToExtract As String) As String
+ Dim PNACHString As String
+ Try
+ Using NewFileStream As New FileStream(DATFile, FileMode.Open, FileAccess.Read)
+ Dim NewUdfReader As New Udf.UdfReader(NewFileStream, 2048)
+ Try
+ PNACHString = New StreamReader(NewUdfReader.OpenFile(FileToExtract, FileMode.Open)).ReadToEnd()
+ Catch exception1 As Exception
+ PNACHString = ""
+ End Try
+ End Using
+ Catch exception3 As Exception
+ PNACHString = ""
+ End Try
+ Return PNACHString
+ End Function
+
+ Private Sub BrowsePS2IconButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2IconButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PNG icon file.", .Multiselect = False, .Filter = "PNG (*.png)|*.png"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedIconTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS2StartupImageButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2StartupImageButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PNG background file.", .Multiselect = False, .Filter = "PNG (*.png)|*.png"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedStartupImageTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS2MCButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2MCButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS2 Memory Card file.", .Multiselect = False, .Filter = "VM2 Card (*.vm2)|*.vm2|PS2 Card (*.ps2)|*.ps2|BIN Card (*.bin)|*.bin"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPS2MemoryCardTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS2TXTConfigButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2TXTConfigButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a TXT config file.", .Multiselect = False, .Filter = "TXT (*.txt)|*.txt"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPS2TXTConfigTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS2LUAConfigButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2LUAConfigButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a LUA config file.", .Multiselect = False, .Filter = "LUA (*.lua)|*.lua"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPS2LUAConfigTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS2Disc2Button_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2Disc2Button.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS2 ISO file.", .Multiselect = False, .Filter = "ISO (*.iso)|*.iso"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedDisc2TextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS2Disc3Button_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2Disc3Button.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS2 ISO file.", .Multiselect = False, .Filter = "ISO (*.iso)|*.iso"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedDisc3TextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS2Disc4Button_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2Disc4Button.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS2 ISO file.", .Multiselect = False, .Filter = "ISO (*.iso)|*.iso"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedDisc4TextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePS2Disc5Button_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePS2Disc5Button.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PS2 ISO file.", .Multiselect = False, .Filter = "ISO (*.iso)|*.iso"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedDisc5TextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BuildPS2fPKGButton_Click(sender As Object, e As RoutedEventArgs) Handles BuildPS2fPKGButton.Click
+
+ 'Checks before fPKG creation
+ If String.IsNullOrEmpty(SelectedDisc1TextBox.Text) Then
+ MsgBox("No disc 1 specified, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+ If String.IsNullOrEmpty(PS2TitleTextBox.Text) Then
+ MsgBox("No game title specified, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+ If String.IsNullOrEmpty(PS2NPTitleTextBox.Text) Then
+ MsgBox("No NP title specified, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+ If PS2NPTitleTextBox.Text.Length <> 9 Then
+ MsgBox("'NP Title' length mismatching, only 9 characters are allowed, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+
+ 'Get disc count
+ Dim DiscCount As Integer = 0
+ If Not String.IsNullOrEmpty(SelectedDisc1TextBox.Text) Then
+ DiscCount += 1
+ End If
+ If Not String.IsNullOrEmpty(SelectedDisc2TextBox.Text) Then
+ DiscCount += 1
+ End If
+ If Not String.IsNullOrEmpty(SelectedDisc3TextBox.Text) Then
+ DiscCount += 1
+ End If
+ If Not String.IsNullOrEmpty(SelectedDisc4TextBox.Text) Then
+ DiscCount += 1
+ End If
+ If Not String.IsNullOrEmpty(SelectedDisc5TextBox.Text) Then
+ DiscCount += 1
+ End If
+
+ 'Select an output folder
+ Dim FBD As New FolderBrowserDialog() With {.Description = "Please select an output folder", .ShowNewFolderButton = True}
+ If FBD.ShowDialog() = Forms.DialogResult.OK Then
+
+ Dim PKGOutputFolder As String = FBD.SelectedPath
+ Dim SelectedPS2Emulator As String = PS2EmulatorComboBox.Text
+ Dim FullPS2GameID As String = CurrentPS2GameID.Replace(".", "").Replace("_", "-").Trim()
+ Dim GameCacheDirectory As String = My.Computer.FileSystem.CurrentDirectory + "\Cache\PS2fPKG"
+
+ 'Remove previous fPKG creation & re-create the PS2fPKG cache folder
+ If Directory.Exists(GameCacheDirectory) Then
+ Directory.Delete(GameCacheDirectory, True)
+ End If
+ If File.Exists(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS2fPKG.gp4") Then
+ File.Delete(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS2fPKG.gp4")
+ End If
+ Directory.CreateDirectory(GameCacheDirectory)
+
+ 'Copy the selected PS2 emulator to the cache directory
+ My.Computer.FileSystem.CopyDirectory(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\emus\" + SelectedPS2Emulator, GameCacheDirectory, True)
+
+ 'Copy the selected icon and background to the cache directory
+ If Not Directory.Exists(GameCacheDirectory + "\sce_sys") Then
+ Directory.CreateDirectory(GameCacheDirectory + "\sce_sys")
+ End If
+ If Not String.IsNullOrEmpty(SelectedIconTextBox.Text) Then
+ Using NewFileStream As New FileStream(SelectedIconTextBox.Text, FileMode.Open, FileAccess.Read)
+ Utils.ConvertTo24bppPNG(Utils.ResizeAsImage(System.Drawing.Image.FromStream(NewFileStream), 512, 512)).Save(GameCacheDirectory + "\sce_sys\icon0.png", ImageFormat.Png)
+ End Using
+ End If
+ If Not String.IsNullOrEmpty(SelectedStartupImageTextBox.Text) Then
+ Using NewFileStream As New FileStream(SelectedStartupImageTextBox.Text, FileMode.Open, FileAccess.Read)
+ Utils.ConvertTo24bppPNG(Utils.ResizeAsImage(System.Drawing.Image.FromStream(NewFileStream), 1920, 1080)).Save(GameCacheDirectory + "\sce_sys\pic0.png", ImageFormat.Png)
+ End Using
+ End If
+
+ 'Create a new PARAM.SFO file
+ Dim NewPS4ParamSFO As New ParamSfo()
+ NewPS4ParamSFO.SetValue("APP_TYPE", SfoEntryType.Integer, "1", 4)
+ NewPS4ParamSFO.SetValue("APP_VER", SfoEntryType.Utf8, "01.00", 8)
+ NewPS4ParamSFO.SetValue("ATTRIBUTE", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("CATEGORY", SfoEntryType.Utf8, "gd", 4)
+ NewPS4ParamSFO.SetValue("CONTENT_ID", SfoEntryType.Utf8, String.Concat(New String() {"UP9000-", PS2NPTitleTextBox.Text, "_00-", CurrentPS2GameID.Replace(".", "").Replace("_", "").Trim(), "0000001"}), 48)
+ NewPS4ParamSFO.SetValue("DOWNLOAD_DATA_SIZE", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("FORMAT", SfoEntryType.Utf8, "obs", 4)
+ NewPS4ParamSFO.SetValue("PARENTAL_LEVEL", SfoEntryType.Integer, "5", 4)
+ NewPS4ParamSFO.SetValue("REMOTE_PLAY_KEY_ASSIGN", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("SYSTEM_VER", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("TITLE", SfoEntryType.Utf8, PS2TitleTextBox.Text, 128)
+ NewPS4ParamSFO.SetValue("TITLE_ID", SfoEntryType.Utf8, PS2NPTitleTextBox.Text, 12)
+ NewPS4ParamSFO.SetValue("VERSION", SfoEntryType.Utf8, "01.00", 8)
+
+ File.WriteAllBytes(GameCacheDirectory + "\sce_sys\param.sfo", NewPS4ParamSFO.Serialize)
+
+ 'Create a new PS2 emulator configuration file
+ Dim NewPS2EmulatorConfig As String() = New String() {"--path-vmc=""/tmp/vmc""" + vbCrLf + "--config-local-lua=""""" + vbCrLf + "--ps2-title-id=",
+ FullPS2GameID,
+ vbCrLf + "--max-disc-num=", DiscCount.ToString(),
+ vbCrLf + "--gs-uprender=", LCase(PS2UprenderComboBox.Text),
+ vbCrLf + "--gs-upscale=", LCase(PS2UpscalingComboBox.Text),
+ vbCrLf + "--host-audio=1" + vbCrLf +
+ "--rom=""PS20220WD20050620.crack""" + vbCrLf +
+ "--verbose-cdvd-reads=0" + vbCrLf +
+ "--host-display-mode=", LCase(PS2DisplayModeComboBox.Text)}
+ Dim NewPS2EmulatorConfigContent As String = String.Concat(NewPS2EmulatorConfig)
+
+ 'Reset on disc change config
+ If Not PS2RestartEmulatorOnDiscChangeCheckBox.IsChecked Then
+ NewPS2EmulatorConfigContent = NewPS2EmulatorConfigContent + vbCrLf + "#Disable emu reset on disc change" + vbCrLf + "--switch-disc-reset=0"
+ End If
+
+ 'Multitap config
+ If PS2MultitapComboBox.SelectedIndex = 1 Then
+ NewPS2EmulatorConfigContent = NewPS2EmulatorConfigContent + vbCrLf + "#Enable Multitap" + vbCrLf + "--mtap1=always"
+ ElseIf PS2MultitapComboBox.SelectedIndex = 2 Then
+ NewPS2EmulatorConfigContent = NewPS2EmulatorConfigContent + vbCrLf + "#Enable Multitap" + vbCrLf + "--mtap2=always"
+ ElseIf PS2MultitapComboBox.SelectedIndex = 3 Then
+ NewPS2EmulatorConfigContent = (NewPS2EmulatorConfigContent + vbCrLf + "#Enable Multitap" + vbCrLf + "--mtap1=always" + vbCrLf + "--mtap2=always")
+ End If
+
+ 'Check for PS3 config file
+ If PS2AddPS3ConfigFromDatabaseCheckBox.IsChecked Then
+ If File.Exists(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\ps3\" + CurrentPS2GameID + ".CONFIG") Then
+
+ NewPS2EmulatorConfigContent = NewPS2EmulatorConfigContent + vbCrLf + "--lopnor-config=1"
+
+ 'Create patches directory
+ If Not Directory.Exists(GameCacheDirectory + "\patches\" + FullPS2GameID) Then
+ Directory.CreateDirectory(GameCacheDirectory + "\patches\" + FullPS2GameID)
+ End If
+
+ File.Copy(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\ps3\" + CurrentPS2GameID + ".CONFIG",
+ GameCacheDirectory + "\patches\" + FullPS2GameID + "\" + FullPS2GameID + "_lopnor.cfgbin", True)
+
+ ElseIf IsConfigAvailable(CurrentPS2GameID + ".CONFIG", My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\configs_ps3.dat") Then
+
+ If Not Directory.Exists(GameCacheDirectory + "\patches\" + FullPS2GameID) Then
+ Directory.CreateDirectory(GameCacheDirectory + "\patches\" + FullPS2GameID)
+ End If
+
+ ExtractFileFromISO(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\configs_ps3.dat",
+ CurrentPS2GameID + ".CONFIG", GameCacheDirectory + "\patches\" + FullPS2GameID + "\" + FullPS2GameID + "_lopnor.cfgbin")
+
+ End If
+ End If
+
+ 'Widescreen Patch cnofig
+ If PS2UseWidescreenPatchCheckBox.IsChecked Then
+ Dim WidescreenPatch As String = ""
+
+ If File.Exists(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\widescreen\" + CurrentPS2GameCRC + ".lua") Then
+ WidescreenPatch = File.ReadAllText(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\widescreen\" + CurrentPS2GameCRC + ".lua")
+ ElseIf IsConfigAvailable(CurrentPS2GameCRC + ".lua", My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\widescreen.dat") Then
+ WidescreenPatch = GetPNACHFromDAT(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\widescreen.dat", CurrentPS2GameCRC + ".lua")
+ End If
+
+ If Not String.IsNullOrEmpty(WidescreenPatch) Then
+ NewPS2EmulatorConfigContent = NewPS2EmulatorConfigContent + vbCrLf + "--path-trophydata=""/app0/trophy_data"""
+
+ If Not Directory.Exists(GameCacheDirectory + "\trophy_data\") Then
+ Directory.CreateDirectory(GameCacheDirectory + "\trophy_data\")
+ End If
+
+ File.WriteAllText(GameCacheDirectory + "\trophy_data\" + FullPS2GameID + "_trophies.lua", WidescreenPatch)
+ End If
+ End If
+
+ 'Copy lua_include to cache directory
+ My.Computer.FileSystem.CopyDirectory(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\lua_include", GameCacheDirectory + "\lua_include", True)
+
+ 'Check for LUA config
+ If Not String.IsNullOrEmpty(SelectedPS2LUAConfigTextBox.Text) Then
+
+ NewPS2EmulatorConfigContent = NewPS2EmulatorConfigContent + vbCrLf + "--path-patches=""/app0/patches"
+
+ 'Create patches directory if it doesn't exist yet
+ If Not Directory.Exists(GameCacheDirectory + "\patches\" + FullPS2GameID) Then
+ Directory.CreateDirectory(GameCacheDirectory + "\patches\" + FullPS2GameID)
+ End If
+
+ File.Copy(SelectedPS2LUAConfigTextBox.Text, GameCacheDirectory + "\patches\" + FullPS2GameID + "_config.lua", True)
+ Else
+ If PS2AddLUAConfigFromDatabaseCheckBox.IsChecked Then
+ If IsConfigAvailable(CurrentPS2GameID, My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\configs_lua.dat") Then
+
+ NewPS2EmulatorConfigContent = NewPS2EmulatorConfigContent + vbCrLf + "--path-patches=""/app0/patches"
+
+ If Not Directory.Exists(GameCacheDirectory + "\patches\" + FullPS2GameID) Then
+ Directory.CreateDirectory(GameCacheDirectory + "\patches\" + FullPS2GameID)
+ End If
+
+ ExtractFileFromISO(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\configs_lua.dat", CurrentPS2GameID, GameCacheDirectory + "\patches\" + FullPS2GameID + "_config.lua")
+ End If
+ End If
+ End If
+
+ 'Emulator fixes
+ Dim PS2EmulatorFixes As String = ""
+ If PS2ImproveSpeedCheckBox.IsChecked Then
+ PS2EmulatorFixes = PS2EmulatorFixes + vbCrLf + "#Improve Speed" + vbCrLf + "-vu0-opt-flags=1" + vbCrLf + "--vu1-opt-flags=1" + vbCrLf + "--cop2-opt-flags=1" + vbCrLf + "--vu0-const-prop=0" + vbCrLf + "--vu1-const-prop=0" + vbCrLf + "--vu1-jr-cache-policy=newprog" + vbCrLf + "--vu1-jalr-cache-policy=newprog" + vbCrLf + "--vu0-jr-cache-policy=newprog" + vbCrLf + "--vu0-jalr-cache-policy=newprog"
+ End If
+ If PS2FixGraphicsCheckBox.IsChecked Then
+ PS2EmulatorFixes = PS2EmulatorFixes + vbCrLf + "#Fix Graphics" + vbCrLf + "--fpu-no-clamping=0" + vbCrLf + "--fpu-clamp-results=1" + vbCrLf + "--vu0-no-clamping=0" + vbCrLf + "--vu0-clamp-results=1" + vbCrLf + "--vu1-no-clamping=0" + vbCrLf + "--vu1-clamp-results=1" + vbCrLf + "--cop2-no-clamping=0" + vbCrLf + "--cop2-clamp-results=1"
+ End If
+ If PS2DisableMTVUCheckBox.IsChecked Then
+ PS2EmulatorFixes = PS2EmulatorFixes + vbCrLf + "#Disable MTVU" + vbCrLf + "--vu1=jit-sync"
+ End If
+ If PS2DisableInstantVIF1TransferCheckBox.IsChecked Then
+ PS2EmulatorFixes = PS2EmulatorFixes + vbCrLf + "#Disable Instant VIF1 Transfer" + vbCrLf + "--vif1-instant-xfer=0"
+ End If
+
+ 'Check for TXT config
+ If Not String.IsNullOrEmpty(SelectedPS2TXTConfigTextBox.Text) Then
+ Dim ModifiedPS2EmulatorConfigContent As String() = New String() {NewPS2EmulatorConfigContent, vbCrLf, PS2EmulatorFixes, vbCrLf + "#User Config" + vbCrLf, File.ReadAllText(SelectedPS2TXTConfigTextBox.Text)}
+ NewPS2EmulatorConfigContent = String.Concat(ModifiedPS2EmulatorConfigContent)
+ Else
+ If PS2AddTXTConfigFromDatabaseCheckBox.IsChecked Then
+ If IsConfigAvailable(CurrentPS2GameID, My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\configs_txt.dat") Then
+ NewPS2EmulatorConfigContent = NewPS2EmulatorConfigContent + vbCrLf + "#" + CurrentPS2GameID + vbCrLf + GetPNACHFromDAT(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\ps2-configs\configs_txt.dat", CurrentPS2GameID)
+ End If
+ Else
+ 'Append only PS2EmulatorFixes
+ NewPS2EmulatorConfigContent = NewPS2EmulatorConfigContent + vbCrLf + PS2EmulatorFixes
+ End If
+ End If
+
+ 'Write config-emu-ps4.txt
+ If File.Exists(GameCacheDirectory + "\config-emu-ps4.txt") Then
+ File.Delete(GameCacheDirectory + "\config-emu-ps4.txt")
+ End If
+ File.WriteAllText(GameCacheDirectory + "\config-emu-ps4.txt", NewPS2EmulatorConfigContent)
+
+ If Not Directory.Exists(GameCacheDirectory + "\feature_data\") Then
+ Directory.CreateDirectory(GameCacheDirectory + "\feature_data\")
+ End If
+ If Not Directory.Exists(GameCacheDirectory + "\feature_data\" + FullPS2GameID) Then
+ Directory.CreateDirectory(GameCacheDirectory + "\feature_data\" + FullPS2GameID)
+ End If
+
+ 'Check for PS2 Memory Card file
+ If Not String.IsNullOrEmpty(SelectedPS2MemoryCardTextBox.Text) Then
+ File.Copy(SelectedPS2MemoryCardTextBox.Text, GameCacheDirectory + "\feature_data\" + FullPS2GameID + "\custom.card", True)
+ End If
+
+ If Not Directory.Exists(GameCacheDirectory + "\image") Then
+ Directory.CreateDirectory(GameCacheDirectory + "\image")
+ End If
+
+ 'Create a GP4 project
+ Dim NewProcess As New Process()
+ NewProcess.StartInfo.FileName = My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\gengp4_patch.exe"
+ NewProcess.StartInfo.Arguments = """" + GameCacheDirectory + """"
+ NewProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
+ NewProcess.Start()
+ NewProcess.WaitForExit()
+
+ File.WriteAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS2fPKG.gp4", File.ReadAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS2fPKG.gp4").Replace("", ""))
+
+ 'Check compression config
+ Dim UseCompression As String = "disable"
+ If PS2UseCompressionCheckBox.IsChecked Then
+ UseCompression = "enable"
+ End If
+
+ 'Add disc information
+ Dim FullDiscInfo As String = ""
+ If Not String.IsNullOrEmpty(SelectedDisc1TextBox.Text) Then
+ Dim NewDiscInfo As String() = New String() {FullDiscInfo, vbCrLf + " "}
+ FullDiscInfo = String.Concat(NewDiscInfo)
+ End If
+ If Not String.IsNullOrEmpty(SelectedDisc2TextBox.Text) Then
+ Dim NewDiscInfo As String() = New String() {FullDiscInfo, vbCrLf + " "}
+ FullDiscInfo = String.Concat(NewDiscInfo)
+ End If
+ If Not String.IsNullOrEmpty(SelectedDisc3TextBox.Text) Then
+ Dim NewDiscInfo As String() = New String() {FullDiscInfo, vbCrLf + " "}
+ FullDiscInfo = String.Concat(NewDiscInfo)
+ End If
+ If Not String.IsNullOrEmpty(SelectedDisc4TextBox.Text) Then
+ Dim NewDiscInfo As String() = New String() {FullDiscInfo, vbCrLf + " "}
+ FullDiscInfo = String.Concat(NewDiscInfo)
+ End If
+ If Not String.IsNullOrEmpty(SelectedDisc5TextBox.Text) Then
+ Dim NewDiscInfo As String() = New String() {FullDiscInfo, vbCrLf + " "}
+ FullDiscInfo = String.Concat(NewDiscInfo)
+ End If
+
+ File.WriteAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS2fPKG.gp4", File.ReadAllText(My.Computer.FileSystem.CurrentDirectory + "\Cache\PS2fPKG.gp4").Replace("", FullDiscInfo + vbCrLf + ""))
+
+ MsgBox("All files ready for PKG creation.", MsgBoxStyle.Information)
+
+ 'Create the fPKG
+ Dim PKGBuilderProcessOutput As String = ""
+ Dim PKGBuilderProcess As New Process()
+ PKGBuilderProcess.StartInfo.FileName = My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\mod-pub\orbis-pub-cmd-3.38.exe"
+ PKGBuilderProcess.StartInfo.Arguments = "img_create --oformat pkg --skip_digest --no_progress_bar """ + My.Computer.FileSystem.CurrentDirectory + "\Cache\PS2fPKG.gp4"" """ + PKGOutputFolder + """"
+ PKGBuilderProcess.StartInfo.UseShellExecute = False
+ PKGBuilderProcess.StartInfo.RedirectStandardOutput = True
+ PKGBuilderProcess.StartInfo.CreateNoWindow = True
+ PKGBuilderProcess.Start()
+ PKGBuilderProcess.WaitForExit()
+
+ Using OutputStreamReader As StreamReader = PKGBuilderProcess.StandardOutput
+ PKGBuilderProcessOutput = OutputStreamReader.ReadToEnd()
+ End Using
+
+ If PKGBuilderProcessOutput.Contains("Create image Process finished with warning") Then
+ If MsgBox("PKG created!" + vbCrLf + "Do you want to open the output folder ?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
+ Process.Start("explorer", FBD.SelectedPath)
+ End If
+ Else
+ MsgBox("Error while creating the fPKG.", MsgBoxStyle.Critical)
+ MsgBox(PKGBuilderProcessOutput)
+ End If
+
+ Else
+ MsgBox("Aborted", MsgBoxStyle.Information)
+ End If
+ End Sub
+
+#End Region
+
+#Region "PSP"
+
+ Public Function FileExistInISO(GameISOPath As String, FileToSearch As String) As Boolean
+ Dim Exists As Boolean = False
+ Try
+ Using NewFileStream As New FileStream(GameISOPath, FileMode.Open, FileAccess.Read)
+ Dim NewIso9660CDReader As New Iso9660.CDReader(NewFileStream, True)
+ Try
+ NewIso9660CDReader.OpenFile(FileToSearch, FileMode.Open)
+ Exists = True
+ Catch exception As Exception
+ Exists = False
+ End Try
+ End Using
+ Catch exception1 As Exception
+ Exists = False
+ End Try
+ Return Exists
+ End Function
+
+ Public Function ExtractFileFromPSPISO(path As String, fileName As String, DestinationPath As String) As String
+ Dim OutputDestination As String = ""
+ Dim DesinationDirectoryName As String = IO.Path.GetDirectoryName(DestinationPath)
+ If Not Directory.Exists(DesinationDirectoryName) Then
+ Directory.CreateDirectory(DesinationDirectoryName)
+ End If
+ Try
+ Using NewFileStream As New FileStream(path, FileMode.Open, FileAccess.Read)
+ Dim NewIso9660CDReader As New Iso9660.CDReader(NewFileStream, True)
+ Try
+ Dim NewSparseStream As Streams.SparseStream = NewIso9660CDReader.OpenFile(fileName, FileMode.Open)
+ Dim OutputFileStream As New FileStream(DestinationPath, FileMode.Create)
+ NewSparseStream.CopyTo(OutputFileStream)
+ OutputFileStream.Close()
+ OutputDestination = DestinationPath
+ Catch ex As Exception
+ OutputDestination = ""
+ End Try
+ End Using
+ Catch ex As Exception
+ OutputDestination = ""
+ End Try
+ Return OutputDestination
+ End Function
+
+ Public Function ReadUMDData(DataFile As String, Offset As Long, Lenght As Integer) As Byte()
+ Dim NewByte(Lenght - 1 + 1 - 1) As Byte
+ Using NewBinaryReader As New BinaryReader(File.Open(DataFile, FileMode.Open))
+ Dim BaseStreamLenght As Long = NewBinaryReader.BaseStream.Length
+ Dim Num As Integer = 0
+ NewBinaryReader.BaseStream.Seek(Offset, SeekOrigin.Begin)
+ While Offset < BaseStreamLenght And Num < Lenght
+ NewByte(Num) = NewBinaryReader.ReadByte()
+ Offset += 1
+ Num += 1
+ End While
+ End Using
+ Return NewByte
+ End Function
+
+ Public Function FindOffset(FileName As String, Query As Byte()) As Object
+ Dim ReturnLenght As Object
+ Using NewBinaryReader As New BinaryReader(File.Open(FileName, FileMode.Open))
+ Dim BaseStreamLength As Double = NewBinaryReader.BaseStream.Length
+ If Query.Length <= BaseStreamLength Then
+
+ Dim NewByteArray As Byte() = NewBinaryReader.ReadBytes(Query.Length)
+ Dim Flag As Boolean = False
+ Dim NewQueryLenght As Integer = Query.Length - 1
+ Dim WhileInt As Integer = 0
+
+ While WhileInt <= NewQueryLenght
+ If NewByteArray(WhileInt) = Query(WhileInt) Then
+ Flag = True
+ WhileInt += 1
+ Else
+ Flag = False
+ Exit While
+ End If
+ End While
+
+ If Not Flag Then
+ Dim NewBaseStreamLength As Double = BaseStreamLength - 1
+ Dim QueryLenght As Double = Query.Length
+ While QueryLenght <= NewBaseStreamLength
+ Array.Copy(NewByteArray, 1, NewByteArray, 0, NewByteArray.Length - 1)
+ NewByteArray(NewByteArray.Length - 1) = NewBinaryReader.ReadByte()
+ Dim length3 As Integer = Query.Length - 1
+ Dim num3 As Integer = 0
+ While num3 <= length3
+ If NewByteArray(num3) = Query(num3) Then
+ Flag = True
+ num3 += 1
+ Else
+ Flag = False
+ Exit While
+ End If
+ End While
+ If Not Flag Then
+ QueryLenght += 1
+ Else
+ ReturnLenght = QueryLenght - (Query.Length - 1)
+ Return ReturnLenght
+ End If
+ End While
+ Else
+ ReturnLenght = 0
+ Return ReturnLenght
+ End If
+ End If
+ End Using
+ ReturnLenght = -1
+ Return ReturnLenght
+ End Function
+
+ Public Sub WriteData(FileToWrite As String, Offset As Long, DataToWrite As String)
+ Dim NewFileStream As New FileStream(FileToWrite, FileMode.Open, FileAccess.Write, FileShare.Write)
+ Dim NewStringArray As String() = DataToWrite.Split(New Char() {"-"c})
+ NewFileStream.Seek(Offset, SeekOrigin.Begin)
+ Dim DoInt As Integer = 0
+ Do
+ Dim str As String = NewStringArray(DoInt)
+ NewFileStream.WriteByte(Convert.ToByte(Convert.ToInt32(str, 16)))
+ DoInt += 1
+ Loop While DoInt < NewStringArray.Length
+ NewFileStream.Close()
+ End Sub
+
+ Private Sub BrowsePSPIconButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePSPIconButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PNG icon file.", .Multiselect = False, .Filter = "PNG (*.png)|*.png"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPSPIconTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePSPBGButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePSPBGButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PNG background file.", .Multiselect = False, .Filter = "PNG (*.png)|*.png"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPSPBGImageTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BrowsePSPDiscButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePSPDiscButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a PSP ISO file.", .Multiselect = False, .Filter = "ISO (*.iso)|*.iso"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+
+ If FileExistInISO(OFD.FileName, "\PSP_GAME\PARAM.SFO") Then
+ Dim CacheDir As String = My.Computer.FileSystem.CurrentDirectory + ""
+ Dim ExtractedUMDDataPath As String = ExtractFileFromPSPISO(OFD.FileName, "UMD_DATA.BIN", CacheDir + "\temp_umd_data.bin")
+
+ If Not String.IsNullOrEmpty(ExtractedUMDDataPath) Then
+ PSPNPTitleTextBox.Text = Text.Encoding.ASCII.GetString(ReadUMDData(CacheDir + "\temp_umd_data.bin", 0, 10)).Replace("-", "")
+ PSPTitleTextBox.Text = Regex.Replace(Path.GetFileNameWithoutExtension(OFD.FileName), "\((.*?)\)", "")
+ PSPTitleTextBox.Text = Regex.Replace(PSPTitleTextBox.Text, " {2,}", "")
+ End If
+
+ SelectedPSPDiscTextBox.Text = OFD.FileName
+ Else
+ If MsgBox("Could not find any PSP game information within the ISO file." + vbCrLf + "Do you want to use this file anyway ?", MsgBoxStyle.YesNo, "Unknown PSP ISO file") = MsgBoxResult.Yes Then
+ SelectedPSPDiscTextBox.Text = OFD.FileName
+ End If
+ End If
+
+ End If
+ End Sub
+
+ Private Sub BrowsePSPConfigButton_Click(sender As Object, e As RoutedEventArgs) Handles BrowsePSPConfigButton.Click
+ Dim OFD As New OpenFileDialog() With {.Title = "Select a config-title.txt file.", .Multiselect = False, .Filter = "TXT (*.txt)|*.txt"}
+ If OFD.ShowDialog() = Forms.DialogResult.OK Then
+ SelectedPSPConfigTextBox.Text = OFD.FileName
+ End If
+ End Sub
+
+ Private Sub BuildPSPfPKGButton_Click(sender As Object, e As RoutedEventArgs) Handles BuildPSPfPKGButton.Click
+
+ 'Checks before fPKG creation
+ If String.IsNullOrEmpty(SelectedPSPDiscTextBox.Text) Then
+ MsgBox("No disc 1 specified, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+ If String.IsNullOrEmpty(PSPTitleTextBox.Text) Then
+ MsgBox("No game title specified, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+ If String.IsNullOrEmpty(PSPNPTitleTextBox.Text) Then
+ MsgBox("No NP title specified, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+ If PSPNPTitleTextBox.Text.Length <> 9 Then
+ MsgBox("'NP Title' length mismatching, only 9 characters are allowed, fPKG creation will be aborted.", MsgBoxStyle.Critical, "Cannot create fPKG")
+ Exit Sub
+ End If
+
+ Dim FBD As New FolderBrowserDialog() With {.Description = "Please select an output folder", .ShowNewFolderButton = True}
+ If FBD.ShowDialog() = Forms.DialogResult.OK Then
+
+ Dim CacheDirectory As String = My.Computer.FileSystem.CurrentDirectory + "\Cache"
+ Dim GameCacheDirectory As String = My.Computer.FileSystem.CurrentDirectory + "\Cache\PSPfPKG"
+ Dim SelectedISOFile As String = SelectedPSPDiscTextBox.Text
+
+ 'Remove previous fPKG creation & re-create the PSPfPKG cache folder
+ If Directory.Exists(GameCacheDirectory) Then
+ Directory.Delete(GameCacheDirectory, True)
+ End If
+ If File.Exists(My.Computer.FileSystem.CurrentDirectory + "\Cache\PSPfPKG.gp4") Then
+ File.Delete(My.Computer.FileSystem.CurrentDirectory + "\Cache\PSPfPKG.gp4")
+ End If
+ Directory.CreateDirectory(GameCacheDirectory)
+
+ 'Copy the selected PS2 emulator to the cache directory
+ My.Computer.FileSystem.CopyDirectory(My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\emus\psphd", GameCacheDirectory, True)
+
+ 'Get PSP EBOOT
+ If Not File.Exists(ExtractFileFromPSPISO(SelectedISOFile, "\PSP_GAME\SYSDIR\EBOOT.BIN", CacheDirectory + "\temp_eboot.bin")) Then
+ File.Copy(SelectedISOFile, GameCacheDirectory + "\data\USER_L0.IMG", True)
+ MsgBox("Cannot read the EBOOT.BIN file from the ISO." + vbCrLf + "Warning: This game may not work!", MsgBoxStyle.Exclamation)
+ Else
+ Dim NewProcess As New Process()
+ NewProcess.StartInfo.FileName = My.Computer.FileSystem.CurrentDirectory + "\Tools\pspdecrypt.exe"
+ NewProcess.StartInfo.Arguments = """" + CacheDirectory + "\temp_eboot.bin"""
+ NewProcess.StartInfo.CreateNoWindow = True
+ NewProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
+ NewProcess.Start()
+ NewProcess.WaitForExit()
+
+ File.Copy(SelectedISOFile, GameCacheDirectory + "\data\USER_L0.IMG", True)
+
+ Dim NewFileInfo As New FileInfo(CacheDirectory + "\temp_eboot.bin")
+ Dim FileLength As Long = NewFileInfo.Length
+ If FileLength > 512320 Then
+ FileLength = 512320
+ End If
+
+ Dim TempEBOOTByteArray As Byte() = ReadUMDData(CacheDirectory + "\temp_eboot.bin", 0, CInt(FileLength))
+ Dim OffsetValue As Object = RuntimeHelpers.GetObjectValue(FindOffset(GameCacheDirectory + "\data\USER_L0.IMG", TempEBOOTByteArray))
+ Dim DecTempEBOOTByteArray As Byte() = ReadUMDData(CacheDirectory + "\temp_eboot.bin.dec", 0, CInt(NewFileInfo.Length))
+
+ WriteData(GameCacheDirectory + "\data\USER_L0.IMG", CLng(OffsetValue), BitConverter.ToString(DecTempEBOOTByteArray))
+ End If
+
+ 'Remove temp files
+ If File.Exists(CacheDirectory + "\temp_eboot.bin") Then
+ File.Delete(CacheDirectory + "\temp_eboot.bin")
+ End If
+ If File.Exists(CacheDirectory + "\temp_eboot.bin.dec") Then
+ File.Delete(CacheDirectory + "\temp_eboot.bin.dec")
+ End If
+ If File.Exists(GameCacheDirectory + "\sce_sys\icon0.png") Then
+ File.Delete(GameCacheDirectory + "\sce_sys\icon0.png")
+ End If
+ If File.Exists(GameCacheDirectory + "\sce_sys\pic1.png") Then
+ File.Delete(GameCacheDirectory + "\sce_sys\pic1.png")
+ End If
+
+ 'Copy the selected icon and background to the cache directory
+ If Not Directory.Exists(GameCacheDirectory + "\sce_sys") Then
+ Directory.CreateDirectory(GameCacheDirectory + "\sce_sys")
+ End If
+ If Not String.IsNullOrEmpty(SelectedPSPIconTextBox.Text) Then
+ Using NewFileStream As New FileStream(SelectedPSPIconTextBox.Text, FileMode.Open, FileAccess.Read)
+ Utils.ConvertTo24bppPNG(Utils.ResizeAsImage(System.Drawing.Image.FromStream(NewFileStream), 512, 512)).Save(GameCacheDirectory + "\sce_sys\icon0.png", ImageFormat.Png)
+ End Using
+ End If
+ If Not String.IsNullOrEmpty(SelectedPSPBGImageTextBox.Text) Then
+ Using NewFileStream As New FileStream(SelectedPSPBGImageTextBox.Text, FileMode.Open, FileAccess.Read)
+ Utils.ConvertTo24bppPNG(Utils.ResizeAsImage(System.Drawing.Image.FromStream(NewFileStream), 1920, 1080)).Save(GameCacheDirectory + "\sce_sys\pic0.png", ImageFormat.Png)
+ End Using
+ End If
+
+ 'PSP Emulator configuration
+ Dim EmulatorConfig As String = String.Concat("--ps4-trophies=0" + vbCrLf +
+ "--ps5-uds=0" + vbCrLf +
+ "--trophies=0" + vbCrLf +
+ "--image=""data/USER_L0.IMG""" + vbCrLf +
+ "--antialias=SSAA4x" + vbCrLf +
+ "--multisaves=true" + vbCrLf +
+ "--notrophies=true" + vbCrLf +
+ "" + vbCrLf + "")
+
+ If File.Exists(GameCacheDirectory + "/config-title.txt") Then
+ File.Delete(GameCacheDirectory + "/config-title.txt")
+ End If
+ File.WriteAllText(GameCacheDirectory + "/config-title.txt", EmulatorConfig)
+ If Not String.IsNullOrEmpty(SelectedPSPConfigTextBox.Text) Then
+ File.AppendAllText(GameCacheDirectory + "/config-title.txt", File.ReadAllText(SelectedPSPConfigTextBox.Text))
+ End If
+
+ 'Create a new PARAM.SFO file
+ Dim NewPS4ParamSFO As New ParamSfo()
+ NewPS4ParamSFO.SetValue("APP_TYPE", SfoEntryType.Integer, "1", 4)
+ NewPS4ParamSFO.SetValue("APP_VER", SfoEntryType.Utf8, "01.00", 8)
+ NewPS4ParamSFO.SetValue("ATTRIBUTE", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("CATEGORY", SfoEntryType.Utf8, "gd", 4)
+ NewPS4ParamSFO.SetValue("CONTENT_ID", SfoEntryType.Utf8, String.Concat(New String() {"UP9000-", PSPNPTitleTextBox.Text, "_00-", PSPNPTitleTextBox.Text, "PSPFPKG"}), 48)
+ NewPS4ParamSFO.SetValue("DOWNLOAD_DATA_SIZE", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("FORMAT", SfoEntryType.Utf8, "obs", 4)
+ NewPS4ParamSFO.SetValue("PARENTAL_LEVEL", SfoEntryType.Integer, "5", 4)
+ NewPS4ParamSFO.SetValue("SYSTEM_VER", SfoEntryType.Integer, "0", 4)
+ NewPS4ParamSFO.SetValue("TITLE", SfoEntryType.Utf8, PSPTitleTextBox.Text, 128)
+ NewPS4ParamSFO.SetValue("TITLE_ID", SfoEntryType.Utf8, PSPNPTitleTextBox.Text, 12)
+ NewPS4ParamSFO.SetValue("VERSION", SfoEntryType.Utf8, "01.00", 8)
+
+ File.WriteAllBytes(GameCacheDirectory + "\sce_sys\param.sfo", NewPS4ParamSFO.Serialize())
+
+ 'Create a GP4 project
+ Dim GenGP4Process As New Process()
+ GenGP4Process.StartInfo.FileName = My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\gengp4_patch.exe"
+ GenGP4Process.StartInfo.Arguments = """" + GameCacheDirectory + """"
+ GenGP4Process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
+ GenGP4Process.Start()
+ GenGP4Process.WaitForExit()
+
+ File.WriteAllText(CacheDirectory + "\PSPfPKG.gp4", File.ReadAllText(CacheDirectory + "\PSPfPKG.gp4").Replace("", ""))
+
+ MsgBox("All files ready for PKG creation.", MsgBoxStyle.Information)
+
+ Dim PKGBuilderProcessOutput As String = ""
+ Dim PKGBuilderProcess As New Process()
+ PKGBuilderProcess.StartInfo.FileName = My.Computer.FileSystem.CurrentDirectory + "\Tools\PS4\mod-pub\orbis-pub-cmd-3.38.exe"
+ PKGBuilderProcess.StartInfo.Arguments = "img_create --oformat pkg --skip_digest --no_progress_bar """ + CacheDirectory + "\PSPfPKG.gp4"" """ + FBD.SelectedPath + """"
+ PKGBuilderProcess.StartInfo.UseShellExecute = False
+ PKGBuilderProcess.StartInfo.RedirectStandardOutput = True
+ PKGBuilderProcess.StartInfo.CreateNoWindow = True
+ PKGBuilderProcess.Start()
+ PKGBuilderProcess.WaitForExit()
+
+ Using standardOutput As StreamReader = PKGBuilderProcess.StandardOutput
+ PKGBuilderProcessOutput = standardOutput.ReadToEnd()
+ End Using
+
+ If Not PKGBuilderProcessOutput.Contains("Create image Process finished with warning") Then
+ MsgBox(PKGBuilderProcessOutput)
+ Else
+ If MsgBox("PKG created!" + vbCrLf + "Do you want to open the output folder ?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
+ Process.Start("explorer", FBD.SelectedPath)
+ End If
+ End If
+
+ End If
+
+ End Sub
+
+#End Region
+
+End Class
diff --git a/Windows/PS Classics fPKG Builder/Utils.vb b/Windows/PS Classics fPKG Builder/Utils.vb
new file mode 100644
index 0000000..2d5d81f
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/Utils.vb
@@ -0,0 +1,17 @@
+Imports System.Drawing
+
+Public Class Utils
+
+ Public Shared Function ResizeAsImage(InputImage As Image, NewSizeX As Integer, NewSizeY As Integer) As Image
+ Return New Bitmap(InputImage, New Size(NewSizeX, NewSizeY))
+ End Function
+
+ Public Shared Function ConvertTo24bppPNG(ImageToConvert As Image) As Bitmap
+ Dim NewBitmap As New Bitmap(ImageToConvert.Width, ImageToConvert.Height, Imaging.PixelFormat.Format24bppRgb)
+ Using NewGraphics As Graphics = Graphics.FromImage(NewBitmap)
+ NewGraphics.DrawImage(ImageToConvert, New Rectangle(0, 0, ImageToConvert.Width, ImageToConvert.Height))
+ End Using
+ Return NewBitmap
+ End Function
+
+End Class
diff --git a/Windows/PS Classics fPKG Builder/packages.config b/Windows/PS Classics fPKG Builder/packages.config
new file mode 100644
index 0000000..ae09fb3
--- /dev/null
+++ b/Windows/PS Classics fPKG Builder/packages.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Windows/PS Classics fPKG Builder/v14Icon.ico b/Windows/PS Classics fPKG Builder/v14Icon.ico
new file mode 100644
index 0000000..5de5be1
Binary files /dev/null and b/Windows/PS Classics fPKG Builder/v14Icon.ico differ