Skip to content
This repository was archived by the owner on Mar 21, 2025. It is now read-only.

code: Nuke savestate support #42

Merged
merged 1 commit into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,6 @@ add_subdirectory(externals)
if (NOT USE_SYSTEM_BOOST)
add_definitions( -DBOOST_ALL_NO_LIB )
add_library(Boost::boost ALIAS boost)
add_library(Boost::serialization ALIAS boost_serialization)
add_library(Boost::iostreams ALIAS boost_iostreams)
endif()

Expand Down
5 changes: 0 additions & 5 deletions externals/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ if (NOT USE_SYSTEM_BOOST)
add_library(boost INTERFACE)
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})

# Boost::serialization
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
add_library(boost_serialization STATIC ${boost_serialization_SRC})
target_link_libraries(boost_serialization PUBLIC boost)

# Boost::iostreams
add_library(
boost_iostreams
Expand Down
22 changes: 3 additions & 19 deletions src/android/app/src/main/jni/native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include "core/hle/service/am/am.h"
#include "core/hle/service/nfc/nfc.h"
#include "core/loader/loader.h"
#include "core/savestate.h"
#include "core/telemetry_session.h"
#include "jni/android_common/android_common.h"
#include "jni/applets/mii_selector.h"
Expand Down Expand Up @@ -430,7 +429,8 @@ jobject Java_org_citra_citra_1emu_NativeLibrary_downloadTitleFromNus([[maybe_unu
[[maybe_unused]] jobject obj,
jlong title) {
const auto title_id = static_cast<u64>(title);
Service::AM::InstallStatus status = Service::AM::InstallFromNus(title_id);
auto& system = Core::System::GetInstance();
Service::AM::InstallStatus status = Service::AM::InstallFromNus(system, title_id);
if (status != Service::AM::InstallStatus::Success) {
return IDCache::GetJavaCiaInstallStatus(status);
}
Expand Down Expand Up @@ -690,12 +690,7 @@ JNIEXPORT jobject JNICALL Java_org_citra_citra_1emu_utils_CiaInstallWorker_insta

jobjectArray Java_org_citra_citra_1emu_NativeLibrary_getSavestateInfo(
JNIEnv* env, [[maybe_unused]] jobject obj) {
const jclass date_class = env->FindClass("java/util/Date");
const auto date_constructor = env->GetMethodID(date_class, "<init>", "(J)V");

const jclass savestate_info_class = IDCache::GetSavestateInfoClass();
const auto slot_field = env->GetFieldID(savestate_info_class, "slot", "I");
const auto date_field = env->GetFieldID(savestate_info_class, "time", "Ljava/util/Date;");

const Core::System& system{Core::System::GetInstance()};
if (!system.IsPoweredOn()) {
Expand All @@ -707,18 +702,7 @@ jobjectArray Java_org_citra_citra_1emu_NativeLibrary_getSavestateInfo(
return nullptr;
}

const auto savestates = Core::ListSaveStates(title_id, system.Movie().GetCurrentMovieID());
const jobjectArray array =
env->NewObjectArray(static_cast<jsize>(savestates.size()), savestate_info_class, nullptr);
for (std::size_t i = 0; i < savestates.size(); ++i) {
const jobject object = env->AllocObject(savestate_info_class);
env->SetIntField(object, slot_field, static_cast<jint>(savestates[i].slot));
env->SetObjectField(object, date_field,
env->NewObject(date_class, date_constructor,
static_cast<jlong>(savestates[i].time * 1000)));

env->SetObjectArrayElement(array, i, object);
}
const jobjectArray array = env->NewObjectArray(jsize(0), savestate_info_class, nullptr);
return array;
}

Expand Down
6 changes: 1 addition & 5 deletions src/audio_core/dsp_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

#pragma once

#include <functional>
#include <memory>
#include <span>
#include <boost/serialization/access.hpp>
#include "audio_core/audio_types.h"
#include "audio_core/time_stretch.h"
#include "common/common_types.h"
Expand Down Expand Up @@ -123,10 +123,6 @@ class DspInterface {
std::array<s16, 2> last_frame{};
TimeStretcher time_stretcher;
std::unique_ptr<Sink> sink;

template <class Archive>
void serialize(Archive& ar, const unsigned int) {}
friend class boost::serialization::access;
};

} // namespace AudioCore
24 changes: 0 additions & 24 deletions src/audio_core/hle/hle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#include <boost/serialization/array.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/weak_ptr.hpp>
#include "audio_core/audio_types.h"
#include "audio_core/hle/aac_decoder.h"
#include "audio_core/hle/common.h"
Expand All @@ -16,7 +11,6 @@
#include "audio_core/hle/shared_memory.h"
#include "audio_core/hle/source.h"
#include "audio_core/sink.h"
#include "common/archives.h"
#include "common/assert.h"
#include "common/common_types.h"
#include "common/hash.h"
Expand All @@ -30,13 +24,6 @@ namespace AudioCore {

DspHle::DspHle(Core::System& system) : DspHle(system, system.Memory(), system.CoreTiming()) {}

template <class Archive>
void DspHle::serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<DspInterface>(*this);
ar&* impl.get();
}
SERIALIZE_IMPL(DspHle)

// The value below is the "perfect" mathematical ratio of ARM11 cycles per audio frame, samples per
// frame * teaklite cycles per sample * 2 ARM11 cycles/teaklite cycle
// (160 * 4096 * 2) = (1310720)
Expand Down Expand Up @@ -95,17 +82,6 @@ struct DspHle::Impl final {
std::unique_ptr<HLE::DecoderBase> aac_decoder{};

std::function<void(Service::DSP::InterruptType type, DspPipe pipe)> interrupt_handler{};

template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& dsp_state;
ar& pipe_data;
ar& dsp_memory.raw_memory;
ar& sources;
ar& mixers;
// interrupt_handler is reregistered when loading state from DSP_DSP
}
friend class boost::serialization::access;
};

DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory, Core::Timing& timing)
Expand Down
5 changes: 0 additions & 5 deletions src/audio_core/hle/hle.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <array>
#include <memory>
#include <vector>
#include <boost/serialization/export.hpp>
#include "audio_core/audio_types.h"
#include "audio_core/dsp_interface.h"
#include "common/common_types.h"
Expand Down Expand Up @@ -49,10 +48,6 @@ class DspHle final : public DspInterface {
struct Impl;
friend struct Impl;
std::unique_ptr<Impl> impl;

template <class Archive>
void serialize(Archive& ar, const unsigned int);
friend class boost::serialization::access;
};

} // namespace AudioCore
11 changes: 0 additions & 11 deletions src/audio_core/hle/mixers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#pragma once

#include <array>
#include <boost/serialization/array.hpp>
#include "audio_core/audio_types.h"
#include "audio_core/hle/shared_memory.h"

Expand Down Expand Up @@ -54,16 +53,6 @@ class Mixers final {
void DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& samples);
/// INTERNAL: Generate DspStatus based on internal state.
DspStatus GetCurrentStatus() const;

template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& current_frame;
ar& state.intermediate_mixer_volume;
ar& state.aux_bus_enable;
ar& state.intermediate_mix_buffer;
ar& state.output_format;
}
friend class boost::serialization::access;
};

} // namespace AudioCore::HLE
7 changes: 0 additions & 7 deletions src/audio_core/hle/shared_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <cstddef>
#include <memory>
#include <type_traits>
#include <boost/serialization/access.hpp>
#include "audio_core/audio_types.h"
#include "audio_core/hle/common.h"
#include "common/bit_field.h"
Expand Down Expand Up @@ -57,12 +56,6 @@ struct u32_dsp {
return (value << 16) | (value >> 16);
}
u32_le storage;

