195 lines
6.9 KiB
C#
195 lines
6.9 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace MyNes.Core
|
|
{
|
|
public class StateHandler
|
|
{
|
|
public static int Slot = 0;
|
|
|
|
internal static string StateFolder = "States";
|
|
|
|
private const byte state_version = 7;
|
|
|
|
private static bool IsSavingState = false;
|
|
|
|
private static bool IsLoadingState = false;
|
|
|
|
public static void SaveState(string fileName, bool saveImage)
|
|
{
|
|
if (!NesEmu.ON)
|
|
{
|
|
Tracer.WriteError("Can't save state, emu is off.");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error1, instant: false);
|
|
return;
|
|
}
|
|
if (!File.Exists(NesEmu.CurrentFilePath))
|
|
{
|
|
Tracer.WriteError("Can't save state, no rom file is loaded.");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error2, instant: false);
|
|
return;
|
|
}
|
|
if (IsLoadingState)
|
|
{
|
|
Tracer.WriteError("Can't save state while loading a state !");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error3, instant: false);
|
|
return;
|
|
}
|
|
if (IsSavingState)
|
|
{
|
|
Tracer.WriteError("Already saving state !!");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error4, instant: false);
|
|
return;
|
|
}
|
|
IsSavingState = true;
|
|
BinaryWriter bin = new BinaryWriter(new MemoryStream());
|
|
bin.Write(Encoding.ASCII.GetBytes("MNS"));
|
|
bin.Write((byte)7);
|
|
for (int i = 0; i < NesEmu.SHA1.Length; i += 2)
|
|
{
|
|
string value = NesEmu.SHA1.Substring(i, 2).ToUpper();
|
|
bin.Write(Convert.ToByte(value, 16));
|
|
}
|
|
NesEmu.WriteStateData(ref bin);
|
|
byte[] outData = new byte[0];
|
|
ZlipWrapper.CompressData(((MemoryStream)bin.BaseStream).GetBuffer(), out outData);
|
|
FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write);
|
|
fileStream.Write(outData, 0, outData.Length);
|
|
MyNesMain.VideoProvider.TakeSnapshotAs(fileName.Replace(".mns", ".jpg"), ".jpg");
|
|
bin.Flush();
|
|
bin.Close();
|
|
fileStream.Flush();
|
|
fileStream.Close();
|
|
IsSavingState = false;
|
|
Tracer.WriteInformation("State saved at slot " + Slot);
|
|
MyNesMain.VideoProvider.WriteInfoNotification(MNInterfaceLanguage.Message_Info1 + " " + Slot, instant: false);
|
|
}
|
|
|
|
public static void SaveState(int Slot)
|
|
{
|
|
if (StateFolder == "States")
|
|
{
|
|
StateFolder = Path.Combine(MyNesMain.WorkingFolder, "States");
|
|
}
|
|
Directory.CreateDirectory(StateFolder);
|
|
SaveState(Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + Slot + ".mns", saveImage: false);
|
|
}
|
|
|
|
public static void SaveState()
|
|
{
|
|
SaveState(Slot);
|
|
}
|
|
|
|
public static void LoadState()
|
|
{
|
|
LoadState(Slot);
|
|
}
|
|
|
|
public static void LoadState(string fileName)
|
|
{
|
|
if (!NesEmu.ON)
|
|
{
|
|
Tracer.WriteError("Can't load state, emu is off.");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error5, instant: false);
|
|
return;
|
|
}
|
|
if (!File.Exists(NesEmu.CurrentFilePath))
|
|
{
|
|
Tracer.WriteError("Can't load state, no rom file is loaded.");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error6, instant: false);
|
|
return;
|
|
}
|
|
if (IsSavingState)
|
|
{
|
|
Tracer.WriteError("Can't load state while saving a state !");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error7, instant: false);
|
|
return;
|
|
}
|
|
if (IsLoadingState)
|
|
{
|
|
Tracer.WriteError("Already loading state !!");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error8, instant: false);
|
|
return;
|
|
}
|
|
if (!File.Exists(fileName))
|
|
{
|
|
Tracer.WriteError("No state found in slot " + Slot);
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error9 + " " + Slot, instant: false);
|
|
return;
|
|
}
|
|
IsLoadingState = true;
|
|
FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
|
|
byte[] array = new byte[fileStream.Length];
|
|
byte[] outData = new byte[0];
|
|
fileStream.Read(array, 0, array.Length);
|
|
fileStream.Close();
|
|
ZlipWrapper.DecompressData(array, out outData);
|
|
BinaryReader bin = new BinaryReader(new MemoryStream(outData));
|
|
byte[] array2 = new byte[3];
|
|
bin.Read(array2, 0, array2.Length);
|
|
if (Encoding.ASCII.GetString(array2) != "MNS")
|
|
{
|
|
Tracer.WriteError("Unable load state at slot " + Slot + "; Not My Nes State File !");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error10 + " " + Slot + "; " + MNInterfaceLanguage.Message_Error11, instant: false);
|
|
IsLoadingState = false;
|
|
return;
|
|
}
|
|
if (bin.ReadByte() != 7)
|
|
{
|
|
Tracer.WriteError("Unable load state at slot " + Slot + "; Not compatible state file version !");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error10 + " " + Slot + "; " + MNInterfaceLanguage.Message_Error12, instant: false);
|
|
IsLoadingState = false;
|
|
return;
|
|
}
|
|
string text = "";
|
|
for (int i = 0; i < NesEmu.SHA1.Length; i += 2)
|
|
{
|
|
text += bin.ReadByte().ToString("X2");
|
|
}
|
|
if (text.ToLower() != NesEmu.SHA1.ToLower())
|
|
{
|
|
Tracer.WriteError("Unable load state at slot " + Slot + "; This state file is not for this game; not same SHA1 !");
|
|
MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error10 + " " + Slot + "; " + MNInterfaceLanguage.Message_Error13, instant: false);
|
|
IsLoadingState = false;
|
|
}
|
|
else
|
|
{
|
|
NesEmu.ReadStateData(ref bin);
|
|
bin.Close();
|
|
IsLoadingState = false;
|
|
Tracer.WriteInformation("State loaded from slot " + Slot);
|
|
MyNesMain.VideoProvider.WriteInfoNotification(MNInterfaceLanguage.Message_Info2 + " " + Slot, instant: false);
|
|
}
|
|
}
|
|
|
|
public static void LoadState(int Slot)
|
|
{
|
|
if (StateFolder == "States")
|
|
{
|
|
StateFolder = Path.Combine(MyNesMain.WorkingFolder, "States");
|
|
}
|
|
Directory.CreateDirectory(StateFolder);
|
|
LoadState(Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + Slot + ".mns");
|
|
}
|
|
|
|
public static string GetStateFile(int slot)
|
|
{
|
|
if (File.Exists(NesEmu.CurrentFilePath))
|
|
{
|
|
return Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + slot + ".mns";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public static string GetStateImageFile(int slot)
|
|
{
|
|
if (File.Exists(NesEmu.CurrentFilePath))
|
|
{
|
|
return Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + slot + ".jpg";
|
|
}
|
|
return "";
|
|
}
|
|
}
|
|
}
|