mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-04-08 10:21:29 -06:00
core: Fix memory mode handling and n3ds exclusive app detection (#1560)
This commit is contained in:
parent
43e044ad9a
commit
4ac18f5e18
@ -222,7 +222,7 @@ jboolean Java_org_citra_citra_1emu_model_GameInfo_getIsVisibleSystemTitle(JNIEnv
|
||||
return false;
|
||||
}
|
||||
|
||||
return smdh->flags & Loader::SMDH::Flags::Visible;
|
||||
return smdh->flags.visible;
|
||||
}
|
||||
|
||||
jstring Java_org_citra_citra_1emu_model_GameInfo_getFileType(JNIEnv* env, jobject obj) {
|
||||
|
||||
@ -92,7 +92,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
||||
if (Loader::IsValidSMDH(smdh)) {
|
||||
if (system_title) {
|
||||
auto smdh_struct = reinterpret_cast<Loader::SMDH*>(smdh.data());
|
||||
if (!(smdh_struct->flags & Loader::SMDH::Flags::Visible)) {
|
||||
if (!smdh_struct->flags.visible) {
|
||||
// Skip system titles without the visible flag.
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -362,8 +362,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
|
||||
ASSERT(n3ds_hw_caps.first);
|
||||
app_n3ds_hw_capabilities = n3ds_hw_caps.first.value();
|
||||
|
||||
if (!Settings::values.is_new_3ds.GetValue() &&
|
||||
app_n3ds_hw_capabilities.memory_mode != Kernel::New3dsMemoryMode::Legacy) {
|
||||
if (!Settings::values.is_new_3ds.GetValue() && app_loader->IsN3DSExclusive()) {
|
||||
return ResultStatus::ErrorN3DSApplication;
|
||||
}
|
||||
|
||||
@ -374,14 +373,10 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
|
||||
// proper memory mode.
|
||||
if (used_default_mem_mode) {
|
||||
|
||||
// If we are on the Old 3DS prod mode, the application is not a New 3DS application and
|
||||
// the application memory mode does not match, we need to adjust it. We do not need
|
||||
// adjustment if we are on the New 3DS prod mode, as that one overrides all the Old 3DS
|
||||
// memory modes.
|
||||
if (system_mem_mode == Kernel::MemoryMode::Prod &&
|
||||
app_n3ds_hw_capabilities.memory_mode == Kernel::New3dsMemoryMode::Legacy &&
|
||||
app_mem_mode != system_mem_mode) {
|
||||
|
||||
// If we are on the Old 3DS prod mode and the application memory mode does not match, we
|
||||
// need to adjust it. We do not need adjustment if we are on the New 3DS prod mode, as that
|
||||
// one overrides all the Old 3DS memory modes.
|
||||
if (system_mem_mode == Kernel::MemoryMode::Prod && app_mem_mode != system_mem_mode) {
|
||||
system_mem_mode = app_mem_mode;
|
||||
}
|
||||
|
||||
@ -389,7 +384,6 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
|
||||
// memory mode (only CTRAging is known to do this), adjust the memory mode.
|
||||
else if (system_mem_mode == Kernel::MemoryMode::NewProd &&
|
||||
app_n3ds_hw_capabilities.memory_mode == Kernel::New3dsMemoryMode::NewDev1) {
|
||||
|
||||
system_mem_mode = Kernel::MemoryMode::NewDev1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#include "common/archives.h"
|
||||
#include "common/serialization/atomic.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/config_mem.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
@ -172,7 +173,9 @@ void KernelSystem::ResetThreadIDs() {
|
||||
|
||||
void KernelSystem::UpdateCPUAndMemoryState(u64 title_id, MemoryMode memory_mode,
|
||||
New3dsHwCapabilities n3ds_hw_cap) {
|
||||
SetRunning804MHz(n3ds_hw_cap.enable_804MHz_cpu);
|
||||
if (Settings::values.is_new_3ds) {
|
||||
SetRunning804MHz(n3ds_hw_cap.enable_804MHz_cpu);
|
||||
}
|
||||
|
||||
u32 tid_high = static_cast<u32>(title_id >> 32);
|
||||
|
||||
|
||||
@ -134,6 +134,16 @@ Apploader_Artic::LoadNew3dsHwCapabilities() {
|
||||
return std::make_pair(std::move(caps), ResultStatus::Success);
|
||||
}
|
||||
|
||||
bool Apploader_Artic::IsN3DSExclusive() {
|
||||
std::vector<u8> smdh_buffer;
|
||||
if (ReadIcon(smdh_buffer) == ResultStatus::Success && IsValidSMDH(smdh_buffer)) {
|
||||
SMDH* smdh = reinterpret_cast<SMDH*>(smdh_buffer.data());
|
||||
return smdh->flags.n3ds_exclusive != 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ResultStatus Apploader_Artic::LoadExec(std::shared_ptr<Kernel::Process>& process) {
|
||||
|
||||
if (!is_loaded)
|
||||
|
||||
@ -56,6 +56,8 @@ public:
|
||||
std::pair<std::optional<Kernel::New3dsHwCapabilities>, ResultStatus> LoadNew3dsHwCapabilities()
|
||||
override;
|
||||
|
||||
bool IsN3DSExclusive() override;
|
||||
|
||||
ResultStatus IsExecutable(bool& out_executable) override;
|
||||
|
||||
ResultStatus ReadCode(std::vector<u8>& buffer) override;
|
||||
|
||||
@ -163,6 +163,10 @@ public:
|
||||
ResultStatus::Success);
|
||||
}
|
||||
|
||||
virtual bool IsN3DSExclusive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this application is executable.
|
||||
* @param out_executable Reference to store the executable flag into.
|
||||
|
||||
@ -125,6 +125,23 @@ AppLoader_NCCH::LoadNew3dsHwCapabilities() {
|
||||
return std::make_pair(std::move(caps), ResultStatus::Success);
|
||||
}
|
||||
|
||||
bool AppLoader_NCCH::IsN3DSExclusive() {
|
||||
if (!is_loaded) {
|
||||
ResultStatus res = base_ncch.Load();
|
||||
if (res != ResultStatus::Success) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<u8> smdh_buffer;
|
||||
if (ReadIcon(smdh_buffer) == ResultStatus::Success && IsValidSMDH(smdh_buffer)) {
|
||||
SMDH* smdh = reinterpret_cast<SMDH*>(smdh_buffer.data());
|
||||
return smdh->flags.n3ds_exclusive != 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ResultStatus AppLoader_NCCH::LoadExec(std::shared_ptr<Kernel::Process>& process) {
|
||||
using Kernel::CodeSet;
|
||||
|
||||
|
||||
@ -50,6 +50,8 @@ public:
|
||||
std::pair<std::optional<Kernel::New3dsHwCapabilities>, ResultStatus> LoadNew3dsHwCapabilities()
|
||||
override;
|
||||
|
||||
bool IsN3DSExclusive() override;
|
||||
|
||||
ResultStatus IsExecutable(bool& out_executable) override;
|
||||
|
||||
ResultStatus ReadCode(std::vector<u8>& buffer) override;
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <array>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
@ -37,7 +38,23 @@ struct SMDH {
|
||||
u32_le region_lockout;
|
||||
u32_le match_maker_id;
|
||||
u64_le match_maker_bit_id;
|
||||
u32_le flags;
|
||||
union {
|
||||
u32_le raw;
|
||||
|
||||
BitField<0, 1, u32> visible;
|
||||
BitField<1, 1, u32> autoboot;
|
||||
BitField<2, 1, u32> allow_3D;
|
||||
BitField<3, 1, u32> require_eula;
|
||||
BitField<4, 1, u32> autosave;
|
||||
BitField<5, 1, u32> extended_banner;
|
||||
BitField<6, 1, u32> rating_required;
|
||||
BitField<7, 1, u32> uses_savedata;
|
||||
BitField<8, 1, u32> record_usage;
|
||||
BitField<10, 1, u32> disable_save_backup;
|
||||
BitField<12, 1, u32> n3ds_exclusive;
|
||||
BitField<14, 1, u32> parental_restricted;
|
||||
} flags;
|
||||
|
||||
u16_le eula_version;
|
||||
INSERT_PADDING_BYTES(2);
|
||||
float_le banner_animation_frame;
|
||||
@ -73,10 +90,6 @@ struct SMDH {
|
||||
Taiwan = 6,
|
||||
};
|
||||
|
||||
enum Flags {
|
||||
Visible = 1 << 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if SMDH is valid.
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user