template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& storage;
}
friend class boost::serialization::access;
};
static_assert(std::is_trivially_copyable<u32_dsp>::value, "u32_dsp isn't trivially copyable");

Expand Down
49 changes: 0 additions & 49 deletions src/audio_core/hle/source.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@

#include <array>
#include <vector>
#include <boost/serialization/array.hpp>
#include <boost/serialization/deque.hpp>
#include <boost/serialization/priority_queue.hpp>
#include <boost/serialization/vector.hpp>
#include <queue>
#include "audio_core/audio_types.h"
#include "audio_core/codec.h"
Expand Down Expand Up @@ -89,24 +85,6 @@ class Source final {
bool from_queue;
u32 play_position; // = 0;
bool has_played; // = false;

private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& physical_address;
ar& length;
ar& adpcm_ps;
ar& adpcm_yn;
ar& adpcm_dirty;
ar& is_looping;
ar& buffer_id;
ar& mono_or_stereo;
ar& format;
ar& from_queue;
ar& play_position;
ar& has_played;
}
friend class boost::serialization::access;
};

struct BufferOrder {
Expand Down Expand Up @@ -159,27 +137,6 @@ class Source final {
// Filter state

SourceFilters filters = {};

private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& enabled;
ar& sync_count;
ar& gain;
ar& input_queue;
ar& mono_or_stereo;
ar& format;
ar& current_sample_number;
ar& current_buffer_physical_address;
ar& current_buffer;
ar& buffer_update;
ar& current_buffer_id;
ar& adpcm_coeffs;
ar& rate_multiplier;
ar& interpolation_mode;
}
friend class boost::serialization::access;

} state;

