Files
ARMSX2/pcsx2/SaveStateLegacy.h
Brian Degenhardt 078b5d661b SaveState: load AetherSX2/NetherSX2-format save states
Accept the two legacy majors at the version gate and route them to the legacy
reader, so states from AetherSX2 v1.5-era builds and NetherSX2 v2.1 load in
place. Re-saving one writes a current-format state, which is the whole of the
conversion story.

Three of the zip entries need era-specific handling, so entries now declare how
they survive a legacy load:

- GS carries its own version, which Defrost still reads back through these
  eras. Only its size has to come from the zip entry rather than from today's
  component, since the generic reader would otherwise demand a current-sized
  block and reject a short read.
- SPU2 shares only its head (registers and sample RAM) across eras; its tail
  was re-laid-out repeatedly while the block's self-version stayed at 0xe, so
  the self-version cannot arbitrate it and ThawIt must never see one. The new
  SPU2freezeLegacy restores the memory and resets the cores instead, which
  costs a note in flight and nothing else.
- PAD, USB and achievements predate the StateWrapper streams that read them
  today. They are skipped, and correspondingly not required to be present: the
  pads keep the type and mode they booted with.

The GS entry's existing overrides gain the `override` keyword, which adding one
to the class now requires.
2026-08-02 11:19:56 -07:00

28 lines
1.2 KiB
C++

// SPDX-FileCopyrightText: 2026 yaps2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include "common/Pcsx2Types.h"
// Loader for legacy-format savestates: upstream-PCSX2 formats of the
// AetherSX2/NetherSX2 era. The container (zip entry set) is unchanged across
// eras; what differs is the layout of the versioned blobs. The supported
// legacy majors and the blob reader live in SaveStateLegacy.cpp; the per-entry
// legacy handling (GS/SPU2/PAD) hangs off SaveState_UnzipFromZip.
namespace SaveStateLegacy
{
// The legacy savestate majors the in-engine reader understands:
// 0x9A2C — upstream PCSX2 at 0312e902 (the AetherSX2 v1.5-era format)
// 0x9A34 — upstream PCSX2 at 7e939b75 (the NetherSX2 v2.1 format)
bool IsSupportedVersion(u32 savever);
// Widens a wrapping 32-bit cycle counter to 64 bits relative to a domain
// base: the signed 32-bit delta to the old base is preserved against the
// new base. Correct across u32 wraps, which zero-extension is not.
inline constexpr u64 WidenCycle(u32 old_value, u32 old_base, u64 new_base)
{
return new_base + static_cast<s64>(static_cast<s32>(old_value - old_base));
}
} // namespace SaveStateLegacy