feature: Added psxsplash installer, added basic BSP implementation (non-functional)
This commit is contained in:
@@ -2,214 +2,521 @@ using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using SplashEdit.RuntimeCode;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class InstallerWindow : EditorWindow
|
||||
|
||||
namespace SplashEdit.EditorCode
|
||||
{
|
||||
// Cached status for MIPS toolchain binaries.
|
||||
private Dictionary<string, bool> mipsToolStatus = new Dictionary<string, bool>();
|
||||
|
||||
// Cached status for optional tools.
|
||||
private bool makeInstalled;
|
||||
private bool gdbInstalled;
|
||||
private string pcsxReduxPath;
|
||||
|
||||
private bool isInstalling = false;
|
||||
|
||||
[MenuItem("PSX/Toolchain & Build Tools Installer")]
|
||||
public static void ShowWindow()
|
||||
public class InstallerWindow : EditorWindow
|
||||
{
|
||||
InstallerWindow window = GetWindow<InstallerWindow>("Toolchain Installer");
|
||||
window.RefreshToolStatus();
|
||||
window.pcsxReduxPath = DataStorage.LoadData().PCSXReduxPath;
|
||||
}
|
||||
// Cached status for MIPS toolchain binaries.
|
||||
private Dictionary<string, bool> mipsToolStatus = new Dictionary<string, bool>();
|
||||
|
||||
/// <summary>
|
||||
/// Refresh the cached statuses for all tools.
|
||||
/// </summary>
|
||||
private void RefreshToolStatus()
|
||||
{
|
||||
mipsToolStatus.Clear();
|
||||
foreach (var tool in ToolchainChecker.GetRequiredTools())
|
||||
// Cached status for optional tools.
|
||||
private bool makeInstalled;
|
||||
private bool gdbInstalled;
|
||||
private string pcsxReduxPath;
|
||||
|
||||
// PSXSplash related variables
|
||||
private bool psxsplashInstalled = false;
|
||||
private bool psxsplashInstalling = false;
|
||||
private bool psxsplashFetching = false;
|
||||
private string selectedVersion = "main";
|
||||
private Dictionary<string, string> availableBranches = new Dictionary<string, string>();
|
||||
private List<string> availableReleases = new List<string>();
|
||||
private bool showBranches = true;
|
||||
private bool showReleases = false;
|
||||
private Vector2 scrollPosition;
|
||||
private Vector2 versionScrollPosition;
|
||||
|
||||
private bool isInstalling = false;
|
||||
|
||||
[MenuItem("PSX/Toolchain & Build Tools Installer")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
mipsToolStatus[tool] = ToolchainChecker.IsToolAvailable(tool);
|
||||
InstallerWindow window = GetWindow<InstallerWindow>("Toolchain Installer");
|
||||
window.RefreshToolStatus();
|
||||
window.pcsxReduxPath = DataStorage.LoadData().PCSXReduxPath;
|
||||
window.CheckPSXSplashInstallation();
|
||||
}
|
||||
|
||||
makeInstalled = ToolchainChecker.IsToolAvailable("make");
|
||||
gdbInstalled = ToolchainChecker.IsToolAvailable("gdb-multiarch");
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
GUILayout.Label("Toolchain & Build Tools Installer", EditorStyles.boldLabel);
|
||||
GUILayout.Space(5);
|
||||
|
||||
if (GUILayout.Button("Refresh Status"))
|
||||
/// <summary>
|
||||
/// Refresh the cached statuses for all tools.
|
||||
/// </summary>
|
||||
private void RefreshToolStatus()
|
||||
{
|
||||
RefreshToolStatus();
|
||||
}
|
||||
GUILayout.Space(10);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
DrawToolchainColumn();
|
||||
DrawAdditionalToolsColumn();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawToolchainColumn()
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.MaxWidth(position.width / 2 - 10));
|
||||
GUILayout.Label("MIPS Toolchain", EditorStyles.boldLabel);
|
||||
GUILayout.Space(5);
|
||||
|
||||
// Display cached status for each required MIPS tool.
|
||||
foreach (var kvp in mipsToolStatus)
|
||||
{
|
||||
GUI.color = kvp.Value ? Color.green : Color.red;
|
||||
GUILayout.Label($"{kvp.Key}: {(kvp.Value ? "Found" : "Missing")}");
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
GUILayout.Space(5);
|
||||
|
||||
if (GUILayout.Button("Install MIPS Toolchain"))
|
||||
{
|
||||
if (!isInstalling)
|
||||
InstallMipsToolchainAsync();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawAdditionalToolsColumn()
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.MaxWidth(position.width / 2 - 10));
|
||||
GUILayout.Label("Optional Tools", EditorStyles.boldLabel);
|
||||
GUILayout.Space(5);
|
||||
|
||||
// GNU Make status (required).
|
||||
GUI.color = makeInstalled ? Color.green : Color.red;
|
||||
GUILayout.Label($"GNU Make: {(makeInstalled ? "Found" : "Missing")} (Required)");
|
||||
GUI.color = Color.white;
|
||||
GUILayout.Space(5);
|
||||
if (GUILayout.Button("Install GNU Make"))
|
||||
{
|
||||
if (!isInstalling)
|
||||
InstallMakeAsync();
|
||||
}
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
// GDB status (optional).
|
||||
GUI.color = gdbInstalled ? Color.green : Color.red;
|
||||
GUILayout.Label($"GDB: {(gdbInstalled ? "Found" : "Missing")} (Optional)");
|
||||
GUI.color = Color.white;
|
||||
GUILayout.Space(5);
|
||||
if (GUILayout.Button("Install GDB"))
|
||||
{
|
||||
if (!isInstalling)
|
||||
InstallGDBAsync();
|
||||
}
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
// PCSX-Redux (manual install)
|
||||
GUI.color = string.IsNullOrEmpty(pcsxReduxPath) ? Color.red : Color.green;
|
||||
GUILayout.Label($"PCSX-Redux: {(string.IsNullOrEmpty(pcsxReduxPath) ? "Not Configured" : "Configured")} (Optional)");
|
||||
GUI.color = Color.white;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Browse for PCSX-Redux"))
|
||||
{
|
||||
string selectedPath = EditorUtility.OpenFilePanel("Select PCSX-Redux Executable", "", "");
|
||||
if (!string.IsNullOrEmpty(selectedPath))
|
||||
mipsToolStatus.Clear();
|
||||
foreach (var tool in ToolchainChecker.GetRequiredTools())
|
||||
{
|
||||
pcsxReduxPath = selectedPath;
|
||||
PSXData data = DataStorage.LoadData();
|
||||
data.PCSXReduxPath = pcsxReduxPath;
|
||||
DataStorage.StoreData(data);
|
||||
mipsToolStatus[tool] = ToolchainChecker.IsToolAvailable(tool);
|
||||
}
|
||||
|
||||
makeInstalled = ToolchainChecker.IsToolAvailable("make");
|
||||
gdbInstalled = ToolchainChecker.IsToolAvailable("gdb-multiarch");
|
||||
}
|
||||
|
||||
private void CheckPSXSplashInstallation()
|
||||
{
|
||||
psxsplashInstalled = PSXSplashInstaller.IsInstalled();
|
||||
|
||||
if (psxsplashInstalled)
|
||||
{
|
||||
FetchPSXSplashVersions();
|
||||
}
|
||||
else
|
||||
{
|
||||
availableBranches = new Dictionary<string, string>();
|
||||
availableReleases = new List<string>();
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(pcsxReduxPath))
|
||||
|
||||
private async void FetchPSXSplashVersions()
|
||||
{
|
||||
if (GUILayout.Button("Clear", GUILayout.Width(60)))
|
||||
if (psxsplashFetching) return;
|
||||
|
||||
psxsplashFetching = true;
|
||||
try
|
||||
{
|
||||
pcsxReduxPath = "";
|
||||
PSXData data = DataStorage.LoadData();
|
||||
data.PCSXReduxPath = pcsxReduxPath;
|
||||
DataStorage.StoreData(data);
|
||||
// Fetch latest from remote
|
||||
await PSXSplashInstaller.FetchLatestAsync();
|
||||
|
||||
// Get all available versions
|
||||
var branchesTask = PSXSplashInstaller.GetBranchesWithLatestCommitsAsync();
|
||||
var releasesTask = PSXSplashInstaller.GetReleasesAsync();
|
||||
|
||||
await Task.WhenAll(branchesTask, releasesTask);
|
||||
|
||||
availableBranches = branchesTask.Result;
|
||||
availableReleases = releasesTask.Result;
|
||||
|
||||
// If no branches were found, add main as default
|
||||
if (!availableBranches.Any())
|
||||
{
|
||||
availableBranches["main"] = "latest";
|
||||
}
|
||||
|
||||
// Select the first branch by default
|
||||
if (availableBranches.Any() && string.IsNullOrEmpty(selectedVersion))
|
||||
{
|
||||
selectedVersion = availableBranches.Keys.First();
|
||||
}
|
||||
|
||||
Repaint();
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Failed to fetch PSXSplash versions: {e.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
psxsplashFetching = false;
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private async void InstallMipsToolchainAsync()
|
||||
{
|
||||
try
|
||||
private void OnGUI()
|
||||
{
|
||||
isInstalling = true;
|
||||
EditorUtility.DisplayProgressBar("Installing MIPS Toolchain",
|
||||
"Please wait while the MIPS toolchain is being installed...", 0f);
|
||||
bool success = await ToolchainInstaller.InstallToolchain();
|
||||
EditorUtility.ClearProgressBar();
|
||||
if (success)
|
||||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||||
|
||||
GUILayout.Label("Toolchain & Build Tools Installer", EditorStyles.boldLabel);
|
||||
GUILayout.Space(5);
|
||||
|
||||
if (GUILayout.Button("Refresh Status"))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Installation Complete", "MIPS toolchain installed successfully.", "OK");
|
||||
RefreshToolStatus();
|
||||
CheckPSXSplashInstallation();
|
||||
}
|
||||
RefreshToolStatus(); // Update cached statuses after installation
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Failed", $"Error: {ex.Message}", "OK");
|
||||
}
|
||||
finally
|
||||
{
|
||||
isInstalling = false;
|
||||
}
|
||||
}
|
||||
GUILayout.Space(10);
|
||||
|
||||
private async void InstallMakeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
isInstalling = true;
|
||||
EditorUtility.DisplayProgressBar("Installing GNU Make",
|
||||
"Please wait while GNU Make is being installed...", 0f);
|
||||
await ToolchainInstaller.InstallMake();
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Complete", "GNU Make installed successfully.", "OK");
|
||||
RefreshToolStatus();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Failed", $"Error: {ex.Message}", "OK");
|
||||
}
|
||||
finally
|
||||
{
|
||||
isInstalling = false;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
DrawToolchainColumn();
|
||||
DrawAdditionalToolsColumn();
|
||||
DrawPSXSplashColumn();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
private async void InstallGDBAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
isInstalling = true;
|
||||
EditorUtility.DisplayProgressBar("Installing GDB",
|
||||
"Please wait while GDB is being installed...", 0f);
|
||||
await ToolchainInstaller.InstallGDB();
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Complete", "GDB installed successfully.", "OK");
|
||||
RefreshToolStatus();
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
|
||||
private void DrawToolchainColumn()
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Failed", $"Error: {ex.Message}", "OK");
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.MaxWidth(position.width / 3 - 10));
|
||||
GUILayout.Label("MIPS Toolchain", EditorStyles.boldLabel);
|
||||
GUILayout.Space(5);
|
||||
|
||||
// Display cached status for each required MIPS tool.
|
||||
foreach (var kvp in mipsToolStatus)
|
||||
{
|
||||
GUI.color = kvp.Value ? Color.green : Color.red;
|
||||
GUILayout.Label($"{kvp.Key}: {(kvp.Value ? "Found" : "Missing")}");
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
GUILayout.Space(5);
|
||||
|
||||
if (GUILayout.Button("Install MIPS Toolchain"))
|
||||
{
|
||||
if (!isInstalling)
|
||||
InstallMipsToolchainAsync();
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
finally
|
||||
|
||||
private void DrawAdditionalToolsColumn()
|
||||
{
|
||||
isInstalling = false;
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.MaxWidth(position.width / 3 - 10));
|
||||
GUILayout.Label("Optional Tools", EditorStyles.boldLabel);
|
||||
GUILayout.Space(5);
|
||||
|
||||
// GNU Make status (required).
|
||||
GUI.color = makeInstalled ? Color.green : Color.red;
|
||||
GUILayout.Label($"GNU Make: {(makeInstalled ? "Found" : "Missing")} (Required)");
|
||||
GUI.color = Color.white;
|
||||
GUILayout.Space(5);
|
||||
if (GUILayout.Button("Install GNU Make"))
|
||||
{
|
||||
if (!isInstalling)
|
||||
InstallMakeAsync();
|
||||
}
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
// GDB status (optional).
|
||||
GUI.color = gdbInstalled ? Color.green : Color.red;
|
||||
GUILayout.Label($"GDB: {(gdbInstalled ? "Found" : "Missing")} (Optional)");
|
||||
GUI.color = Color.white;
|
||||
GUILayout.Space(5);
|
||||
if (GUILayout.Button("Install GDB"))
|
||||
{
|
||||
if (!isInstalling)
|
||||
InstallGDBAsync();
|
||||
}
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
// PCSX-Redux (manual install)
|
||||
GUI.color = string.IsNullOrEmpty(pcsxReduxPath) ? Color.red : Color.green;
|
||||
GUILayout.Label($"PCSX-Redux: {(string.IsNullOrEmpty(pcsxReduxPath) ? "Not Configured" : "Configured")} (Optional)");
|
||||
GUI.color = Color.white;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Browse for PCSX-Redux"))
|
||||
{
|
||||
string selectedPath = EditorUtility.OpenFilePanel("Select PCSX-Redux Executable", "", "");
|
||||
if (!string.IsNullOrEmpty(selectedPath))
|
||||
{
|
||||
pcsxReduxPath = selectedPath;
|
||||
PSXData data = DataStorage.LoadData();
|
||||
data.PCSXReduxPath = pcsxReduxPath;
|
||||
DataStorage.StoreData(data);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(pcsxReduxPath))
|
||||
{
|
||||
if (GUILayout.Button("Clear", GUILayout.Width(60)))
|
||||
{
|
||||
pcsxReduxPath = "";
|
||||
PSXData data = DataStorage.LoadData();
|
||||
data.PCSXReduxPath = pcsxReduxPath;
|
||||
DataStorage.StoreData(data);
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawPSXSplashColumn()
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box", GUILayout.MaxWidth(position.width / 3 - 10));
|
||||
GUILayout.Label("PSXSplash", EditorStyles.boldLabel);
|
||||
GUILayout.Space(5);
|
||||
|
||||
// PSXSplash status
|
||||
GUI.color = psxsplashInstalled ? Color.green : Color.red;
|
||||
GUILayout.Label($"PSXSplash: {(psxsplashInstalled ? "Installed" : "Not Installed")}");
|
||||
GUI.color = Color.white;
|
||||
|
||||
if (psxsplashFetching)
|
||||
{
|
||||
GUILayout.Label("Fetching versions...");
|
||||
}
|
||||
else if (!psxsplashInstalled)
|
||||
{
|
||||
GUILayout.Space(5);
|
||||
EditorGUILayout.HelpBox("Git is required to install PSXSplash. Make sure it's installed and available in your PATH.", MessageType.Info);
|
||||
|
||||
// Show version selection even before installation
|
||||
DrawVersionSelection();
|
||||
|
||||
if (GUILayout.Button("Install PSXSplash") && !psxsplashInstalling)
|
||||
{
|
||||
InstallPSXSplashAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
|
||||
// Current version
|
||||
EditorGUILayout.LabelField($"Current Version: {selectedVersion}", EditorStyles.boldLabel);
|
||||
|
||||
// Version selection
|
||||
DrawVersionSelection();
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
// Refresh and update buttons
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Refresh Versions"))
|
||||
{
|
||||
FetchPSXSplashVersions();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Update PSXSplash"))
|
||||
{
|
||||
UpdatePSXSplashAsync();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
private void DrawVersionSelection()
|
||||
{
|
||||
EditorGUILayout.LabelField("Available Versions:", EditorStyles.boldLabel);
|
||||
|
||||
versionScrollPosition = EditorGUILayout.BeginScrollView(versionScrollPosition, GUILayout.Height(200));
|
||||
|
||||
// Branches (with latest commits)
|
||||
showBranches = EditorGUILayout.Foldout(showBranches, $"Branches ({availableBranches.Count})");
|
||||
if (showBranches && availableBranches.Any())
|
||||
{
|
||||
foreach (var branch in availableBranches)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
bool isSelected = selectedVersion == branch.Key;
|
||||
if (GUILayout.Toggle(isSelected, "", GUILayout.Width(20)) && !isSelected)
|
||||
{
|
||||
selectedVersion = branch.Key;
|
||||
if (psxsplashInstalled)
|
||||
{
|
||||
CheckoutPSXSplashVersionAsync(branch.Key);
|
||||
}
|
||||
}
|
||||
GUILayout.Label($"{branch.Key} (Latest: {branch.Value})", EditorStyles.label);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
else if (showBranches)
|
||||
{
|
||||
GUILayout.Label("No branches available");
|
||||
}
|
||||
|
||||
// Releases
|
||||
showReleases = EditorGUILayout.Foldout(showReleases, $"Releases ({availableReleases.Count})");
|
||||
if (showReleases && availableReleases.Any())
|
||||
{
|
||||
foreach (var release in availableReleases)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
bool isSelected = selectedVersion == release;
|
||||
if (GUILayout.Toggle(isSelected, "", GUILayout.Width(20)) && !isSelected)
|
||||
{
|
||||
selectedVersion = release;
|
||||
if (psxsplashInstalled)
|
||||
{
|
||||
CheckoutPSXSplashVersionAsync(release);
|
||||
}
|
||||
}
|
||||
GUILayout.Label(release, EditorStyles.label);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
else if (showReleases)
|
||||
{
|
||||
GUILayout.Label("No releases available");
|
||||
}
|
||||
|
||||
EditorGUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
private async void InstallPSXSplashAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
psxsplashInstalling = true;
|
||||
EditorUtility.DisplayProgressBar("Installing PSXSplash", "Cloning repository...", 0.3f);
|
||||
|
||||
bool success = await PSXSplashInstaller.Install();
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
|
||||
if (success)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Installation Complete", "PSXSplash installed successfully.", "OK");
|
||||
CheckPSXSplashInstallation();
|
||||
|
||||
// Checkout the selected version after installation
|
||||
if (!string.IsNullOrEmpty(selectedVersion))
|
||||
{
|
||||
await CheckoutPSXSplashVersionAsync(selectedVersion);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Installation Failed",
|
||||
"Failed to install PSXSplash. Make sure Git is installed and available in your PATH.", "OK");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Failed", $"Error: {ex.Message}", "OK");
|
||||
}
|
||||
finally
|
||||
{
|
||||
psxsplashInstalling = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> CheckoutPSXSplashVersionAsync(string version)
|
||||
{
|
||||
try
|
||||
{
|
||||
psxsplashInstalling = true;
|
||||
EditorUtility.DisplayProgressBar("Checking Out Version", $"Switching to {version}...", 0.3f);
|
||||
|
||||
bool success = await PSXSplashInstaller.CheckoutVersionAsync(version);
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
|
||||
if (success)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Checkout Complete", $"Switched to {version} successfully.", "OK");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Checkout Failed",
|
||||
$"Failed to switch to {version}.", "OK");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Checkout Failed", $"Error: {ex.Message}", "OK");
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
psxsplashInstalling = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async void UpdatePSXSplashAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
psxsplashInstalling = true;
|
||||
EditorUtility.DisplayProgressBar("Updating PSXSplash", "Pulling latest changes...", 0.3f);
|
||||
|
||||
// Pull the latest changes
|
||||
bool success = await PSXSplashInstaller.CheckoutVersionAsync(selectedVersion);
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
|
||||
if (success)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Update Complete", "PSXSplash updated successfully.", "OK");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Update Failed",
|
||||
"Failed to update PSXSplash.", "OK");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Update Failed", $"Error: {ex.Message}", "OK");
|
||||
}
|
||||
finally
|
||||
{
|
||||
psxsplashInstalling = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async void InstallMipsToolchainAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
isInstalling = true;
|
||||
EditorUtility.DisplayProgressBar("Installing MIPS Toolchain",
|
||||
"Please wait while the MIPS toolchain is being installed...", 0f);
|
||||
bool success = await ToolchainInstaller.InstallToolchain();
|
||||
EditorUtility.ClearProgressBar();
|
||||
if (success)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Installation Complete", "MIPS toolchain installed successfully.", "OK");
|
||||
}
|
||||
RefreshToolStatus(); // Update cached statuses after installation
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Failed", $"Error: {ex.Message}", "OK");
|
||||
}
|
||||
finally
|
||||
{
|
||||
isInstalling = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async void InstallMakeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
isInstalling = true;
|
||||
EditorUtility.DisplayProgressBar("Installing GNU Make",
|
||||
"Please wait while GNU Make is being installed...", 0f);
|
||||
await ToolchainInstaller.InstallMake();
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Complete", "GNU Make installed successfully.", "OK");
|
||||
RefreshToolStatus();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Failed", $"Error: {ex.Message}", "OK");
|
||||
}
|
||||
finally
|
||||
{
|
||||
isInstalling = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async void InstallGDBAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
isInstalling = true;
|
||||
EditorUtility.DisplayProgressBar("Installing GDB",
|
||||
"Please wait while GDB is being installed...", 0f);
|
||||
await ToolchainInstaller.InstallGDB();
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Complete", "GDB installed successfully.", "OK");
|
||||
RefreshToolStatus();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
EditorUtility.ClearProgressBar();
|
||||
EditorUtility.DisplayDialog("Installation Failed", $"Error: {ex.Message}", "OK");
|
||||
}
|
||||
finally
|
||||
{
|
||||
isInstalling = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
203
Editor/PSXSplashInstaller.cs
Normal file
203
Editor/PSXSplashInstaller.cs
Normal file
@@ -0,0 +1,203 @@
|
||||
using UnityEngine;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
|
||||
namespace SplashEdit.EditorCode
|
||||
{
|
||||
|
||||
public static class PSXSplashInstaller
|
||||
{
|
||||
public static readonly string RepoUrl = "https://github.com/psxsplash/psxsplash.git";
|
||||
public static readonly string InstallPath = "Assets/psxsplash";
|
||||
public static readonly string FullInstallPath;
|
||||
|
||||
static PSXSplashInstaller()
|
||||
{
|
||||
FullInstallPath = Path.Combine(Application.dataPath, "psxsplash");
|
||||
}
|
||||
|
||||
public static bool IsInstalled()
|
||||
{
|
||||
return Directory.Exists(FullInstallPath) &&
|
||||
Directory.EnumerateFileSystemEntries(FullInstallPath).Any();
|
||||
}
|
||||
|
||||
public static async Task<bool> Install()
|
||||
{
|
||||
if (IsInstalled()) return true;
|
||||
|
||||
try
|
||||
{
|
||||
// Create the parent directory if it doesn't exist
|
||||
Directory.CreateDirectory(Application.dataPath);
|
||||
|
||||
// Clone the repository
|
||||
var result = await RunGitCommandAsync($"clone --recursive {RepoUrl} \"{FullInstallPath}\"", Application.dataPath);
|
||||
return !result.Contains("error");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Failed to install PSXSplash: {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<Dictionary<string, string>> GetBranchesWithLatestCommitsAsync()
|
||||
{
|
||||
if (!IsInstalled()) return new Dictionary<string, string>();
|
||||
|
||||
try
|
||||
{
|
||||
// Fetch all branches and tags
|
||||
await RunGitCommandAsync("fetch --all", FullInstallPath);
|
||||
|
||||
// Get all remote branches
|
||||
var branchesOutput = await RunGitCommandAsync("branch -r", FullInstallPath);
|
||||
var branches = branchesOutput.Split('\n')
|
||||
.Where(b => !string.IsNullOrEmpty(b.Trim()))
|
||||
.Select(b => b.Trim().Replace("origin/", ""))
|
||||
.Where(b => !b.Contains("HEAD"))
|
||||
.ToList();
|
||||
|
||||
var branchesWithCommits = new Dictionary<string, string>();
|
||||
|
||||
// Get the latest commit for each branch
|
||||
foreach (var branch in branches)
|
||||
{
|
||||
var commitOutput = await RunGitCommandAsync($"log origin/{branch} -1 --pretty=format:%h", FullInstallPath);
|
||||
if (!string.IsNullOrEmpty(commitOutput))
|
||||
{
|
||||
branchesWithCommits[branch] = commitOutput.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
return branchesWithCommits;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Failed to get branches: {e.Message}");
|
||||
return new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<List<string>> GetReleasesAsync()
|
||||
{
|
||||
if (!IsInstalled()) return new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
await RunGitCommandAsync("fetch --tags", FullInstallPath);
|
||||
var output = await RunGitCommandAsync("tag -l", FullInstallPath);
|
||||
|
||||
return output.Split('\n')
|
||||
.Where(t => !string.IsNullOrEmpty(t.Trim()))
|
||||
.Select(t => t.Trim())
|
||||
.ToList();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Failed to get releases: {e.Message}");
|
||||
return new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<bool> CheckoutVersionAsync(string version)
|
||||
{
|
||||
if (!IsInstalled()) return false;
|
||||
|
||||
try
|
||||
{
|
||||
// If it's a branch name, checkout the branch
|
||||
// If it's a commit hash, checkout the commit
|
||||
var result = await RunGitCommandAsync($"checkout {version}", FullInstallPath);
|
||||
var result2 = await RunGitCommandAsync("submodule update --init --recursive", FullInstallPath);
|
||||
|
||||
return !result.Contains("error") && !result2.Contains("error");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Failed to checkout version: {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<bool> FetchLatestAsync()
|
||||
{
|
||||
if (!IsInstalled()) return false;
|
||||
|
||||
try
|
||||
{
|
||||
var result = await RunGitCommandAsync("fetch --all", FullInstallPath);
|
||||
return !result.Contains("error");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Failed to fetch latest: {e.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<string> RunGitCommandAsync(string arguments, string workingDirectory)
|
||||
{
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "git",
|
||||
Arguments = arguments,
|
||||
WorkingDirectory = workingDirectory,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using (var process = new Process())
|
||||
{
|
||||
process.StartInfo = processInfo;
|
||||
var outputBuilder = new System.Text.StringBuilder();
|
||||
var errorBuilder = new System.Text.StringBuilder();
|
||||
|
||||
process.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
outputBuilder.AppendLine(e.Data);
|
||||
};
|
||||
|
||||
process.ErrorDataReceived += (sender, e) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
errorBuilder.AppendLine(e.Data);
|
||||
};
|
||||
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
|
||||
// Wait for exit with timeout
|
||||
var timeout = TimeSpan.FromSeconds(30);
|
||||
if (await Task.Run(() => process.WaitForExit((int)timeout.TotalMilliseconds)))
|
||||
{
|
||||
process.WaitForExit(); // Ensure all output is processed
|
||||
|
||||
string output = outputBuilder.ToString();
|
||||
string error = errorBuilder.ToString();
|
||||
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Git error: {error}");
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
else
|
||||
{
|
||||
process.Kill();
|
||||
throw new TimeoutException("Git command timed out");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Editor/PSXSplashInstaller.cs.meta
Normal file
2
Editor/PSXSplashInstaller.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72d1da27a16f0794cb1ad49c00799e74
|
||||
39
Editor/SerialConnection.cs
Normal file
39
Editor/SerialConnection.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.IO.Ports;
|
||||
|
||||
|
||||
namespace SplashEdit.EditorCode
|
||||
{
|
||||
public class SerialConnection
|
||||
{
|
||||
private static SerialPort serialPort;
|
||||
|
||||
public SerialConnection(string portName, int baudRate)
|
||||
{
|
||||
serialPort = new SerialPort(portName, baudRate);
|
||||
serialPort.ReadTimeout = 50;
|
||||
serialPort.WriteTimeout = 50;
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{ serialPort.Open(); }
|
||||
|
||||
public void Close()
|
||||
{ serialPort.Close(); }
|
||||
|
||||
public int ReadByte()
|
||||
{ return serialPort.ReadByte(); }
|
||||
|
||||
public int ReadChar()
|
||||
{ return serialPort.ReadChar(); }
|
||||
|
||||
public void Write(string text)
|
||||
{ serialPort.Write(text); }
|
||||
|
||||
public void Write(char[] buffer, int offset, int count)
|
||||
{ serialPort.Write(buffer, offset, count); }
|
||||
|
||||
public void Write(byte[] buffer, int offset, int count)
|
||||
{ serialPort.Write(buffer, offset, count); }
|
||||
|
||||
}
|
||||
}
|
||||
2
Editor/SerialConnection.cs.meta
Normal file
2
Editor/SerialConnection.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 714bd2374b7a9a14686078e5eb431795
|
||||
22
Editor/UniromConnection.cs
Normal file
22
Editor/UniromConnection.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace SplashEdit.EditorCode
|
||||
{
|
||||
public class UniromConnection
|
||||
{
|
||||
|
||||
private SerialConnection serialConnection;
|
||||
|
||||
public UniromConnection(int baudRate, string portName)
|
||||
{
|
||||
serialConnection = new SerialConnection(portName, baudRate);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
serialConnection.Open();
|
||||
serialConnection.Write("REST");
|
||||
serialConnection.Close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
2
Editor/UniromConnection.cs.meta
Normal file
2
Editor/UniromConnection.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8fbc734f42ab9d42a843b6718127da7
|
||||
145
Editor/UniromConnectionWindow.cs
Normal file
145
Editor/UniromConnectionWindow.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO.Ports;
|
||||
using System.Collections;
|
||||
using SplashEdit.RuntimeCode;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SplashEdit.EditorCode
|
||||
{
|
||||
public class PSXConnectionConfigWindow : EditorWindow
|
||||
{
|
||||
|
||||
public PSXConnectionType connectionType = PSXConnectionType.REAL_HARDWARE;
|
||||
|
||||
// REAL HARDWARE (Unirom) SETTINGS
|
||||
private string[] portNames;
|
||||
private int selectedPortIndex = 1;
|
||||
private int[] baudRates = { 9600, 115200 };
|
||||
private int selectedBaudIndex = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
private string statusMessage = "";
|
||||
private MessageType statusType;
|
||||
private Vector2 scrollPosition;
|
||||
|
||||
[MenuItem("PSX/Console or Emulator Connection")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
GetWindow<PSXConnectionConfigWindow>("Serial Config");
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
RefreshPorts();
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
private void RefreshPorts()
|
||||
{
|
||||
portNames = SerialPort.GetPortNames();
|
||||
if (portNames.Length == 0)
|
||||
{
|
||||
portNames = new[] { "No ports available" };
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
using (var scrollView = new EditorGUILayout.ScrollViewScope(scrollPosition))
|
||||
{
|
||||
scrollPosition = scrollView.scrollPosition;
|
||||
|
||||
EditorGUILayout.LabelField("Pick connection type", EditorStyles.boldLabel);
|
||||
connectionType = (PSXConnectionType)EditorGUILayout.EnumPopup("Connection Type", connectionType);
|
||||
|
||||
if (connectionType == PSXConnectionType.REAL_HARDWARE)
|
||||
{
|
||||
// Port selection
|
||||
EditorGUILayout.LabelField("Select COM Port", EditorStyles.boldLabel);
|
||||
selectedPortIndex = EditorGUILayout.Popup("Available Ports", selectedPortIndex, portNames);
|
||||
|
||||
// Baud rate selection
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Select Baud Rate", EditorStyles.boldLabel);
|
||||
selectedBaudIndex = EditorGUILayout.Popup("Baud Rate", selectedBaudIndex, new[] { "9600", "115200" });
|
||||
|
||||
// Buttons
|
||||
EditorGUILayout.Space();
|
||||
using (new EditorGUILayout.HorizontalScope())
|
||||
{
|
||||
if (GUILayout.Button("Refresh Ports"))
|
||||
{
|
||||
RefreshPorts();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Test Connection"))
|
||||
{
|
||||
TestConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Save settings"))
|
||||
{
|
||||
SaveSettings();
|
||||
|
||||
}
|
||||
|
||||
// Status message
|
||||
EditorGUILayout.Space();
|
||||
if (!string.IsNullOrEmpty(statusMessage))
|
||||
{
|
||||
EditorGUILayout.HelpBox(statusMessage, statusType);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
PSXData _psxData = DataStorage.LoadData();
|
||||
if (_psxData != null)
|
||||
{
|
||||
connectionType = _psxData.ConnectionType;
|
||||
selectedBaudIndex = System.Array.IndexOf(baudRates, _psxData.BaudRate);
|
||||
if (selectedBaudIndex == -1) selectedBaudIndex = 0;
|
||||
|
||||
RefreshPorts();
|
||||
selectedPortIndex = System.Array.IndexOf(portNames, _psxData.PortName);
|
||||
if (selectedPortIndex == -1) selectedPortIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void TestConnection()
|
||||
{
|
||||
if (portNames.Length == 0 || portNames[0] == "No ports available")
|
||||
{
|
||||
statusMessage = "No serial ports available";
|
||||
statusType = MessageType.Error;
|
||||
return;
|
||||
}
|
||||
|
||||
UniromConnection connection = new UniromConnection(baudRates[selectedBaudIndex], portNames[selectedPortIndex]);
|
||||
connection.Reset();
|
||||
|
||||
statusMessage = "Connection tested. If your PlayStation reset, it worked!";
|
||||
statusType = MessageType.Info;
|
||||
Repaint();
|
||||
}
|
||||
|
||||
private void SaveSettings()
|
||||
{
|
||||
PSXData _psxData = DataStorage.LoadData();
|
||||
_psxData.ConnectionType = connectionType;
|
||||
_psxData.BaudRate = baudRates[selectedBaudIndex];
|
||||
_psxData.PortName = portNames[selectedPortIndex];
|
||||
DataStorage.StoreData(_psxData);
|
||||
statusMessage = "Settings saved";
|
||||
statusType = MessageType.Info;
|
||||
Repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Editor/UniromConnectionWindow.cs.meta
Normal file
2
Editor/UniromConnectionWindow.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ade0bf0fd69f449458c5b43e0f48ddff
|
||||
Reference in New Issue
Block a user