Skip to content

Commit f34be49

Browse files
author
N3xoX1
committed
OS: Implement IAddOnContentManager::ListAddOnContent and IApplicationFunctions::GetDesiredLanguage
1 parent 20515af commit f34be49

4 files changed

Lines changed: 91 additions & 3 deletions

File tree

src/nxemu-module-spec/base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
enum
1818
{
19-
MODULE_LOADER_SPECS_VERSION = 0x0105,
19+
MODULE_LOADER_SPECS_VERSION = 0x0106,
2020
MODULE_VIDEO_SPECS_VERSION = 0x0102,
2121
MODULE_CPU_SPECS_VERSION = 0x0102,
2222
MODULE_OPERATING_SYSTEM_SPECS_VERSION = 0x0104,

src/nxemu-module-spec/system_loader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ __interface IRomFsController
131131

132132
__interface IFileSysNACP
133133
{
134+
uint32_t GetSupportedLanguages() const = 0;
134135
uint32_t GetParentalControlFlag() const = 0;
135136
bool GetRatingAge(uint8_t * buffer, uint32_t bufferSize) const = 0;
136137
void Release() = 0;

src/nxemu-os/core/hle/service/am/service/application_functions.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "yuzu_common/settings.h"
55
#include "yuzu_common/uuid.h"
6+
#include "core/file_sys/filesystem_interfaces.h"
67
#include "core/hle/kernel/k_transfer_memory.h"
78
#include "core/hle/service/am/am_results.h"
89
#include "core/hle/service/am/applet.h"
@@ -13,6 +14,15 @@
1314
#include "core/hle/service/ns/application_manager_interface.h"
1415
#include "core/hle/service/ns/service_getter_interface.h"
1516
#include "core/hle/service/sm/sm.h"
17+
#include <nxemu-module-spec/system_loader.h>
18+
19+
namespace FileSys {
20+
21+
constexpr u64 GetUpdateTitleID(u64 base_title_id) {
22+
return base_title_id | 0x800;
23+
}
24+
25+
}
1626

1727
namespace Service::AM {
1828

@@ -126,7 +136,34 @@ Result IApplicationFunctions::GetDesiredLanguage(Out<u64> out_language_code) {
126136
// TODO(bunnei): This should be configurable
127137
LOG_DEBUG(Service_AM, "called");
128138

129-
UNIMPLEMENTED();
139+
// Get supported languages from NACP, if possible
140+
// Default to 0 (all languages supported)
141+
u32 supported_languages = 0;
142+
143+
ISystemloader & loader = system.GetSystemloader();
144+
IFileSysNACPPtr metadata(loader.GetPMControlMetadata(m_applet->program_id));
145+
if (!metadata)
146+
{
147+
metadata = loader.GetPMControlMetadata(FileSys::GetUpdateTitleID(m_applet->program_id));
148+
}
149+
150+
if (metadata) {
151+
supported_languages = metadata->GetSupportedLanguages();
152+
}
153+
154+
// Call IApplicationManagerInterface implementation.
155+
auto& service_manager = system.ServiceManager();
156+
auto ns_am2 = service_manager.GetService<NS::IServiceGetterInterface>("ns:am2");
157+
158+
std::shared_ptr<NS::IApplicationManagerInterface> app_man;
159+
R_TRY(ns_am2->GetApplicationManagerInterface(&app_man));
160+
161+
// Get desired application language
162+
NS::ApplicationLanguage desired_language{};
163+
R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages));
164+
165+
// Convert to settings language code.
166+
R_TRY(app_man->ConvertApplicationLanguageToLanguageCode(out_language_code, desired_language));
130167

131168
LOG_DEBUG(Service_AM, "got desired_language={:016X}", *out_language_code);
132169
R_SUCCEED();

src/nxemu-os/core/hle/service/aoc/addon_content_manager.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,32 @@
1818

1919
#include <nxemu-module-spec/system_loader.h>
2020

21+
namespace FileSys {
22+
23+
constexpr u64 AOC_TITLE_ID_MASK = 0x7FF;
24+
constexpr u64 BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
25+
26+
/**
27+
* Gets the base title ID from a given title ID.
28+
*
29+
* @param title_id The title ID.
30+
* @returns The base title ID.
31+
*/
32+
[[nodiscard]] constexpr u64 GetBaseTitleID(u64 title_id) {
33+
return title_id & BASE_TITLE_ID_MASK;
34+
}
35+
36+
/**
37+
* Gets the AOC (Add-On Content) ID from a given AOC title ID.
38+
*
39+
* @param aoc_title_id The AOC title ID.
40+
* @returns The AOC ID.
41+
*/
42+
[[nodiscard]] constexpr u64 GetAOCID(u64 aoc_title_id) {
43+
return aoc_title_id & AOC_TITLE_ID_MASK;
44+
}
45+
}
46+
2147
namespace Service::AOC {
2248

2349
static bool CheckAOCTitleIDMatchesBase(u64 title_id, u64 base) {
@@ -110,7 +136,31 @@ Result IAddOnContentManager::CountAddOnContent(Out<u32> out_count, ClientProcess
110136
Result IAddOnContentManager::ListAddOnContent(Out<u32> out_count,
111137
OutBuffer<BufferAttr_HipcMapAlias> out_addons,
112138
u32 offset, u32 count, ClientProcessId process_id) {
113-
UNIMPLEMENTED();
139+
LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count,
140+
process_id.pid);
141+
142+
const auto current = FileSys::GetBaseTitleID(system.GetApplicationProcessProgramID());
143+
144+
std::vector<u32> out;
145+
const auto& disabled = Settings::values.disabled_addons[current];
146+
if (std::find(disabled.begin(), disabled.end(), "DLC") == disabled.end()) {
147+
for (u64 content_id : add_on_content) {
148+
if (FileSys::GetBaseTitleID(content_id) != current) {
149+
continue;
150+
}
151+
152+
out.push_back(static_cast<u32>(FileSys::GetAOCID(content_id)));
153+
}
154+
}
155+
156+
// TODO(DarkLordZach): Find the correct error code.
157+
R_UNLESS(out.size() >= offset, ResultUnknown);
158+
159+
*out_count = static_cast<u32>(std::min<size_t>(out.size() - offset, count));
160+
std::rotate(out.begin(), out.begin() + offset, out.end());
161+
162+
std::memcpy(out_addons.data(), out.data(), *out_count * sizeof(u32));
163+
114164
R_SUCCEED();
115165
}
116166

0 commit comments

Comments
 (0)