Essgee.Unity/Assets/Scripts/UEssgee.cs

722 lines
27 KiB
C#
Raw Normal View History

2025-01-03 01:07:11 +08:00
using Essgee;
using Essgee.Emulation;
using Essgee.Emulation.Configuration;
using Essgee.EventArguments;
using Essgee.Exceptions;
using Essgee.Extensions;
using Essgee.Metadata;
using Essgee.Utilities;
using Essgee.Utilities.XInput;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
public class Essgeeinit : MonoBehaviour
{
static Essgeeinit instance;
2025-01-03 01:07:11 +08:00
public static System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
public static bool bInGame => instance?.emulatorHandler?.IsRunning == true ? true : false;
2025-01-03 01:07:11 +08:00
#region
UEGVideoPlayer graphicsHandler;
UEGSoundPlayer soundHandler;
GameMetadataHandler gameMetadataHandler;
GameMetadata lastGameMetadata;
EmulatorHandler emulatorHandler;
2025-02-06 00:14:13 +08:00
UEGResources uegResources;
UEGLog uegLog;
2025-01-03 01:07:11 +08:00
bool lastUserPauseState;
(int x, int y, int width, int height) currentViewport;
double currentPixelAspectRatio;
byte[] lastFramebufferData;
(int width, int height) lastFramebufferSize;
2025-02-06 00:14:13 +08:00
private UEGKeyboard mUniKeyboard;
2025-01-03 01:07:11 +08:00
#endregion
void Awake()
{
instance = this;
2025-02-06 00:14:13 +08:00
uegResources = new UEGResources();
uegLog = new UEGLog();
InitAll(uegResources, Application.persistentDataPath);
2025-02-05 23:35:36 +08:00
LoadAndRunCartridge("G:/Ninja_Gaiden_(UE)_type_A_[!].sms");
//LoadAndRunCartridge("G:/SML2.gb");
2025-01-03 01:07:11 +08:00
}
void OnDisable()
{
SaveConfiguration();
Dispose(false);
}
private void Update()
{
if (!emulatorHandler.IsRunning)
return;
mUniKeyboard.UpdateInputKey();
}
2025-02-06 00:14:13 +08:00
void InitAll(IGameMetaReources metaresources,string CustonDataDir)
2025-01-03 01:07:11 +08:00
{
//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-02-06 00:14:13 +08:00
InitAppEnvironment(CustonDataDir);
2025-01-03 01:07:11 +08:00
InitEmu();
//ϸ<>ڳ<EFBFBD>ʼ<EFBFBD><CABC>
2025-02-06 00:14:13 +08:00
InitializeHandlers(metaresources);
2025-01-03 01:07:11 +08:00
}
2025-02-06 00:14:13 +08:00
private void InitAppEnvironment(string CustonDataDir)
2025-01-03 01:07:11 +08:00
{
2025-02-06 00:14:13 +08:00
EssgeeLogger.Init(uegLog);
2025-01-03 01:07:11 +08:00
2025-02-06 00:14:13 +08:00
//EmuStandInfo.datDirectoryPath = Path.Combine(BaseDataDir, "EssgeeAssets", "No-Intro");
//EmuStandInfo.metadataDatabaseFilePath = Path.Combine(BaseDataDir, "EssgeeAssets", "MetadataDatabase.json");
2025-01-03 01:07:11 +08:00
EmuStandInfo.jsonConfigFileName = "Config.json";
EmuStandInfo.saveDataDirectoryName = "Saves";
EmuStandInfo.screenshotDirectoryName = "Screenshots";
EmuStandInfo.saveStateDirectoryName = "Savestates";
EmuStandInfo.extraDataDirectoryName = "Extras";
EmuStandInfo.ProductName = "AxibugEmu";
EmuStandInfo.ProductVersion = "";
EmuStandInfo.programDataDirectory = Path.Combine(CustonDataDir, EmuStandInfo.ProductName);
EmuStandInfo.programConfigPath = Path.Combine(EmuStandInfo.programDataDirectory, EmuStandInfo.jsonConfigFileName);
EmuStandInfo.ShaderPath = Path.Combine(CustonDataDir, "Assets", "Shaders");
EmuStandInfo.SaveDataPath = Path.Combine(EmuStandInfo.programDataDirectory, EmuStandInfo.saveDataDirectoryName);
EmuStandInfo.ScreenshotPath = Path.Combine(EmuStandInfo.programDataDirectory, EmuStandInfo.screenshotDirectoryName);
EmuStandInfo.SaveStatePath = Path.Combine(EmuStandInfo.programDataDirectory, EmuStandInfo.saveStateDirectoryName);
EmuStandInfo.ExtraDataPath = Path.Combine(EmuStandInfo.programDataDirectory, EmuStandInfo.extraDataDirectoryName);
LoadConfiguration();
if (!Directory.Exists(EmuStandInfo.SaveDataPath))
Directory.CreateDirectory(EmuStandInfo.SaveDataPath);
if (!Directory.Exists(EmuStandInfo.ScreenshotPath))
Directory.CreateDirectory(EmuStandInfo.ScreenshotPath);
if (!Directory.Exists(EmuStandInfo.SaveStatePath))
Directory.CreateDirectory(EmuStandInfo.SaveStatePath);
if (!Directory.Exists(EmuStandInfo.ExtraDataPath))
Directory.CreateDirectory(EmuStandInfo.ExtraDataPath);
if (AppEnvironment.EnableLogger)
{
//TODO <20>ر<EFBFBD>Debug
//Logger.Flush();
//Logger.Close();
}
}
void InitEmu()
{
//keysDown = new List<MotionKey>();
2025-01-03 01:07:11 +08:00
}
#region ϸ<EFBFBD>ڳ<EFBFBD>ʼ<EFBFBD><EFBFBD>
2025-02-06 00:14:13 +08:00
private void InitializeHandlers(IGameMetaReources metaresources)
2025-01-03 01:07:11 +08:00
{
InitializeOSDHandler();
InitializeGraphicsHandler();
InitializeSoundHandler();
2025-02-06 00:14:13 +08:00
InitializeMetadataHandler(metaresources);
2025-02-06 00:14:13 +08:00
mUniKeyboard = this.gameObject.AddComponent<UEGKeyboard>();
2025-01-03 01:07:11 +08:00
}
private void InitializeOSDHandler()
{
//var osdFontText = Assembly.GetExecutingAssembly().ReadEmbeddedImageFile($"{Application.ProductName}.Assets.OsdFont.png");
//onScreenDisplayHandler = new OnScreenDisplayHandler(osdFontText);
//onScreenDisplayHandler?.EnqueueMessageDebug($"Hello from {GetProductNameAndVersionString(true)}, this is a debug build!\nOSD handler initialized; font bitmap is {osdFontText.Width}x{osdFontText.Height}.");
//if (onScreenDisplayHandler == null) throw new HandlerException("Failed to initialize OSD handler");
}
private void InitializeGraphicsHandler()
{
graphicsHandler = this.gameObject.GetComponent<UEGVideoPlayer>();
//graphicsHandler = new GraphicsHandler(onScreenDisplayHandler);
//graphicsHandler?.LoadShaderBundle(Program.Configuration.LastShader);
}
private void InitializeSoundHandler()
{
soundHandler = this.gameObject.GetComponent<UEGSoundPlayer>();
2025-01-03 01:07:11 +08:00
//soundHandler = new SoundHandler(onScreenDisplayHandler, Program.Configuration.SampleRate, 2, ExceptionHandler);
//soundHandler.SetVolume(Program.Configuration.Volume);
//soundHandler.SetMute(Program.Configuration.Mute);
//soundHandler.SetLowPassFilter(Program.Configuration.LowPassFilter);
//soundHandler.Startup();
}
2025-02-06 00:14:13 +08:00
private void InitializeMetadataHandler(IGameMetaReources metaresources)
2025-01-03 01:07:11 +08:00
{
//gameMetadataHandler = new GameMetadataHandler(onScreenDisplayHandler);
2025-02-06 00:14:13 +08:00
gameMetadataHandler = new GameMetadataHandler(metaresources);
2025-01-03 01:07:11 +08:00
}
#endregion
void Dispose(bool disposing)
{
//TODO <20>ͷ<EFBFBD>ʱ
//if (disposing)
//{
// if (components != null) components.Dispose();
// if (onScreenDisplayHandler != null) onScreenDisplayHandler.Dispose();
// if (graphicsHandler != null) graphicsHandler.Dispose();
// if (soundHandler != null) soundHandler.Dispose();
//}
//base.Dispose(disposing);
}
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private static void LoadConfiguration()
{
2025-02-06 00:14:13 +08:00
//TODO <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><C3BC><EFBFBD>
2025-02-05 23:35:36 +08:00
//Directory.CreateDirectory(EmuStandInfo.programDataDirectory);
//if (!File.Exists(EmuStandInfo.programConfigPath) || (EmuStandInfo.Configuration = EmuStandInfo.programConfigPath.DeserializeFromFile<Configuration>()) == null)
//{
// EmuStandInfo.Configuration = new Configuration();
// EmuStandInfo.Configuration.SerializeToFile(EmuStandInfo.programConfigPath);
//}
EmuStandInfo.Configuration = new Configuration();
2025-01-03 01:07:11 +08:00
List<Type> machineType = new List<Type>();
machineType.Add(typeof(GameBoy));
2025-01-07 11:04:34 +08:00
machineType.Add(typeof(GameBoyColor));
machineType.Add(typeof(ColecoVision));
machineType.Add(typeof(GameGear));
machineType.Add(typeof(MasterSystem));
2025-01-07 11:04:34 +08:00
machineType.Add(typeof(SC3000));
machineType.Add(typeof(SG1000));
2025-01-03 01:07:11 +08:00
//foreach (var machineConfigType in Assembly.GetExecutingAssembly().GetTypes().Where(x => typeof(IConfiguration).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract))
foreach (var machineConfigType in machineType)
{
if (!EmuStandInfo.Configuration.Machines.ContainsKey(machineConfigType.Name))
EmuStandInfo.Configuration.Machines.Add(machineConfigType.Name, (IConfiguration)Activator.CreateInstance(machineConfigType));
}
//foreach (var debuggerFormType in Assembly.GetExecutingAssembly().GetTypes().Where(x => typeof(IDebuggerForm).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract))
//{
// if (!StandInfo.Configuration.DebugWindows.ContainsKey(debuggerFormType.Name))
// StandInfo.Configuration.DebugWindows.Add(debuggerFormType.Name, Point.Empty);
//}
}
private void ApplyConfigOverrides(Type machineType)
{
var forcePowerOnWithoutCart = false;
var hasTVStandardOverride = false;
var hasRegionOverride = false;
var hasDisallowMemoryControlOverride = false;
var overrideConfig = EmuStandInfo.Configuration.Machines[machineType.Name].CloneObject();
if (lastGameMetadata == null)
{
var property = overrideConfig.GetType().GetProperty("UseBootstrap");
if (property != null && (bool)property.GetValue(overrideConfig) != true)
{
property.SetValue(overrideConfig, true);
forcePowerOnWithoutCart = true;
}
}
if (lastGameMetadata != null && lastGameMetadata.PreferredTVStandard != TVStandard.Auto)
{
var property = overrideConfig.GetType().GetProperty("TVStandard");
if (property != null)
{
property.SetValue(overrideConfig, lastGameMetadata.PreferredTVStandard);
hasTVStandardOverride = true;
}
}
if (lastGameMetadata != null && lastGameMetadata.PreferredRegion != Essgee.Emulation.Region.Auto)
{
var property = overrideConfig.GetType().GetProperty("Region");
if (property != null)
{
property.SetValue(overrideConfig, lastGameMetadata.PreferredRegion);
hasRegionOverride = true;
}
}
if (lastGameMetadata != null && lastGameMetadata.AllowMemoryControl != true)
{
var propertyMem = overrideConfig.GetType().GetProperty("AllowMemoryControl");
if (propertyMem != null)
{
propertyMem.SetValue(overrideConfig, lastGameMetadata.AllowMemoryControl);
hasDisallowMemoryControlOverride = true;
var propertyBoot = overrideConfig.GetType().GetProperty("UseBootstrap");
if (propertyBoot != null)
{
propertyBoot.SetValue(overrideConfig, false);
}
}
}
if (forcePowerOnWithoutCart)
EssgeeLogger.EnqueueMessageWarning("Bootstrap ROM is disabled in settings; enabling it for this startup.");
if (hasTVStandardOverride)
EssgeeLogger.EnqueueMessageWarning($"Overriding TV standard setting; running game as {lastGameMetadata?.PreferredTVStandard}.");
if (hasRegionOverride)
EssgeeLogger.EnqueueMessageWarning($"Overriding region setting; running game as {lastGameMetadata?.PreferredRegion}.");
if (hasDisallowMemoryControlOverride)
EssgeeLogger.EnqueueMessageWarning("Game-specific hack: Preventing software from reconfiguring memory control.\nBootstrap ROM has been disabled for this startup due to memory control hack.");
if (forcePowerOnWithoutCart || hasTVStandardOverride || hasRegionOverride || hasDisallowMemoryControlOverride)
emulatorHandler.SetConfiguration(overrideConfig);
}
public static void SaveConfiguration()
{
EmuStandInfo.Configuration.SerializeToFile(EmuStandInfo.programConfigPath);
}
#endregion
#region ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public void SetEmuFpsLimit(bool bOpen)
{
emulatorHandler?.SetFpsLimiting(bOpen);
}
public void SetSoundMute(bool bOpen)
{
//soundHandler?.SetMute(Program.Configuration.Mute);
}
public void SetSoundLowPassFilter(bool bOpen)
{
//soundHandler?.SetLowPassFilter(Program.Configuration.LowPassFilter);;
}
public void SetTemporaryPause(bool newTemporaryPauseState)
{
if (emulatorHandler == null || !emulatorHandler.IsRunning || !EmuStandInfo.Configuration.AutoPause) return;
if (newTemporaryPauseState)
emulatorHandler.Pause(true);
else if (!lastUserPauseState)
emulatorHandler.Pause(false);
}
#endregion
#region ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private void PowerOnWithoutCartridge(Type machineType)
{
//TODO IsRecording?? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫʵ<D2AA><CAB5>
//if (soundHandler.IsRecording)
// soundHandler.CancelRecording();
InitializeEmulation(machineType);
lastGameMetadata = null;
ApplyConfigOverrides(machineType);
emulatorHandler.Startup();
EssgeeLogger.EnqueueMessageSuccess("Power on without cartridge.");
}
private void LoadAndRunCartridge(string fileName)
{
try
{
var (machineType, romData) = CartridgeLoader.Load(fileName, "ROM image");
//TODO IsRecording?? <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫʵ<D2AA><CAB5>
//if (soundHandler.IsRecording)
// soundHandler.CancelRecording();
InitializeEmulation(machineType);
lastGameMetadata = gameMetadataHandler.GetGameMetadata(emulatorHandler.Information.DatFileName, fileName, Crc32.Calculate(romData), romData.Length);
ApplyConfigOverrides(machineType);
emulatorHandler.LoadCartridge(romData, lastGameMetadata);
//AddToRecentFiles(fileName);
//CreateRecentFilesMenu();
//CreateLoadSaveStateMenus();
//CreateToggleGraphicsLayersMenu();
//CreateToggleSoundChannelsMenu();
//takeScreenshotToolStripMenuItem.Enabled = pauseToolStripMenuItem.Enabled = resetToolStripMenuItem.Enabled = stopToolStripMenuItem.Enabled = true;
//loadStateToolStripMenuItem.Enabled = saveStateToolStripMenuItem.Enabled = true;
//startRecordingToolStripMenuItem.Enabled = true;
//toggleLayersToolStripMenuItem.Enabled = enableChannelsToolStripMenuItem.Enabled = true;
//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ͬƽ̨<C6BD>İ<EFBFBD>ť
mUniKeyboard.Init(emulatorHandler.emulator);
2025-01-03 01:07:11 +08:00
emulatorHandler.Startup();
//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>Ƶ
soundHandler.Initialize();
2025-01-03 01:07:11 +08:00
//SizeAndPositionWindow();
//SetWindowTitleAndStatus();
EssgeeLogger.EnqueueMessage($"Loaded '{lastGameMetadata?.KnownName ?? "unrecognized game"}'.");
}
catch (Exception ex) when (!AppEnvironment.DebugMode)
{
ExceptionHandler(ex);
}
}
private void InitializeEmulation(Type machineType)
{
if (emulatorHandler != null)
ShutdownEmulation();
emulatorHandler = new EmulatorHandler(machineType, ExceptionHandler);
emulatorHandler.Initialize();
emulatorHandler.SendLogMessage += EmulatorHandler_SendLogMessage;
emulatorHandler.EmulationReset += EmulatorHandler_EmulationReset;
emulatorHandler.RenderScreen += EmulatorHandler_RenderScreen;
emulatorHandler.SizeScreen += EmulatorHandler_SizeScreen;
emulatorHandler.ChangeViewport += EmulatorHandler_ChangeViewport;
emulatorHandler.PollInput += EmulatorHandler_PollInput;
emulatorHandler.EnqueueSamples += EnqueueSoundSamples;
emulatorHandler.SaveExtraData += EmulatorHandler_SaveExtraData;
emulatorHandler.EnableRumble += EmulatorHandler_EnableRumble;
emulatorHandler.PauseChanged += EmulatorHandler_PauseChanged;
//emulatorHandler.EnqueueSamples += soundDebuggerForm.EnqueueSamples;
emulatorHandler.SetFpsLimiting(EmuStandInfo.Configuration.LimitFps);
emulatorHandler.SetConfiguration(EmuStandInfo.Configuration.Machines[machineType.Name]);
currentPixelAspectRatio = emulatorHandler.Information.PixelAspectRatio;
//pauseToolStripMenuItem.DataBindings.Clear();
//pauseToolStripMenuItem.CheckedChanged += (s, e) =>
//{
// var pauseState = (s as ToolStripMenuItem).Checked;
// emulatorHandler.Pause(pauseState);
// lastUserPauseState = pauseState;
//};
EssgeeLogger.EnqueueMessageSuccess($"{emulatorHandler.Information.Manufacturer} {emulatorHandler.Information.Model} emulation initialized.");
}
private void ExceptionHandler(Exception ex)
{
//this.CheckInvokeMethod(() =>
//{
if (!AppEnvironment.TemporaryDisableCustomExceptionForm)
{
//TODO debug<75><67><EFBFBD>ڣ<EFBFBD>
//(_, ExceptionResult result, string prefix, string postfix) = ExceptionForm.GetExceptionInfo(ex);
//if (result == ExceptionResult.Continue)
//{
// //MessageBox.Show($"{prefix}{ex.InnerException?.Message ?? ex.Message}\n\n{postfix}.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
// EssgeeLogger.Err($"{prefix}{ex.InnerException?.Message ?? ex.Message}\n\n{postfix}.");
//}
//else
//{
// //var exceptionForm = new ExceptionForm(ex) { Owner = this };
// //exceptionForm.ShowDialog();
// switch (result)
// {
// case ExceptionResult.StopEmulation:
// SignalStopEmulation();
// break;
// case ExceptionResult.ExitApplication:
// Environment.Exit(-1);
// break;
// }
//}
}
else
{
var exceptionInfoBuilder = new StringBuilder();
exceptionInfoBuilder.AppendLine($"Thread: {ex.Data["Thread"] ?? "<unnamed>"}");
exceptionInfoBuilder.AppendLine($"Function: {ex.TargetSite.ReflectedType.FullName}.{ex.TargetSite.Name}");
exceptionInfoBuilder.AppendLine($"Exception: {ex.GetType().Name}");
exceptionInfoBuilder.Append($"Message: {ex.Message}");
var isUnhandled = Convert.ToBoolean(ex.Data["IsUnhandled"]);
if (!isUnhandled && ex is CartridgeLoaderException)
{
//MessageBox.Show($"{ex.InnerException?.Message ?? ex.Message}\n\nFailed to load cartridge.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
EssgeeLogger.Err($"{ex.InnerException?.Message ?? ex.Message}\n\nFailed to load cartridge.");
}
else if (!isUnhandled && ex is EmulationException)
{
//MessageBox.Show($"An emulation exception has occured!\n\n{exceptionInfoBuilder.ToString()}\n\nEmulation cannot continue and will be terminated.", "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
EssgeeLogger.Err($"An emulation exception has occured!\n\n{exceptionInfoBuilder.ToString()}\n\nEmulation cannot continue and will be terminated.");
SignalStopEmulation();
}
else
{
var errorBuilder = new StringBuilder();
errorBuilder.AppendLine("An unhandled exception has occured!");
errorBuilder.AppendLine();
errorBuilder.AppendLine(exceptionInfoBuilder.ToString());
errorBuilder.AppendLine();
errorBuilder.AppendLine("Exception occured:");
errorBuilder.AppendLine($"{ex.StackTrace}");
errorBuilder.AppendLine();
errorBuilder.AppendLine("Execution cannot continue and the application will be terminated.");
//EssgeeLogger.Err(errorBuilder.ToString(), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
EssgeeLogger.Err(errorBuilder.ToString());
Environment.Exit(-1);
}
}
//});
}
private void SignalStopEmulation()
{
ShutdownEmulation();
lastGameMetadata = null;
//takeScreenshotToolStripMenuItem.Enabled = pauseToolStripMenuItem.Enabled = resetToolStripMenuItem.Enabled = stopToolStripMenuItem.Enabled = false;
//loadStateToolStripMenuItem.Enabled = saveStateToolStripMenuItem.Enabled = false;
//startRecordingToolStripMenuItem.Enabled = false;
//toggleLayersToolStripMenuItem.Enabled = enableChannelsToolStripMenuItem.Enabled = false;
//SetWindowTitleAndStatus();
}
private void ShutdownEmulation()
{
if (emulatorHandler == null) return;
emulatorHandler.SaveCartridge();
emulatorHandler.SendLogMessage -= EmulatorHandler_SendLogMessage;
emulatorHandler.EmulationReset -= EmulatorHandler_EmulationReset;
emulatorHandler.RenderScreen -= EmulatorHandler_RenderScreen;
emulatorHandler.SizeScreen -= EmulatorHandler_SizeScreen;
emulatorHandler.ChangeViewport -= EmulatorHandler_ChangeViewport;
emulatorHandler.PollInput -= EmulatorHandler_PollInput;
emulatorHandler.EnqueueSamples -= EnqueueSoundSamples;
emulatorHandler.SaveExtraData -= EmulatorHandler_SaveExtraData;
emulatorHandler.EnableRumble -= EmulatorHandler_EnableRumble;
emulatorHandler.PauseChanged -= EmulatorHandler_PauseChanged;
//emulatorHandler.EnqueueSamples -= soundDebuggerForm.EnqueueSamples;
emulatorHandler.Shutdown();
while (emulatorHandler.IsRunning) { }
emulatorHandler = null;
GC.Collect();
//graphicsHandler?.FlushTextures();
EssgeeLogger.WriteLine("Emulation stopped.");
}
#endregion
#region ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD>¼<EFBFBD>
private void EmulatorHandler_SendLogMessage(object sender, SendLogMessageEventArgs e)
{
//this.CheckInvokeMethod(delegate () { onScreenDisplayHandler.EnqueueMessageCore($"{emulatorHandler.Information.Model}: {e.Message}"); });
//TODO log
EssgeeLogger.EnqueueMessageSuccess($"{emulatorHandler.Information.Model}: {e.Message}");
}
private void EmulatorHandler_EmulationReset(object sender, EventArgs e)
{
//this.CheckInvokeMethod(delegate () { onScreenDisplayHandler.EnqueueMessage("Emulation reset."); });
EssgeeLogger.EnqueueMessageSuccess("Emulation reset.");
}
private void EmulatorHandler_RenderScreen(object sender, RenderScreenEventArgs e)
{
//this.CheckInvokeMethod(delegate ()
//{
//if (e.Width != lastFramebufferSize.width || e.Height != lastFramebufferSize.height)
//{
// lastFramebufferSize = (e.Width, e.Height);
// graphicsHandler?.SetTextureSize(e.Width, e.Height);
//}
//lastFramebufferData = e.FrameData;
//graphicsHandler?.SetTextureData(e.FrameData);
//graphicsHandler.SubmitVideo(e.Width, e.Height, e.FrameData, 0);
graphicsHandler.SubmitVideo(e.Width, e.Height, e.FrameDataPtr, 0);
2025-01-03 01:07:11 +08:00
// TODO: create emulation "EndOfFrame" event for this?
ControllerManager.Update();
//});
}
private void EmulatorHandler_SizeScreen(object sender, SizeScreenEventArgs e)
{
//TODO <20><>ʵ<EFBFBD><CAB5> <20><>Ļ<EFBFBD><C4BB>С
//this.CheckInvokeMethod(delegate ()
//{
// lastFramebufferSize = (e.Width, e.Height);
// graphicsHandler?.SetTextureSize(e.Width, e.Height);
//});
}
private void EmulatorHandler_ChangeViewport(object sender, ChangeViewportEventArgs e)
{
//TODO <20><>ʵ<EFBFBD><CAB5>
//this.CheckInvokeMethod(delegate ()
//{
// graphicsHandler?.SetScreenViewport(currentViewport = e.Viewport);
// SizeAndPositionWindow();
//});
}
private void EmulatorHandler_PollInput(object sender, PollInputEventArgs e)
{
//TODO Inputʵ<74><CAB5>
//e.Keyboard = mUniKeyboard.mKeyCodeCore.GetPressedKeys();
e.Keyboard.AddRange(mUniKeyboard.mKeyCodeCore.GetPressedKeys());
e.MouseButtons = default;
e.MousePosition = default;
// TODO: rare, random, weird argument exceptions on e.Keyboard assignment; does this lock help??
2025-01-03 01:07:11 +08:00
//lock (uiLock)
//{
// e.Keyboard = new List<MotionKey>(keysDown);
2025-01-03 01:07:11 +08:00
// e.MouseButtons = mouseButtonsDown;
// var vx = (currentViewport.x - 50);
// var dvx = renderControl.ClientSize.Width / (currentViewport.width - (double)vx);
// var dvy = renderControl.ClientSize.Height / (currentViewport.height - (double)currentViewport.y);
// e.MousePosition = ((int)(mousePosition.x / dvx) - vx, (int)(mousePosition.y / dvy) - currentViewport.y);
// if (EmuStandInfo.Configuration.EnableXInput)
// e.ControllerState = ControllerManager.GetController(0).GetControllerState();
//}
}
private void EmulatorHandler_SaveExtraData(object sender, SaveExtraDataEventArgs e)
{
/* Extract options etc. */
var includeDateTime = e.Options.HasFlag(ExtraDataOptions.IncludeDateTime);
var allowOverwrite = e.Options.HasFlag(ExtraDataOptions.AllowOverwrite);
var extension = string.Empty;
switch (e.DataType)
{
case ExtraDataTypes.Image: extension = "png"; break;
case ExtraDataTypes.Raw: extension = "bin"; break;
default: throw new EmulationException($"Unknown extra data type {e.DataType}");
}
/* Generate filename/path */
var filePrefix = $"{Path.GetFileNameWithoutExtension(lastGameMetadata.FileName)} ({e.Description}{(includeDateTime ? $" {DateTime.Now:yyyy-MM-dd HH-mm-ss})" : ")")}";
var filePath = Path.Combine(EmuStandInfo.ExtraDataPath, $"{filePrefix}.{extension}");
if (!allowOverwrite)
{
var existingFiles = Directory.EnumerateFiles(EmuStandInfo.ExtraDataPath, $"{filePrefix}*{extension}");
if (existingFiles.Contains(filePath))
for (int i = 2; existingFiles.Contains(filePath = Path.Combine(EmuStandInfo.ExtraDataPath, $"{filePrefix} ({i}).{extension}")); i++) { }
}
/* Handle data */
//if (e.Data is Bitmap image)
if (e.DataType == ExtraDataTypes.Image)
{
/* Images, ex. GB Printer printouts */
//image.Save(filePath);
//TODO ͼ<><CDBC><EFBFBD>
}
else if (e.Data is byte[] raw)
{
/* Raw bytes */
using (var file = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
file.Write(raw, 0, raw.Length);
}
}
}
private void EmulatorHandler_EnableRumble(object sender, EventArgs e)
{
if (EmuStandInfo.Configuration.EnableXInput && EmuStandInfo.Configuration.EnableRumble)
ControllerManager.GetController(0).Vibrate(0.0f, 0.5f, TimeSpan.FromSeconds(0.1f));
}
private void EmulatorHandler_PauseChanged(object sender, EventArgs e)
{
//SetWindowTitleAndStatus();
if (emulatorHandler.IsPaused)
{
//TODO <20><>Ƶ<EFBFBD><C6B5>ͣ<EFBFBD><CDA3>
//soundHandler?.ClearSampleBuffer();
}
}
public void EnqueueSoundSamples(object sender, EnqueueSamplesEventArgs e)
{
//if (sampleQueue.Count > MaxQueueLength)
//{
// var samplesToDrop = (sampleQueue.Count - MaxQueueLength);
// onScreenDisplayHandler.EnqueueMessageDebug($"({GetType().Name}/{DateTime.Now.Second:D2}s) Sample queue overflow; dropping {samplesToDrop} of {sampleQueue.Count} samples.");
// for (int i = 0; i < samplesToDrop; i++)
// if (sampleQueue.Count != 0)
// sampleQueue.Dequeue();
//}
//sampleQueue.Enqueue(e.MixedSamples.ToArray());
//if (IsRecording)
//{
// dataChunk.AddSampleData(e.MixedSamples);
// waveHeader.FileLength += (uint)e.MixedSamples.Length;
//}
//TODO <20><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>
soundHandler.SubmitSamples(e.MixedSamples, e.ChannelSamples, e.MixedSamples.Length);
2025-01-03 01:07:11 +08:00
}
#endregion
}