// Internal functions
Expand All @@ -193,12 +150,6 @@ class Source final {
bool DequeueBuffer();
/// INTERNAL: Generates a SourceStatus::Status based on our internal state.
SourceStatus::Status GetCurrentStatus();

template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& state;
}
friend class boost::serialization::access;
};

} // namespace AudioCore::HLE
4 changes: 2 additions & 2 deletions src/citra_qt/configuration/configure_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,8 @@ void ConfigureSystem::DownloadFromNUS() {
&QProgressDialog::setValue);

auto failed = false;
const auto download_title = [&future_watcher, &failed](const u64& title_id) {
if (Service::AM::InstallFromNus(title_id) != Service::AM::InstallStatus::Success) {
const auto download_title = [&future_watcher, &failed, this](const u64& title_id) {
if (Service::AM::InstallFromNus(system, title_id) != Service::AM::InstallStatus::Success) {
failed = true;
future_watcher.cancel();
}
Expand Down
46 changes: 1 addition & 45 deletions src/citra_qt/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include <clocale>
#include <memory>
#include <thread>
#include <QFileDialog>
#include <QFutureWatcher>
#include <QLabel>
Expand Down Expand Up @@ -81,7 +80,6 @@
#endif
#include "common/settings.h"
#include "core/core.h"
#include "core/dumping/backend.h"
#include "core/file_sys/archive_extsavedata.h"
#include "core/file_sys/archive_source_sd_savedata.h"
#include "core/frontend/applets/default_applets.h"
Expand All @@ -90,7 +88,6 @@
#include "core/hle/service/nfc/nfc.h"
#include "core/loader/loader.h"
#include "core/movie.h"
#include "core/savestate.h"
#include "core/system_titles.h"
#include "input_common/main.h"
#include "network/network_settings.h"
Expand Down Expand Up @@ -581,7 +578,7 @@ void GMainWindow::InitializeRecentFileMenuActions() {
}

void GMainWindow::InitializeSaveStateMenuActions() {
for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) {
for (u32 i = 0; i < SaveStateSlotCount; ++i) {
actions_load_state[i] = new QAction(this);
actions_load_state[i]->setData(i + 1);
connect(actions_load_state[i], &QAction::triggered, this, &GMainWindow::OnLoadState);
Expand Down Expand Up @@ -1523,47 +1520,6 @@ void GMainWindow::UpdateSaveStates() {
if (system.GetAppLoader().ReadProgramId(title_id) != Loader::ResultStatus::Success) {
return;
}
auto savestates = Core::ListSaveStates(title_id, movie.GetCurrentMovieID());
for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) {
actions_load_state[i]->setEnabled(false);
actions_load_state[i]->setText(tr("Slot %1").arg(i + 1));
actions_save_state[i]->setText(tr("Slot %1").arg(i + 1));
}
for (const auto& savestate : savestates) {
const bool display_name =
savestate.status == Core::SaveStateInfo::ValidationStatus::RevisionDismatch &&
!savestate.build_name.empty();
const auto text =
tr("Slot %1 - %2 %3")
.arg(savestate.slot)
.arg(QDateTime::fromSecsSinceEpoch(savestate.time)
.toString(QStringLiteral("yyyy-MM-dd hh:mm:ss")))
.arg(display_name ? QString::fromStdString(savestate.build_name) : QLatin1String())
.trimmed();

actions_load_state[savestate.slot - 1]->setEnabled(true);
actions_load_state[savestate.slot - 1]->setText(text);
actions_save_state[savestate.slot - 1]->setText(text);

ui->action_Load_from_Newest_Slot->setEnabled(true);

if (savestate.time > newest_slot_time) {
newest_slot = savestate.slot;
newest_slot_time = savestate.time;
}
if (savestate.time < oldest_slot_time) {
oldest_slot = savestate.slot;
oldest_slot_time = savestate.time;
}
}
for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) {
if (!actions_load_state[i]->isEnabled()) {
// Prefer empty slot
oldest_slot = i + 1;
oldest_slot_time = 0;
break;
}
}
}

void GMainWindow::OnGameListLoadFile(QString game_path) {
Expand Down
6 changes: 3 additions & 3 deletions src/citra_qt/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "citra_qt/compatibility_list.h"
#include "citra_qt/hotkeys.h"
#include "core/core.h"
#include "core/savestate.h"

#ifdef __unix__
#include <QDBusObjectPath>
Expand Down Expand Up @@ -367,8 +366,9 @@ private slots:
bool defer_update_prompt = false;

QAction* actions_recent_files[max_recent_files_item];
std::array<QAction*, Core::SaveStateSlotCount> actions_load_state;
std::array<QAction*, Core::SaveStateSlotCount> actions_save_state;
static constexpr size_t SaveStateSlotCount = 8;
std::array<QAction*, SaveStateSlotCount> actions_load_state;
std::array<QAction*, SaveStateSlotCount> actions_save_state;

u32 oldest_slot;
u64 oldest_slot_time;
Expand Down
Loading