实现存档以及读取存档功能

This commit is contained in:
Alienjack 2025-04-13 19:03:43 +08:00
parent f325e63e26
commit 3dc7e9acd1
5 changed files with 80 additions and 18 deletions

View File

@ -38,6 +38,8 @@ namespace AxibugEmuOnline.Client
} }
} }
public event Action OnSavSuccessed;
/// <summary> 存档顺序号,用于判断云存档和本地存档的同步状态,是否存在冲突 </summary> /// <summary> 存档顺序号,用于判断云存档和本地存档的同步状态,是否存在冲突 </summary>
public uint Sequecen { get; private set; } public uint Sequecen { get; private set; }
@ -126,7 +128,7 @@ namespace AxibugEmuOnline.Client
m_headerCache = new Header(); m_headerCache = new Header();
fixed (Header* headPtr = &m_headerCache) fixed (Header* headPtr = &m_headerCache)
{ {
var headP=(byte*)headPtr; var headP = (byte*)headPtr;
Marshal.Copy(raw, 0, (IntPtr)headP, sizeof(Header)); Marshal.Copy(raw, 0, (IntPtr)headP, sizeof(Header));
} }
@ -179,6 +181,8 @@ namespace AxibugEmuOnline.Client
m_screenShotCaches = screenShotData; m_screenShotCaches = screenShotData;
IsEmpty = false; IsEmpty = false;
OnSavSuccessed?.Invoke();
} }
/// <summary> /// <summary>

View File

@ -9,7 +9,7 @@ namespace AxibugEmuOnline.Client
{ {
private InGameUI m_gameUI; private InGameUI m_gameUI;
public override string Name => "存"; public override string Name => "";
public InGameUI_SaveStateMenu(InGameUI inGameUI) public InGameUI_SaveStateMenu(InGameUI inGameUI)
{ {
@ -22,39 +22,81 @@ namespace AxibugEmuOnline.Client
List<InternalOptionMenu> result = new List<InternalOptionMenu>(); List<InternalOptionMenu> result = new List<InternalOptionMenu>();
foreach (var savFile in saveFiles) foreach (var savFile in saveFiles)
{ {
if (savFile.AutoSave) continue;
result.Add(new SaveSlotMenu(m_gameUI, savFile)); result.Add(new SaveSlotMenu(m_gameUI, savFile));
} }
return result; return result;
} }
/// <summary> 存档侧边选项UI </summary> /// <summary> 存档侧边选项UI </summary>
public class SaveSlotMenu : ExecuteMenu public class SaveSlotMenu : ExpandMenu
{ {
public override Type MenuUITemplateType => typeof(OptionUI_SavSlotItem); public override Type MenuUITemplateType => typeof(OptionUI_SavSlotItem);
public SaveFile SavFile { get; private set; } public SaveFile SavFile { get; private set; }
private InGameUI m_ingameUI; List<InternalOptionMenu> m_subOptions = new List<InternalOptionMenu>();
public override string Name => SavFile.AutoSave ? "自动存档" : $"存档{SavFile.SlotIndex}";
public override bool Visible => !SavFile.AutoSave;
public SaveSlotMenu(InGameUI inGameui, SaveFile savFile) public SaveSlotMenu(InGameUI inGameui, SaveFile savFile)
{ {
SavFile = savFile; SavFile = savFile;
m_ingameUI = inGameui;
//非自动存档,增加保存选项
if (!savFile.AutoSave) m_subOptions.Add(new SaveMenuItem(inGameui, savFile));
//添加读取选项
m_subOptions.Add(new LoadMenuItem(inGameui, savFile));
} }
public override void OnExcute(OptionUI optionUI, ref bool cancelHide) protected override List<InternalOptionMenu> GetOptionMenus()
{ {
cancelHide = true; return m_subOptions;
var stateData = m_ingameUI.Core.GetStateBytes();
var tex = m_ingameUI.Core.OutputPixel;
var screenData = tex.ToJPG();
SavFile.Save(SavFile.Sequecen, stateData, screenData);
} }
public override string Name => SavFile.AutoSave ? "自动存档" : $"存档{SavFile.SlotIndex}"; public class SaveMenuItem : ExecuteMenu
{
SaveFile m_savFile;
InGameUI m_ingameUI;
public override string Name => "保存";
public SaveMenuItem(InGameUI inGameui, SaveFile savFile)
{
m_ingameUI = inGameui;
m_savFile = savFile;
}
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
{
var stateData = m_ingameUI.Core.GetStateBytes();
var tex = m_ingameUI.Core.OutputPixel;
var screenData = tex.ToJPG();
m_savFile.Save(m_savFile.Sequecen, stateData, screenData);
}
}
public class LoadMenuItem : ExecuteMenu
{
SaveFile m_savFile;
InGameUI m_ingameUI;
public override string Name => "读取";
public LoadMenuItem(InGameUI inGameui, SaveFile savFile)
{
m_ingameUI = inGameui;
m_savFile = savFile;
}
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
{
cancelHide = true;
m_savFile.GetSavData(out byte[] savData, out var _);
if (savData != null)
{
m_ingameUI.Core.LoadStateFromBytes(savData);
}
OverlayManager.HideSideBar();
}
}
} }
} }
} }

View File

@ -221,14 +221,21 @@ namespace AxibugEmuOnline.Client
} }
/// <summary>
/// 关闭这个侧边栏选项UI
/// </summary>
public void Hide() public void Hide()
{ {
if (m_bPoped) if (m_bPoped)
{ {
if (m_child != null)
{
m_child.Hide();
}
Vector2 start = new Vector2(-MenuRoot.rect.width, MenuRoot.anchoredPosition.y); Vector2 start = new Vector2(-MenuRoot.rect.width, MenuRoot.anchoredPosition.y);
Vector2 end = new Vector2(0, MenuRoot.anchoredPosition.y); Vector2 end = new Vector2(0, MenuRoot.anchoredPosition.y);
ReleaseRuntimeMenus(); ReleaseRuntimeMenus();
m_runtimeMenuItems.Clear(); m_runtimeMenuItems.Clear();

View File

@ -17,6 +17,8 @@ namespace AxibugEmuOnline.Client
base.OnSetData(menuData); base.OnSetData(menuData);
RefreshUI(); RefreshUI();
MenuData.SavFile.OnSavSuccessed += RefreshUI;
} }
private void RefreshUI() private void RefreshUI()
@ -57,12 +59,13 @@ namespace AxibugEmuOnline.Client
Destroy(m_screenTex); Destroy(m_screenTex);
m_screenTex = null; m_screenTex = null;
} }
MenuData.SavFile.OnSavSuccessed -= RefreshUI;
} }
public override void OnExecute(OptionUI optionUI, ref bool cancelHide) public override void OnExecute(OptionUI optionUI, ref bool cancelHide)
{ {
MenuData.OnExcute(optionUI, ref cancelHide); MenuData.OnExcute(optionUI, ref cancelHide);
RefreshUI();
} }
} }
} }

View File

@ -39,9 +39,15 @@ namespace AxibugEmuOnline.Client
s_ins.m_OptionUI.Pop(menus, defaultIndex, onClose); s_ins.m_OptionUI.Pop(menus, defaultIndex, onClose);
} }
public static void HideSideBar()
{
s_ins.m_OptionUI.Hide();
}
public static void PopTip(string msg) public static void PopTip(string msg)
{ {
s_ins.m_popTipsUI.Pop(msg); s_ins.m_popTipsUI.Pop(msg);
} }
} }
} }