Skip to content

Commit

Permalink
Open Update and DLC loaders in executeApplication
Browse files Browse the repository at this point in the history
  • Loading branch information
dima-xd committed Aug 12, 2023
1 parent 494ef35 commit 06d70eb
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
21 changes: 20 additions & 1 deletion app/src/main/cpp/emu_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
jstring romUriJstring,
jint romType,
jint romFd,
jintArray dlcFds,
jint updateFd,
jobject settingsInstance,
jstring publicAppFilesPathJstring,
jstring privateAppFilesPathJstring,
Expand All @@ -85,6 +87,12 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(

auto jvmManager{std::make_shared<skyline::JvmManager>(env, instance)};

jsize dlcArrSize = dlcFds != nullptr ? env->GetArrayLength(dlcFds) : 0;
std::vector<int> dlcFdsVector(dlcArrSize);

if (dlcArrSize > 0)
env->GetIntArrayRegion(dlcFds, 0, dlcArrSize, &dlcFdsVector[0]);

std::shared_ptr<skyline::Settings> settings{std::make_shared<skyline::AndroidSettings>(env, settingsInstance)};

skyline::JniString publicAppFilesPath(env, publicAppFilesPathJstring);
Expand Down Expand Up @@ -121,7 +129,7 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(

skyline::Logger::DebugNoPrefix("Launching ROM {}", skyline::JniString(env, romUriJstring));

os->Execute(romFd, static_cast<skyline::loader::RomFormat>(romType));
os->Execute(romFd, dlcFdsVector, updateFd, static_cast<skyline::loader::RomFormat>(romType));
} catch (std::exception &e) {
skyline::Logger::ErrorNoPrefix("An uncaught exception has occurred: {}", e.what());
} catch (const skyline::signal::SignalException &e) {
Expand All @@ -138,7 +146,18 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_executeApplication(
skyline::Logger::Write(skyline::Logger::LogLevel::Info, fmt::format("Emulation has ended in {}ms", std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()));

skyline::Logger::EmulationContext.Finalize();

close(romFd);

close(updateFd);

if (dlcArrSize > 0) {
int i = 0;
jint *body = env->GetIntArrayElements(dlcFds, nullptr);
for (i = 0; i < dlcArrSize; i++)
close(body[i]);
}

}

extern "C" JNIEXPORT jboolean Java_emu_skyline_EmulationActivity_stopEmulation(JNIEnv *, jobject, jboolean join) {
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/cpp/skyline/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ namespace skyline {
std::shared_ptr<JvmManager> jvm;
std::shared_ptr<Settings> settings;
std::shared_ptr<loader::Loader> loader;
std::vector<std::shared_ptr<loader::Loader>> dlcLoaders;
std::shared_ptr<loader::Loader> updateLoader;
std::shared_ptr<nce::NCE> nce;
std::shared_ptr<kernel::type::KProcess> process{};
static thread_local inline std::shared_ptr<kernel::type::KThread> thread{}; //!< The KThread of the thread which accesses this object
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/cpp/skyline/loader/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include <linux/elf.h>
#include <vfs/nacp.h>
#include <vfs/cnmt.h>
#include <vfs/nca.h>
#include <common/signal.h>
#include "executable.h"

Expand Down Expand Up @@ -32,6 +34,9 @@ namespace skyline::loader {
MissingTitleKey,
MissingTitleKek,
MissingKeyArea,

ErrorSparseNCA,
ErrorCompressedNCA,
};

/**
Expand Down Expand Up @@ -85,6 +90,10 @@ namespace skyline::loader {
ExecutableLoadInfo LoadExecutable(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state, Executable &executable, size_t offset = 0, const std::string &name = {}, bool dynamicallyLinked = false);

std::optional<vfs::NACP> nacp;
std::optional<vfs::CNMT> cnmt;
std::optional<vfs::NCA> programNca; //!< The main program NCA within the NSP
std::optional<vfs::NCA> controlNca; //!< The main control NCA within the NSP
std::optional<vfs::NCA> publicNca;
std::shared_ptr<vfs::Backing> romFs;

virtual ~Loader() = default;
Expand Down
14 changes: 11 additions & 3 deletions app/src/main/cpp/skyline/loader/nsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vfs/ticket.h>
#include "nca.h"
#include "nsp.h"
#include "vfs/patch_manager.h"

namespace skyline::loader {
static void ExtractTickets(const std::shared_ptr<vfs::PartitionFileSystem>& dir, const std::shared_ptr<crypto::KeyStore> &keyStore) {
Expand Down Expand Up @@ -33,12 +34,14 @@ namespace skyline::loader {
try {
auto nca{vfs::NCA(nsp->OpenFile(entry.name), keyStore)};

if (nca.contentType == vfs::NcaContentType::Program && nca.romFs != nullptr && nca.exeFs != nullptr)
if (nca.contentType == vfs::NCAContentType::Program && nca.romFs != nullptr && nca.exeFs != nullptr)
programNca = std::move(nca);
else if (nca.contentType == vfs::NcaContentType::Control && nca.romFs != nullptr)
else if (nca.contentType == vfs::NCAContentType::Control && nca.romFs != nullptr)
controlNca = std::move(nca);
else if (nca.contentType == vfs::NcaContentType::Meta)
else if (nca.contentType == vfs::NCAContentType::Meta)
metaNca = std::move(nca);
else if (nca.contentType == vfs::NCAContentType::PublicData)
publicNca = std::move(nca);
} catch (const loader_exception &e) {
throw loader_exception(e.error);
} catch (const std::exception &e) {
Expand All @@ -59,6 +62,11 @@ namespace skyline::loader {
}

void *NspLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> &process, const DeviceState &state) {
if (state.updateLoader) {
auto patchManager{std::make_shared<vfs::PatchManager>()};
programNca->exeFs = patchManager->PatchExeFS(state, programNca->exeFs);
}

process->npdm = vfs::NPDM(programNca->exeFs->OpenFile("main.npdm"));
return NcaLoader::LoadExeFs(this, programNca->exeFs, process, state);
}
Expand Down

0 comments on commit 06d70eb

Please sign in to comment.