aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/service/ns
diff options
context:
space:
mode:
authorMaufeat <sahyno1996@gmail.com>2026-01-17 01:48:15 +0100
committercrueter <crueter@eden-emu.dev>2026-01-17 01:48:15 +0100
commitae501e256ea462268dbae8109ad07ef457c4fd8e (patch)
treeb36691663a10be26462d68f562ad51b8c697ee7b /src/core/hle/service/ns
parentb7417f68ce10145e5eb282110e7d50f46ec8047b (diff)
[bcat/news/web/am] Implement news applet, proper TLV return, external web browser URL and qlaunch app sorting (#3308)
This pulls eden releases changelog & text from our github releases. We don't store the msgpack file but rather generate them in-memory for the News Applet. Uses cache folder. Files generated are: - cache/news/github_releases.json - cache/news/eden_logo.jpg - cache/news/news_read Additional changes: - Proper TLV returning for online web applet, to open external URL - Add applet type `LHub` to properly close, as it also uses TLV return - qlaunch app sorting, adds another cached .json to track last launched app timestamps and sort them accordingly Co-authored-by: crueter <crueter@eden-emu.dev> Co-authored-by: DraVee <dravee@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3308 Reviewed-by: MaranBr <maranbr@eden-emu.dev> Reviewed-by: DraVee <dravee@eden-emu.dev> Reviewed-by: Lizzie <lizzie@eden-emu.dev> Co-authored-by: Maufeat <sahyno1996@gmail.com> Co-committed-by: Maufeat <sahyno1996@gmail.com>
Diffstat (limited to 'src/core/hle/service/ns')
-rw-r--r--src/core/hle/service/ns/application_manager_interface.cpp53
-rw-r--r--src/core/hle/service/ns/ns_types.h9
2 files changed, 37 insertions, 25 deletions
diff --git a/src/core/hle/service/ns/application_manager_interface.cpp b/src/core/hle/service/ns/application_manager_interface.cpp
index 77481a0d98..f989bdc0a8 100644
--- a/src/core/hle/service/ns/application_manager_interface.cpp
+++ b/src/core/hle/service/ns/application_manager_interface.cpp
@@ -16,6 +16,10 @@
#include "core/hle/service/ns/read_only_application_control_data_interface.h"
#include "core/file_sys/patch_manager.h"
#include "frontend_common/firmware_manager.h"
+#include "core/launch_timestamp_cache.h"
+
+#include <algorithm>
+#include <vector>
namespace Service::NS {
@@ -560,33 +564,42 @@ Result IApplicationManagerInterface::ListApplicationRecord(
s32 offset) {
const auto limit = out_records.size();
- LOG_WARNING(Service_NS, "(STUBBED) called");
+ LOG_DEBUG(Service_NS, "called");
const auto& cache = system.GetContentProviderUnion();
const auto installed_games = cache.ListEntriesFilterOrigin(
std::nullopt, FileSys::TitleType::Application, FileSys::ContentRecordType::Program);
- size_t i = 0;
- u8 ii = 24;
+ std::vector<ApplicationRecord> records;
+ records.reserve(installed_games.size());
for (const auto& [slot, game] : installed_games) {
- if (i >= limit) {
- break;
- }
- if (game.title_id == 0 || game.title_id < 0x0100000000001FFFull) {
- continue;
- }
- if (offset > 0) {
- offset--;
- continue;
- }
+ if (game.title_id == 0 || game.title_id < 0x0100000000001FFFull) {
+ continue;
+ }
+ if ((game.title_id & 0xFFF) != 0) {
+ continue; // skip sub-programs (e.g., 001)
+ }
+
+ ApplicationRecord record{};
+ record.application_id = game.title_id;
+ record.last_event = ApplicationEvent::Installed;
+ record.attributes = 0;
+ record.last_updated = Core::LaunchTimestampCache::GetLaunchTimestamp(game.title_id);
+
+ records.push_back(record);
+ }
+
+ std::sort(records.begin(), records.end(), [](const ApplicationRecord& lhs, const ApplicationRecord& rhs) {
+ if (lhs.last_updated == rhs.last_updated) {
+ return lhs.application_id < rhs.application_id;
+ }
+ return lhs.last_updated > rhs.last_updated;
+ });
- ApplicationRecord record{};
- record.application_id = game.title_id;
- record.type = ApplicationRecordType::Installed;
- record.unknown = 0; // 2 = needs update
- record.unknown2 = ii++;
-
- out_records[i++] = record;
+ size_t i = 0;
+ const size_t start = static_cast<size_t>(std::max(0, offset));
+ for (size_t idx = start; idx < records.size() && i < limit; ++idx) {
+ out_records[i++] = records[idx];
}
*out_count = static_cast<s32>(i);
diff --git a/src/core/hle/service/ns/ns_types.h b/src/core/hle/service/ns/ns_types.h
index 247f7063af..c581e8d6c3 100644
--- a/src/core/hle/service/ns/ns_types.h
+++ b/src/core/hle/service/ns/ns_types.h
@@ -12,7 +12,7 @@
namespace Service::NS {
-enum class ApplicationRecordType : u8 {
+enum class ApplicationEvent : u8 {
Installing = 2,
Installed = 3,
GameCardNotInserted = 5,
@@ -34,11 +34,10 @@ enum class BackgroundNetworkUpdateState : u8 {
struct ApplicationRecord {
u64 application_id;
- ApplicationRecordType type;
- u8 unknown;
+ ApplicationEvent last_event;
+ u8 attributes;
INSERT_PADDING_BYTES_NOINIT(0x6);
- u8 unknown2;
- INSERT_PADDING_BYTES_NOINIT(0x7);
+ s64 last_updated;
};
static_assert(sizeof(ApplicationRecord) == 0x18, "ApplicationRecord has incorrect size.");