forked from sin365/AxibugEmuOnline
735 lines
27 KiB
C#
735 lines
27 KiB
C#
using AxibugEmuOnline.Client;
|
||
using AxibugEmuOnline.Client.ClientCore;
|
||
using AxibugProtobuf;
|
||
using StoicGoose.Common.Utilities;
|
||
using StoicGoose.Core.Machines;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO.Compression;
|
||
using System.Linq;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using CartridgeMetadata = StoicGoose.Core.Cartridges.Metadata;
|
||
|
||
public class UStoicGoose : IEmuCore
|
||
{
|
||
public static UStoicGoose instance;
|
||
public static System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
|
||
|
||
/* Constants */
|
||
readonly static int maxScreenSizeFactor = 5;
|
||
readonly static int maxRecentFiles = 15;
|
||
readonly static int statusIconSize = 12;
|
||
|
||
readonly static List<(string description, string extension, Func<string, System.IO.Stream> streamReadFunc)> supportedFileInformation = new()
|
||
{
|
||
("WonderSwan ROMs", ".ws", GetStreamFromFile),
|
||
("WonderSwan Color ROMs", ".wsc", GetStreamFromFile),
|
||
("Zip Archives", ".zip", GetStreamFromFirstZippedFile)
|
||
};
|
||
|
||
/* Various handlers */
|
||
DatabaseHandler databaseHandler = default;
|
||
SGVideoPlayer graphicsHandler = default;
|
||
SGSoundPlayer soundHandler = default;
|
||
SGKeyboard inputHandler = default;
|
||
SGLogger loggerHandler = default;
|
||
public EmulatorHandler emulatorHandler = default;
|
||
private RomPlatformType mPlatform = RomPlatformType.WonderSwan;
|
||
|
||
/* Misc. windows */
|
||
//SoundRecorderForm soundRecorderForm = default;
|
||
//CheatsForm cheatsForm = default;
|
||
|
||
/* Misc. runtime variables */
|
||
Type machineType = default;
|
||
bool isVerticalOrientation = false;
|
||
string internalEepromPath = string.Empty;
|
||
|
||
public string CurrRomName { get; private set; }
|
||
|
||
#region 实现IEmuCore
|
||
public override RomPlatformType Platform => mPlatform;
|
||
|
||
public override uint Frame => (uint)emulatorHandler.AxiEmuRunFrame;
|
||
|
||
public override Texture OutputPixel => graphicsHandler.rawBufferWarper;
|
||
|
||
public override RawImage DrawCanvas => graphicsHandler.DrawCanvas;
|
||
public override object GetState()
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override byte[] GetStateBytes()
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override void LoadState(object state)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override void LoadStateFromBytes(byte[] data)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override void Pause()
|
||
{
|
||
PauseEmulation();
|
||
}
|
||
|
||
public override void Resume()
|
||
{
|
||
UnpauseEmulation();
|
||
}
|
||
|
||
public override MsgBool StartGame(RomFile romFile)
|
||
{
|
||
mPlatform = romFile.Platform;
|
||
|
||
Init();
|
||
|
||
|
||
//保存当前正在进行的游戏存档
|
||
if (emulatorHandler != null && !emulatorHandler.IsRunning)
|
||
{
|
||
SaveAllData();
|
||
}
|
||
|
||
if (LoadAndRunCartridge(romFile.LocalFilePath))
|
||
return true;
|
||
else
|
||
return "Rom加载失败";
|
||
}
|
||
|
||
public override void Dispose()
|
||
{
|
||
//保存当前正在进行的游戏存档
|
||
if (emulatorHandler != null && !emulatorHandler.IsRunning)
|
||
{
|
||
SaveAllData();
|
||
}
|
||
EmuClose();
|
||
}
|
||
|
||
public override void DoReset()
|
||
{
|
||
ResetEmulation();
|
||
}
|
||
|
||
public override IControllerSetuper GetControllerSetuper()
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override bool PushEmulatorFrame()
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override void AfterPushFrame()
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override void GetAudioParams(out int frequency, out int channels)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
#endregion
|
||
|
||
//Cheat[] cheats = default;
|
||
|
||
#region Unity 生命周期
|
||
|
||
void Awake()
|
||
{
|
||
//关闭垂直同步
|
||
QualitySettings.vSyncCount = 0;
|
||
//设为60帧
|
||
Application.targetFrameRate = 60;
|
||
|
||
instance = this;
|
||
loggerHandler = new SGLogger();
|
||
graphicsHandler = this.gameObject.GetComponent<SGVideoPlayer>();
|
||
soundHandler = this.gameObject.GetComponent<SGSoundPlayer>();
|
||
inputHandler = this.gameObject.GetComponent<SGKeyboard>();
|
||
Log.Initialize(loggerHandler);
|
||
Program.InitPath(Application.persistentDataPath);
|
||
//Init();
|
||
//LoadAndRunCartridge("G:/BaiduNetdiskDownload/Rockman & Forte - Mirai Kara no Chousen Sha (J) [M][!].ws");
|
||
}
|
||
private void Update()
|
||
{
|
||
if (!emulatorHandler.IsRunning)
|
||
return;
|
||
|
||
inputHandler.Update_InputData();
|
||
|
||
emulatorHandler.Frame_Update();
|
||
}
|
||
void OnDestroy()
|
||
{
|
||
EmuClose();
|
||
}
|
||
#endregion
|
||
private void Init()
|
||
{
|
||
Log.WriteEvent(LogSeverity.Information, this, "Initializing emulator and UI...");
|
||
|
||
machineType = Program.Configuration.General.PreferOriginalWS ? typeof(WonderSwan) : typeof(WonderSwanColor);
|
||
|
||
InitializeEmulatorHandler();
|
||
VerifyConfiguration();
|
||
InitializeOtherHandlers();
|
||
//InitializeWindows();
|
||
|
||
//SizeAndPositionWindow();
|
||
SetWindowTitleAndStatus();
|
||
Log.WriteEvent(LogSeverity.Information, this, "Initialization done!");
|
||
}
|
||
|
||
|
||
private void EmuClose()
|
||
{
|
||
SaveAllData();
|
||
emulatorHandler.Shutdown();
|
||
|
||
Program.SaveConfiguration();
|
||
}
|
||
|
||
|
||
private void InitializeEmulatorHandler()
|
||
{
|
||
emulatorHandler = new EmulatorHandler(machineType);
|
||
emulatorHandler.SetFpsLimiter(Program.Configuration.General.LimitFps);
|
||
}
|
||
|
||
private void VerifyConfiguration()
|
||
{
|
||
foreach (var button in emulatorHandler.Machine.GameControls.Replace(" ", "").Split(','))
|
||
{
|
||
if (!Program.Configuration.Input.GameControls.ContainsKey(button))
|
||
Program.Configuration.Input.GameControls[button] = new();
|
||
}
|
||
|
||
foreach (var button in emulatorHandler.Machine.HardwareControls.Replace(" ", "").Split(','))
|
||
{
|
||
if (!Program.Configuration.Input.SystemControls.ContainsKey(button))
|
||
Program.Configuration.Input.SystemControls[button] = new();
|
||
}
|
||
|
||
if (Program.Configuration.Video.ScreenSize < 2 || Program.Configuration.Video.ScreenSize > maxScreenSizeFactor)
|
||
Program.Configuration.Video.ResetToDefault(nameof(Program.Configuration.Video.ScreenSize));
|
||
|
||
//if (string.IsNullOrEmpty(Program.Configuration.Video.Shader) || (graphicsHandler != null && !graphicsHandler.AvailableShaders.Contains(Program.Configuration.Video.Shader)))
|
||
// Program.Configuration.Video.Shader = GraphicsHandler.DefaultShaderName;
|
||
}
|
||
|
||
private void InitializeOtherHandlers()
|
||
{
|
||
databaseHandler = new DatabaseHandler();
|
||
|
||
//statusIconsLocation = machineType == typeof(WonderSwan) ? new(0, DisplayControllerCommon.ScreenHeight) : new(DisplayControllerCommon.ScreenWidth, 0);
|
||
|
||
//TODO graphicsHandler基本参数,可能需要补上
|
||
//graphicsHandler = new GraphicsHandler(machineType, new(emulatorHandler.Machine.ScreenWidth, emulatorHandler.Machine.ScreenHeight), statusIconsLocation, statusIconSize, machineType != typeof(WonderSwan), Program.Configuration.Video.Shader)
|
||
//{
|
||
// IsVerticalOrientation = isVerticalOrientation
|
||
//};
|
||
|
||
//TODO 声音基本参数,可能需要补上
|
||
//soundHandler = new SoundHandler(44100, 2);
|
||
//soundHandler.SetVolume(1.0f);
|
||
//soundHandler.SetMute(Program.Configuration.Sound.Mute);
|
||
//soundHandler.SetLowPassFilter(Program.Configuration.Sound.LowPassFilter);
|
||
|
||
//TODO Input基本参数,可能需要补上
|
||
//inputHandler = new InputHandler(renderControl);
|
||
//inputHandler.SetKeyMapping(Program.Configuration.Input.GameControls, Program.Configuration.Input.SystemControls);
|
||
//inputHandler.SetVerticalOrientation(isVerticalOrientation);
|
||
//inputHandler.SetEnableRemapping(Program.Configuration.Input.AutoRemap);
|
||
//inputHandler.SetVerticalRemapping(emulatorHandler.Machine.VerticalControlRemap
|
||
// .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||
// .Select(x => x.Split('=', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
|
||
// .ToDictionary(x => x[0], x => x[1]));
|
||
|
||
|
||
emulatorHandler.Machine.DisplayController.SendFramebuffer = graphicsHandler.UpdateScreen;
|
||
emulatorHandler.Machine.SoundController.SendSamples = (s) =>
|
||
{
|
||
soundHandler.EnqueueSamples(s);
|
||
//soundRecorderForm.EnqueueSamples(s);
|
||
};
|
||
|
||
emulatorHandler.Machine.ReceiveInput += () =>
|
||
{
|
||
//var buttonsPressed = new List<string>();
|
||
//var buttonsHeld = new List<string>();
|
||
|
||
//inputHandler.PollInput(ref buttonsPressed, ref buttonsHeld);
|
||
long buttonsHeld = 0;
|
||
inputHandler.PollInput(ref buttonsHeld);
|
||
return buttonsHeld;
|
||
//if (buttonsPressed.Contains("Volume"))
|
||
// emulatorHandler.Machine.SoundController.ChangeMasterVolume();
|
||
|
||
//return (buttonsPressed, buttonsHeld);
|
||
};
|
||
|
||
//renderControl.Resize += (s, e) => { if (s is Control control) graphicsHandler.Resize(control.ClientRectangle); };
|
||
//renderControl.Paint += (s, e) =>
|
||
//{
|
||
// graphicsHandler.SetClearColor(Color.Black);
|
||
|
||
// graphicsHandler.ClearFrame();
|
||
|
||
// if (emulatorHandler.Machine is MachineCommon machine)
|
||
// {
|
||
// var activeIcons = new List<string>() { "Power" };
|
||
|
||
// if (machine.BuiltInSelfTestOk) activeIcons.Add("Initialized");
|
||
|
||
// if (machine.DisplayController.IconSleep) activeIcons.Add("Sleep");
|
||
// if (machine.DisplayController.IconVertical) activeIcons.Add("Vertical");
|
||
// if (machine.DisplayController.IconHorizontal) activeIcons.Add("Horizontal");
|
||
// if (machine.DisplayController.IconAux1) activeIcons.Add("Aux1");
|
||
// if (machine.DisplayController.IconAux2) activeIcons.Add("Aux2");
|
||
// if (machine.DisplayController.IconAux3) activeIcons.Add("Aux3");
|
||
|
||
// if (machine.SoundController.HeadphonesConnected) activeIcons.Add("Headphones");
|
||
// if (machine.SoundController.MasterVolume == 0) activeIcons.Add("Volume0");
|
||
// if (machine.SoundController.MasterVolume == 1) activeIcons.Add("Volume1");
|
||
// if (machine.SoundController.MasterVolume == 2) activeIcons.Add("Volume2");
|
||
// if (machine.SoundController.MasterVolume == 3 && machine is WonderSwanColor) activeIcons.Add("Volume3");
|
||
|
||
// graphicsHandler.UpdateStatusIcons(activeIcons);
|
||
// }
|
||
// graphicsHandler.DrawFrame();
|
||
//};
|
||
|
||
internalEepromPath = System.IO.Path.Combine(Program.InternalDataPath, $"{machineType.Name}.eep");
|
||
}
|
||
|
||
//private void InitializeWindows()
|
||
//{
|
||
// soundRecorderForm = new(soundHandler.SampleRate, soundHandler.NumChannels);
|
||
// cheatsForm = new()
|
||
// {
|
||
// Callback = (c) =>
|
||
// {
|
||
// if (emulatorHandler.IsRunning)
|
||
// cheats = (Cheat[])c.Clone();
|
||
// }
|
||
// };
|
||
//}
|
||
|
||
private void SizeAndPositionWindow()
|
||
{
|
||
graphicsHandler.SetSize(emulatorHandler.Machine.ScreenWidth, emulatorHandler.Machine.ScreenHeight);
|
||
//if (WindowState == For emulatorHandler.Machine.ScreenHeight;mWindowState.Maximized)
|
||
// WindowState = FormWindowState.Normal;
|
||
|
||
//MinimumSize = SizeFromClientSize(CalculateRequiredClientSize(2));
|
||
//Size = SizeFromClientSize(CalculateRequiredClientSize(Program.Configuration.Video.ScreenSize));
|
||
//var screen = Screen.FromControl(this);
|
||
//var workingArea = screen.WorkingArea;
|
||
//Location = new Point()
|
||
//{
|
||
// X = Math.Max(workingArea.X, workingArea.X + (workingArea.Width - Width) / 2),
|
||
// Y = Math.Max(workingArea.Y, workingArea.Y + (workingArea.Height - Height) / 2)
|
||
//};
|
||
}
|
||
|
||
|
||
//TODO 设置屏幕宽高 看是否需要
|
||
//private Size CalculateRequiredClientSize(int screenSize)
|
||
//{
|
||
// if (emulatorHandler == null || graphicsHandler == null)
|
||
// return ClientSize;
|
||
|
||
// var statusIconsOnRight = statusIconsLocation.X > statusIconsLocation.Y;
|
||
|
||
// int screenWidth, screenHeight;
|
||
|
||
// if (!isVerticalOrientation)
|
||
// {
|
||
// screenWidth = emulatorHandler.Machine.ScreenWidth;
|
||
// screenHeight = emulatorHandler.Machine.ScreenHeight;
|
||
// if (statusIconsOnRight) screenWidth += statusIconSize;
|
||
// if (!statusIconsOnRight) screenHeight += statusIconSize;
|
||
// }
|
||
// else
|
||
// {
|
||
// screenWidth = emulatorHandler.Machine.ScreenHeight;
|
||
// screenHeight = emulatorHandler.Machine.ScreenWidth;
|
||
// if (!statusIconsOnRight) screenWidth += statusIconSize;
|
||
// if (statusIconsOnRight) screenHeight += statusIconSize;
|
||
// }
|
||
|
||
// return new(screenWidth * screenSize, (screenHeight * screenSize) + menuStrip.Height + statusStrip.Height);
|
||
//}
|
||
|
||
private void SetWindowTitleAndStatus()
|
||
{
|
||
//TODO 修改为状态字符串,显示在某个地方
|
||
|
||
//var titleStringBuilder = new StringBuilder();
|
||
|
||
//titleStringBuilder.Append($"{Application.ProductName} {Program.GetVersionString(false)}");
|
||
|
||
//if (emulatorHandler.Machine.Cartridge.IsLoaded)
|
||
//{
|
||
// titleStringBuilder.Append($" - [{Path.GetFileName(Program.Configuration.General.RecentFiles.First())}]");
|
||
|
||
// var statusStringBuilder = new StringBuilder();
|
||
// statusStringBuilder.Append($"Emulating {emulatorHandler.Machine.Manufacturer} {emulatorHandler.Machine.Model}, ");
|
||
// statusStringBuilder.Append($"playing {databaseHandler.GetGameTitle(emulatorHandler.Machine.Cartridge.Crc32, emulatorHandler.Machine.Cartridge.SizeInBytes)} ({emulatorHandler.Machine.Cartridge.Metadata.GameIdString})");
|
||
|
||
// tsslStatus.Text = statusStringBuilder.ToString();
|
||
// tsslEmulationStatus.Text = emulatorHandler.IsRunning ? (emulatorHandler.IsPaused ? "Paused" : "Running") : "Stopped";
|
||
//}
|
||
//else
|
||
//{
|
||
// tsslStatus.Text = "Ready";
|
||
// tsslEmulationStatus.Text = "Stopped";
|
||
//}
|
||
|
||
//Text = titleStringBuilder.ToString();
|
||
}
|
||
|
||
private void LoadBootstrap(string filename)
|
||
{
|
||
if (GlobalVariables.EnableSkipBootstrapIfFound) return;
|
||
|
||
if (!emulatorHandler.IsRunning)
|
||
{
|
||
if (AxiIO.File.Exists(filename))
|
||
{
|
||
//using var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
//var data = new byte[stream.Length];
|
||
//stream.Read(data, 0, data.Length);
|
||
|
||
var data = AxiIO.File.ReadAllBytes(filename);
|
||
|
||
emulatorHandler.Machine.LoadBootstrap(data);
|
||
}
|
||
emulatorHandler.Machine.UseBootstrap = Program.Configuration.General.UseBootstrap;
|
||
}
|
||
}
|
||
|
||
private void LoadInternalEeprom()
|
||
{
|
||
if (!emulatorHandler.IsRunning && AxiIO.File.Exists(internalEepromPath))
|
||
{
|
||
//using var stream = new FileStream(internalEepromPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
//var data = new byte[stream.Length];
|
||
//stream.Read(data, 0, data.Length);
|
||
|
||
var data = AxiIO.File.ReadAllBytes(internalEepromPath);
|
||
|
||
emulatorHandler.Machine.LoadInternalEeprom(data);
|
||
}
|
||
}
|
||
|
||
private static System.IO.Stream GetStreamFromFile(string filename)
|
||
{
|
||
//return new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
byte[] data = AxiIO.File.ReadAllBytes(filename);
|
||
return new System.IO.MemoryStream(data);
|
||
}
|
||
|
||
private static System.IO.Stream GetStreamFromFirstZippedFile(string filename)
|
||
{
|
||
//return new ZipArchive(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)).Entries.FirstOrDefault()?.Open();
|
||
|
||
byte[] data = AxiIO.File.ReadAllBytes(filename);
|
||
return new ZipArchive(new System.IO.MemoryStream(data)).Entries.FirstOrDefault()?.Open();
|
||
}
|
||
|
||
private bool LoadAndRunCartridge(string filename)
|
||
{
|
||
try
|
||
{
|
||
if (emulatorHandler.IsRunning)
|
||
{
|
||
SaveAllData();
|
||
emulatorHandler.Shutdown();
|
||
}
|
||
|
||
using var inputStream = supportedFileInformation.FirstOrDefault(x => x.extension == System.IO.Path.GetExtension(filename)).streamReadFunc(filename) ?? GetStreamFromFile(filename);
|
||
using var stream = new System.IO.MemoryStream();
|
||
inputStream.CopyTo(stream);
|
||
stream.Position = 0;
|
||
|
||
var data = new byte[stream.Length];
|
||
stream.Read(data, 0, data.Length);
|
||
emulatorHandler.Machine.LoadRom(data);
|
||
|
||
graphicsHandler.IsVerticalOrientation = isVerticalOrientation = emulatorHandler.Machine.Cartridge.Metadata.Orientation == CartridgeMetadata.Orientations.Vertical;
|
||
inputHandler.SetVerticalOrientation(isVerticalOrientation);
|
||
|
||
CurrRomName = System.IO.Path.GetFileName(filename);
|
||
|
||
LoadRam();
|
||
|
||
LoadBootstrap(emulatorHandler.Machine is WonderSwan ? Program.Configuration.General.BootstrapFile : Program.Configuration.General.BootstrapFileWSC);
|
||
LoadInternalEeprom();
|
||
|
||
//初始化音频
|
||
soundHandler.Initialize();
|
||
|
||
emulatorHandler.Startup();
|
||
|
||
SizeAndPositionWindow();
|
||
SetWindowTitleAndStatus();
|
||
|
||
Program.SaveConfiguration();
|
||
return true;
|
||
}
|
||
catch (Exception ex) when (!AppEnvironment.DebugMode)
|
||
{
|
||
App.log.Error("ex=>"+ex.ToString());
|
||
return false;
|
||
}
|
||
}
|
||
|
||
private void LoadRam()
|
||
{
|
||
//var path = Path.Combine(Program.SaveDataPath, $"{Path.GetFileNameWithoutExtension(Program.Configuration.General.RecentFiles.First())}.sav");
|
||
var path = System.IO.Path.Combine(Program.SaveDataPath, $"{CurrRomName}.sav");
|
||
//if (!File.Exists(path)) return;
|
||
if (!AxiIO.File.Exists(path)) return;
|
||
|
||
//using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||
//var data = new byte[stream.Length];
|
||
//stream.Read(data, 0, data.Length);
|
||
|
||
var data = AxiIO.File.ReadAllBytes(path);
|
||
if (data.Length != 0)
|
||
emulatorHandler.Machine.LoadSaveData(data);
|
||
}
|
||
|
||
private void SaveAllData()
|
||
{
|
||
SaveInternalEeprom();
|
||
SaveRam();
|
||
}
|
||
|
||
private void SaveInternalEeprom()
|
||
{
|
||
var data = emulatorHandler.Machine.GetInternalEeprom();
|
||
if (data.Length == 0) return;
|
||
|
||
//using var stream = new FileStream(internalEepromPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
|
||
//stream.Write(data, 0, data.Length);
|
||
|
||
AxiIO.File.WriteAllBytes(internalEepromPath, data);
|
||
}
|
||
|
||
private void SaveRam()
|
||
{
|
||
var data = emulatorHandler.Machine.GetSaveData();
|
||
if (data.Length == 0) return;
|
||
|
||
//var path = Path.Combine(Program.SaveDataPath, $"{Path.GetFileNameWithoutExtension(Program.Configuration.General.RecentFiles.First())}.sav");
|
||
var path = System.IO.Path.Combine(Program.SaveDataPath, $"{CurrRomName}.sav");
|
||
|
||
//using var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
|
||
//stream.Write(data, 0, data.Length);
|
||
|
||
AxiIO.File.WriteAllBytes(path, data);
|
||
}
|
||
|
||
|
||
private void PauseEmulation()
|
||
{
|
||
if (!emulatorHandler.IsRunning) return;
|
||
|
||
emulatorHandler.Pause();
|
||
soundHandler.Pause();
|
||
|
||
SetWindowTitleAndStatus();
|
||
}
|
||
|
||
private void UnpauseEmulation()
|
||
{
|
||
if (!emulatorHandler.IsRunning) return;
|
||
|
||
emulatorHandler.Unpause();
|
||
soundHandler.Unpause();
|
||
|
||
SetWindowTitleAndStatus();
|
||
}
|
||
|
||
private void ResetEmulation()
|
||
{
|
||
SaveAllData();
|
||
emulatorHandler.Reset();
|
||
|
||
Program.SaveConfiguration();
|
||
}
|
||
|
||
}
|
||
|
||
static class Program
|
||
{
|
||
static string jsonConfigFileName;//= "Config.json";
|
||
static string logFileName;//= "Log.txt";
|
||
static string internalDataDirectoryName;//= "Internal";
|
||
static string saveDataDirectoryName;//= "Saves";
|
||
static string cheatDataDirectoryName;//= "Cheats";
|
||
static string debuggingDataDirectoryName;//= "Debugging";
|
||
static string assetsDirectoryName;//= "Assets";
|
||
static string shaderDirectoryName;//= "Shaders";
|
||
static string noIntroDatDirectoryName;//= "No-Intro";
|
||
static string mutexName;//= $"Unity_{GetVersionDetails()}";
|
||
static string programDataDirectory;//= Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Application.ProductName);
|
||
static string programConfigPath;//= Path.Combine(programDataDirectory, jsonConfigFileName);
|
||
|
||
public static Configuration Configuration;// { get; private set; } = LoadConfiguration(programConfigPath);
|
||
|
||
public static string DataPath;//{ get; } = string.Empty;
|
||
public static string InternalDataPath;//{ get; } = string.Empty;
|
||
public static string SaveDataPath;//{ get; } = string.Empty;
|
||
public static string CheatsDataPath;//{ get; } = string.Empty;
|
||
public static string DebuggingDataPath;//{ get; } = string.Empty;
|
||
|
||
static string programApplicationDirectory;// = AppDomain.CurrentDomain.BaseDirectory;
|
||
static string programAssetsDirectory;// = Path.Combine(programApplicationDirectory, assetsDirectoryName);
|
||
|
||
//public static string ShaderPath { get; } = string.Empty;
|
||
public static string NoIntroDatPath;// { get; } = string.Empty;
|
||
|
||
//static MainForm mainForm = default;
|
||
|
||
public static void InitPath(string CustonDataDir)
|
||
{
|
||
try
|
||
{
|
||
jsonConfigFileName = "Config.json";
|
||
logFileName = "Log.txt";
|
||
internalDataDirectoryName = "Internal";
|
||
saveDataDirectoryName = "Saves";
|
||
cheatDataDirectoryName = "Cheats";
|
||
debuggingDataDirectoryName = "Debugging";
|
||
assetsDirectoryName = "Assets";
|
||
shaderDirectoryName = "Shaders";
|
||
noIntroDatDirectoryName = "No-Intro";
|
||
mutexName = $"Unity_{GetVersionDetails()}";
|
||
programDataDirectory = System.IO.Path.Combine(CustonDataDir, "AxibugEmu");
|
||
programConfigPath = System.IO.Path.Combine(programDataDirectory, jsonConfigFileName);
|
||
Configuration = LoadConfiguration(programConfigPath);
|
||
Log.WriteLine(System.IO.Path.Combine(programDataDirectory, logFileName));
|
||
programApplicationDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||
programAssetsDirectory = System.IO.Path.Combine(programApplicationDirectory, assetsDirectoryName);
|
||
AxiIO.Directory.CreateDirectory(DataPath = programDataDirectory);
|
||
AxiIO.Directory.CreateDirectory(InternalDataPath = System.IO.Path.Combine(programDataDirectory, internalDataDirectoryName));
|
||
AxiIO.Directory.CreateDirectory(SaveDataPath = System.IO.Path.Combine(programDataDirectory, saveDataDirectoryName));
|
||
AxiIO.Directory.CreateDirectory(CheatsDataPath = System.IO.Path.Combine(programDataDirectory, cheatDataDirectoryName));
|
||
AxiIO.Directory.CreateDirectory(DebuggingDataPath = System.IO.Path.Combine(programDataDirectory, debuggingDataDirectoryName));
|
||
|
||
//if (!Directory.Exists(ShaderPath = Path.Combine(programAssetsDirectory, shaderDirectoryName)))
|
||
// throw new DirectoryNotFoundException("Shader directory missing");
|
||
|
||
if (!AxiIO.Directory.Exists(NoIntroDatPath = System.IO.Path.Combine(programAssetsDirectory, noIntroDatDirectoryName)))
|
||
throw new Exception("No-Intro .dat directory missing");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
}
|
||
}
|
||
|
||
//[STAThread]
|
||
//static void Main()
|
||
//{
|
||
// using var mutex = new Mutex(true, mutexName, out bool newInstance);
|
||
// if (!newInstance)
|
||
// {
|
||
// MessageBox.Show($"Another instance of {Application.ProductName} is already running.\n\nThis instance will now shut down.",
|
||
// $"{Application.ProductName} Startup Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
// Environment.Exit(-1);
|
||
// }
|
||
|
||
// Application.SetHighDpiMode(HighDpiMode.SystemAware);
|
||
// Application.EnableVisualStyles();
|
||
// Application.SetCompatibleTextRenderingDefault(false);
|
||
|
||
// if (!Debugger.IsAttached)
|
||
// {
|
||
// Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
|
||
// Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
||
// AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
|
||
// }
|
||
|
||
// Application.Run(mainForm = new MainForm());
|
||
//}
|
||
|
||
//static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
|
||
//{
|
||
// if (e.Exception is GLFWException glEx)
|
||
// {
|
||
// var renderControl = mainForm.Controls["renderControl"] as OpenGL.RenderControl;
|
||
// MessageBox.Show($"{glEx.Message.EnsureEndsWithPeriod()}\n\n{Application.ProductName} requires GPU and drivers supporting OpenGL {renderControl.APIVersion.Major}.{renderControl.APIVersion.Minor}.", $"{Application.ProductName} Startup Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
// }
|
||
// else
|
||
// {
|
||
// MessageBox.Show(e.Exception.Message.EnsureEndsWithPeriod(), $"{Application.ProductName} Startup Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
// }
|
||
|
||
// Environment.Exit(-1);
|
||
//}
|
||
|
||
//static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||
//{
|
||
// MessageBox.Show((e.ExceptionObject as Exception).Message, $"{Application.ProductName} Startup Error");
|
||
// Environment.Exit(-1);
|
||
//}
|
||
|
||
private static Configuration LoadConfiguration(string filename)
|
||
{
|
||
AxiIO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(filename));
|
||
|
||
Configuration configuration;
|
||
//if (!File.Exists(filename) || (configuration = filename.DeserializeFromFile<Configuration>()) == null)
|
||
//{
|
||
// configuration = new Configuration();
|
||
// configuration.SerializeToFile(filename);
|
||
//}
|
||
|
||
configuration = new Configuration();
|
||
|
||
return configuration;
|
||
}
|
||
|
||
public static void ReplaceConfiguration(Configuration newConfig)
|
||
{
|
||
ConfigurationBase.CopyConfiguration(newConfig, Configuration);
|
||
SaveConfiguration();
|
||
}
|
||
|
||
public static void SaveConfiguration()
|
||
{
|
||
//Configuration?.SerializeToFile(programConfigPath);
|
||
}
|
||
|
||
private static string GetVersionDetails()
|
||
{
|
||
//return $"{ThisAssembly.Git.Branch}-{ThisAssembly.Git.Commit}{(ThisAssembly.Git.IsDirty ? "-dirty" : string.Empty)}{(GlobalVariables.IsDebugBuild ? "+debug" : string.Empty)}";
|
||
return $"{(GlobalVariables.IsDebugBuild ? "+debug" : string.Empty)}";
|
||
}
|
||
|
||
//public static string GetVersionString(bool detailed)
|
||
//{
|
||
// var version = new Version(Application.ProductVersion);
|
||
// var stringBuilder = new StringBuilder();
|
||
// stringBuilder.Append($"v{version.Major:D3}{(version.Minor != 0 ? $".{version.Minor}" : string.Empty)}");
|
||
// if (detailed) stringBuilder.Append($" ({GetVersionDetails()})");
|
||
// return stringBuilder.ToString();
|
||
//}
|
||
}
|
||
|