diff --git a/Makefile b/Makefile
index 7c80329..c6916a9 100644
--- a/Makefile
+++ b/Makefile
@@ -68,10 +68,10 @@ BUILD_TIMESTAMP := $(strip $(shell date --utc '+%Y-%m-%d %T UTC'))
TARGET := ${APP_TITLE}
BUILD := build
-SOURCES := source source/core source/fatfs source/devoptab
+SOURCES := source source/core source/core/fatfs source/core/devoptab source/tasks source/utils source/views
DATA := data
ICON := romfs/icon/${APP_TITLE}.jpg
-INCLUDES := include include/core include/fatfs include/devoptab
+INCLUDES := include
ROMFS := romfs
BOREALIS_PATH := libs/borealis
diff --git a/code_templates/nxdt_rw_poc.c b/code_templates/nxdt_rw_poc.c
index e4ed89b..c07aaea 100644
--- a/code_templates/nxdt_rw_poc.c
+++ b/code_templates/nxdt_rw_poc.c
@@ -19,16 +19,16 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "gamecard.h"
-#include "title.h"
-#include "cnmt.h"
-#include "program_info.h"
-#include "nacp.h"
-#include "legal_info.h"
-#include "cert.h"
-#include "usb.h"
-#include "nxdt_devoptab.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#define BLOCK_SIZE USB_TRANSFER_BUFFER_SIZE
#define WAIT_TIME_LIMIT 30
diff --git a/include/devoptab/nxdt_devoptab.h b/include/core/devoptab/nxdt_devoptab.h
similarity index 98%
rename from include/devoptab/nxdt_devoptab.h
rename to include/core/devoptab/nxdt_devoptab.h
index 2790ea1..99120a9 100644
--- a/include/devoptab/nxdt_devoptab.h
+++ b/include/core/devoptab/nxdt_devoptab.h
@@ -24,9 +24,9 @@
#ifndef __NXDT_DEVOPTAB_H__
#define __NXDT_DEVOPTAB_H__
-#include "pfs.h"
-#include "hfs.h"
-#include "romfs.h"
+#include "../pfs.h"
+#include "../hfs.h"
+#include "../romfs.h"
#ifdef __cplusplus
extern "C" {
diff --git a/include/devoptab/ro_dev.h b/include/core/devoptab/ro_dev.h
similarity index 100%
rename from include/devoptab/ro_dev.h
rename to include/core/devoptab/ro_dev.h
diff --git a/include/fatfs/diskio.h b/include/core/fatfs/diskio.h
similarity index 100%
rename from include/fatfs/diskio.h
rename to include/core/fatfs/diskio.h
diff --git a/include/fatfs/ff.h b/include/core/fatfs/ff.h
similarity index 100%
rename from include/fatfs/ff.h
rename to include/core/fatfs/ff.h
diff --git a/include/fatfs/ffconf.h b/include/core/fatfs/ffconf.h
similarity index 100%
rename from include/fatfs/ffconf.h
rename to include/core/fatfs/ffconf.h
diff --git a/include/core/hos_version_structs.h b/include/core/hos_version_structs.h
new file mode 100644
index 0000000..ee19b5c
--- /dev/null
+++ b/include/core/hos_version_structs.h
@@ -0,0 +1,99 @@
+/*
+ * hos_version_structs.h
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#ifndef __HOS_VERSION_STRUCTS_H__
+#define __HOS_VERSION_STRUCTS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Used to store version numbers expressed in dot notation: "{major}.{minor}.{micro}-{major_relstep}.{minor_relstep}".
+/// Used by system version fields. 16-bit long relstep values were used by system version fields prior to HOS 3.0.0.
+typedef struct {
+ union {
+ u32 value;
+ struct {
+ union {
+ u16 relstep;
+ struct {
+ u16 minor_relstep : 8;
+ u16 major_relstep : 8;
+ };
+ };
+ u16 micro : 4;
+ u16 minor : 6;
+ u16 major : 6;
+ };
+ };
+} SystemVersion;
+
+NXDT_ASSERT(SystemVersion, 0x4);
+
+/// Used to store version numbers expressed in dot notation: "{release}.{private}".
+/// Used by application version fields.
+typedef struct {
+ union {
+ u32 value;
+ struct {
+ u32 private_ver : 16;
+ u32 release_ver : 16;
+ };
+ };
+} ApplicationVersion;
+
+NXDT_ASSERT(ApplicationVersion, 0x4);
+
+/// Used to store version numbers expressed in dot notation: "{major}.{minor}.{micro}-{relstep}".
+/// Used by SDK version fields.
+typedef struct {
+ union {
+ u32 value;
+ struct {
+ u32 relstep : 8;
+ u32 micro : 8;
+ u32 minor : 8;
+ u32 major : 8;
+ };
+ };
+} SdkAddOnVersion;
+
+NXDT_ASSERT(SdkAddOnVersion, 0x4);
+
+/// Convenient wrapper for all version structs.
+typedef struct {
+ union {
+ u32 value;
+ SystemVersion system_version;
+ ApplicationVersion application_version;
+ SdkAddOnVersion sdk_addon_version;
+ };
+} Version;
+
+NXDT_ASSERT(Version, 0x4);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HOS_VERSION_STRUCTS_H__ */
diff --git a/include/core/nxdt_includes.h b/include/core/nxdt_includes.h
index 49fb21f..b5b0b9c 100644
--- a/include/core/nxdt_includes.h
+++ b/include/core/nxdt_includes.h
@@ -78,68 +78,7 @@
#define LZ4_STATIC_LINKING_ONLY /* Required by LZ4 to enable in-place decompression. */
#include "lz4.h"
-/// Used to store version numbers expressed in dot notation: "{major}.{minor}.{micro}-{major_relstep}.{minor_relstep}".
-/// Used by system version fields. 16-bit long relstep values were used by system version fields prior to HOS 3.0.0.
-typedef struct {
- union {
- u32 value;
- struct {
- union {
- u16 relstep;
- struct {
- u16 minor_relstep : 8;
- u16 major_relstep : 8;
- };
- };
- u16 micro : 4;
- u16 minor : 6;
- u16 major : 6;
- };
- };
-} SystemVersion;
-
-NXDT_ASSERT(SystemVersion, 0x4);
-
-/// Used to store version numbers expressed in dot notation: "{release}.{private}".
-/// Used by application version fields.
-typedef struct {
- union {
- u32 value;
- struct {
- u32 private_ver : 16;
- u32 release_ver : 16;
- };
- };
-} ApplicationVersion;
-
-NXDT_ASSERT(ApplicationVersion, 0x4);
-
-/// Used to store version numbers expressed in dot notation: "{major}.{minor}.{micro}-{relstep}".
-/// Used by SDK version fields.
-typedef struct {
- union {
- u32 value;
- struct {
- u32 relstep : 8;
- u32 micro : 8;
- u32 minor : 8;
- u32 major : 8;
- };
- };
-} SdkAddOnVersion;
-
-NXDT_ASSERT(SdkAddOnVersion, 0x4);
-
-/// Convenient wrapper for all version structs.
-typedef struct {
- union {
- u32 value;
- SystemVersion system_version;
- ApplicationVersion application_version;
- SdkAddOnVersion sdk_addon_version;
- };
-} Version;
-
-NXDT_ASSERT(Version, 0x4);
+/* Horizon OS version structs. */
+#include "hos_version_structs.h"
#endif /* __NXDT_INCLUDES_H__ */
diff --git a/include/core/title.h b/include/core/title.h
index 4efe63d..4faccc2 100644
--- a/include/core/title.h
+++ b/include/core/title.h
@@ -51,6 +51,7 @@ typedef struct {
TitleApplicationMetadata *app_metadata; ///< User application metadata.
Version version; ///< Reflects the title version stored in the inserted gamecard.
char display_version[32]; ///< Reflects the title display version stored in its NACP.
+ u32 dlc_count; ///< Reflects the number of DLCs available for this application in the inserted gamecard.
} TitleGameCardApplicationMetadataEntry;
/// Generated using ncm calls.
diff --git a/include/defines.h b/include/defines.h
index 6301dba..eba6ab1 100644
--- a/include/defines.h
+++ b/include/defines.h
@@ -111,6 +111,7 @@
#define FS_MAX_FILENAME_LENGTH 255
#define SDMC_MAX_FILENAME_LENGTH 128 /* Arbitrarily set, I'm tired of FS sysmodule shenanigans. */
+#define REPEATING_TASK_INTERVAL 250 /* 250 milliseconds. */
#define DATA_TRANSFER_TASK_INTERVAL 100 /* 100 milliseconds. */
#define HTTP_USER_AGENT APP_TITLE "/" APP_VERSION " (Nintendo Switch)"
diff --git a/include/tasks.hpp b/include/tasks.hpp
deleted file mode 100644
index 5ca0b99..0000000
--- a/include/tasks.hpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * tasks.hpp
- *
- * Copyright (c) 2020-2024, DarkMatterCore .
- *
- * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
- *
- * nxdumptool is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * nxdumptool is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#pragma once
-
-#ifndef __TASKS_HPP__
-#define __TASKS_HPP__
-
-#include
-
-#include "core/nxdt_includes.h"
-#include "core/gamecard.h"
-#include "core/title.h"
-#include "core/ums.h"
-#include "core/usb.h"
-#include "download_task.hpp"
-
-#define EVENT_SUBSCRIPTION(event_type, event_name) \
- ALWAYS_INLINE event_type::Subscription RegisterListener(event_type::Callback cb) { return this->event_name.subscribe(cb); } \
- ALWAYS_INLINE void UnregisterListener(event_type::Subscription subscription) { this->event_name.unsubscribe(subscription); }
-
-namespace nxdt::tasks
-{
- /* Used to hold status info data. */
- typedef struct {
- struct tm timeinfo;
- u32 charge_percentage;
- PsmChargerType charger_type;
- bool connected;
- NifmInternetConnectionType connection_type;
- char ip_addr[16];
- } StatusInfoData;
-
- /* Used to hold pointers to application metadata entries. */
- typedef std::vector TitleApplicationMetadataVector;
-
- /* Used to hold information from UMS devices. */
- typedef std::pair UmsDeviceVectorEntry;
- typedef std::vector UmsDeviceVector;
-
- /* Custom event types. */
- typedef brls::Event StatusInfoEvent;
- typedef brls::Event GameCardStatusEvent;
- typedef brls::Event UserTitleEvent;
- typedef brls::Event UmsEvent;
- typedef brls::Event UsbHostEvent;
-
- /* Status info task. */
- /* Its event returns a reference to a StatusInfoData struct. */
- class StatusInfoTask: public brls::RepeatingTask
- {
- private:
- StatusInfoEvent status_info_event;
- StatusInfoData status_info_data{};
-
- protected:
- void run(retro_time_t current_time) override;
-
- public:
- StatusInfoTask();
- ~StatusInfoTask();
-
- bool IsInternetConnectionAvailable(void);
-
- EVENT_SUBSCRIPTION(StatusInfoEvent, status_info_event);
- };
-
- /* Gamecard task. */
- /* Its event returns a GameCardStatus value. */
- class GameCardTask: public brls::RepeatingTask
- {
- private:
- GameCardStatusEvent gc_status_event;
- GameCardStatus cur_gc_status = GameCardStatus_NotInserted;
- GameCardStatus prev_gc_status = GameCardStatus_NotInserted;
- bool first_notification = true;
-
- protected:
- void run(retro_time_t current_time) override;
-
- public:
- GameCardTask();
- ~GameCardTask();
-
- EVENT_SUBSCRIPTION(GameCardStatusEvent, gc_status_event);
- };
-
- /* Title task. */
- /* Its event returns a reference to a TitleApplicationMetadataVector with metadata for user titles (system titles don't change at runtime). */
- class TitleTask: public brls::RepeatingTask
- {
- private:
- UserTitleEvent user_title_event;
-
- TitleApplicationMetadataVector system_metadata{};
- TitleApplicationMetadataVector user_metadata{};
-
- void PopulateApplicationMetadataVector(bool is_system);
-
- protected:
- void run(retro_time_t current_time) override;
-
- public:
- TitleTask();
- ~TitleTask();
-
- /* Intentionally left here to let views retrieve title metadata on-demand. */
- const TitleApplicationMetadataVector& GetApplicationMetadata(bool is_system);
-
- EVENT_SUBSCRIPTION(UserTitleEvent, user_title_event);
- };
-
- /* USB Mass Storage task. */
- /* Its event returns a reference to a UmsDeviceVector. */
- class UmsTask: public brls::RepeatingTask
- {
- private:
- UmsEvent ums_event;
-
- UsbHsFsDevice *ums_devices = nullptr;
- u32 ums_devices_count = 0;
-
- UmsDeviceVector ums_devices_vector{};
-
- void PopulateUmsDeviceVector(void);
-
- protected:
- void run(retro_time_t current_time) override;
-
- public:
- UmsTask();
- ~UmsTask();
-
- /* Intentionally left here to let views retrieve UMS device info on-demand. */
- const UmsDeviceVector& GetUmsDevices(void);
-
- EVENT_SUBSCRIPTION(UmsEvent, ums_event);
- };
-
- /* USB host device connection task. */
- class UsbHostTask: public brls::RepeatingTask
- {
- private:
- UsbHostEvent usb_host_event;
- UsbHostSpeed cur_usb_host_speed = UsbHostSpeed_None;
- UsbHostSpeed prev_usb_host_speed = UsbHostSpeed_None;
-
- protected:
- void run(retro_time_t current_time) override;
-
- public:
- UsbHostTask();
- ~UsbHostTask();
-
- /* Intentionally left here to let views retrieve USB host connection speed on-demand. */
- const UsbHostSpeed& GetUsbHostSpeed(void);
-
- EVENT_SUBSCRIPTION(UsbHostEvent, usb_host_event);
- };
-}
-
-#undef EVENT_SUBSCRIPTION
-
-#endif /* __TASKS_HPP__ */
diff --git a/include/async_task.hpp b/include/tasks/async_task.hpp
similarity index 100%
rename from include/async_task.hpp
rename to include/tasks/async_task.hpp
diff --git a/include/data_transfer_task.hpp b/include/tasks/data_transfer_task.hpp
similarity index 99%
rename from include/data_transfer_task.hpp
rename to include/tasks/data_transfer_task.hpp
index 13c0c35..2fe9486 100644
--- a/include/data_transfer_task.hpp
+++ b/include/tasks/data_transfer_task.hpp
@@ -26,7 +26,7 @@
#include
-#include "core/nxdt_utils.h"
+#include "../core/nxdt_utils.h"
#include "async_task.hpp"
namespace nxdt::tasks
diff --git a/include/tasks/download_data_task.hpp b/include/tasks/download_data_task.hpp
new file mode 100644
index 0000000..7d44566
--- /dev/null
+++ b/include/tasks/download_data_task.hpp
@@ -0,0 +1,60 @@
+/*
+ * download_data_task.hpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#ifndef __DOWNLOAD_DATA_TASK_HPP__
+#define __DOWNLOAD_DATA_TASK_HPP__
+
+#include "download_task.hpp"
+
+namespace nxdt::tasks
+{
+ /* Used to hold a buffer + size pair with downloaded data. */
+ typedef std::pair DownloadDataResult;
+
+ /* Asynchronous task used to store downloaded data into a dynamically allocated buffer using a URL. */
+ /* The buffer returned by std::pair::first() must be manually freed by the caller using free(). */
+ class DownloadDataTask: public DownloadTask
+ {
+ protected:
+ /* Set class as non-copyable and non-moveable. */
+ NON_COPYABLE(DownloadDataTask);
+ NON_MOVEABLE(DownloadDataTask);
+
+ /* Runs in the background thread. */
+ DownloadDataResult DoInBackground(const std::string& url, const bool& force_https) override final
+ {
+ char *buf = nullptr;
+ size_t buf_size = 0;
+
+ /* If the process fails or if it's cancelled, httpDownloadData() will take care of freeing up the allocated memory and returning NULL. */
+ buf = httpDownloadData(&buf_size, url.c_str(), force_https, DownloadDataTask::HttpProgressCallback, this);
+
+ return std::make_pair(buf, buf_size);
+ }
+
+ public:
+ DownloadDataTask() = default;
+ };
+}
+
+#endif /* __DOWNLOAD_DATA_TASK_HPP__ */
diff --git a/include/tasks/download_file_task.hpp b/include/tasks/download_file_task.hpp
new file mode 100644
index 0000000..463ddb9
--- /dev/null
+++ b/include/tasks/download_file_task.hpp
@@ -0,0 +1,51 @@
+/*
+ * download_file_task.hpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#ifndef __DOWNLOAD_FILE_TASK_HPP__
+#define __DOWNLOAD_FILE_TASK_HPP__
+
+#include "download_task.hpp"
+
+namespace nxdt::tasks
+{
+ /* Asynchronous task used to download a file using an output path and a URL. */
+ class DownloadFileTask: public DownloadTask
+ {
+ protected:
+ /* Set class as non-copyable and non-moveable. */
+ NON_COPYABLE(DownloadFileTask);
+ NON_MOVEABLE(DownloadFileTask);
+
+ /* Runs in the background thread. */
+ bool DoInBackground(const std::string& path, const std::string& url, const bool& force_https) override final
+ {
+ /* If the process fails or if it's cancelled, httpDownloadFile() will take care of closing the incomplete output file and deleting it. */
+ return httpDownloadFile(path.c_str(), url.c_str(), force_https, DownloadFileTask::HttpProgressCallback, this);
+ }
+
+ public:
+ DownloadFileTask() = default;
+ };
+}
+
+#endif /* __DOWNLOAD_FILE_TASK_HPP__ */
diff --git a/include/download_task.hpp b/include/tasks/download_task.hpp
similarity index 55%
rename from include/download_task.hpp
rename to include/tasks/download_task.hpp
index e8e3caa..9446ed0 100644
--- a/include/download_task.hpp
+++ b/include/tasks/download_task.hpp
@@ -28,9 +28,6 @@
namespace nxdt::tasks
{
- /* Used to hold a buffer + size pair with downloaded data. */
- typedef std::pair DownloadDataResult;
-
/* Class template to asynchronously download data on a background thread. */
/* Uses both AsyncTask and DataTransferTask class templates. */
template
@@ -68,50 +65,6 @@ namespace nxdt::tasks
return 0;
}
};
-
- /* Asynchronous task used to download a file using an output path and a URL. */
- class DownloadFileTask: public DownloadTask
- {
- protected:
- /* Set class as non-copyable and non-moveable. */
- NON_COPYABLE(DownloadFileTask);
- NON_MOVEABLE(DownloadFileTask);
-
- /* Runs in the background thread. */
- bool DoInBackground(const std::string& path, const std::string& url, const bool& force_https) override final
- {
- /* If the process fails or if it's cancelled, httpDownloadFile() will take care of closing the incomplete output file and deleting it. */
- return httpDownloadFile(path.c_str(), url.c_str(), force_https, DownloadFileTask::HttpProgressCallback, this);
- }
-
- public:
- DownloadFileTask() = default;
- };
-
- /* Asynchronous task used to store downloaded data into a dynamically allocated buffer using a URL. */
- /* The buffer returned by std::pair::first() must be manually freed by the caller using free(). */
- class DownloadDataTask: public DownloadTask
- {
- protected:
- /* Set class as non-copyable and non-moveable. */
- NON_COPYABLE(DownloadDataTask);
- NON_MOVEABLE(DownloadDataTask);
-
- /* Runs in the background thread. */
- DownloadDataResult DoInBackground(const std::string& url, const bool& force_https) override final
- {
- char *buf = nullptr;
- size_t buf_size = 0;
-
- /* If the process fails or if it's cancelled, httpDownloadData() will take care of freeing up the allocated memory and returning NULL. */
- buf = httpDownloadData(&buf_size, url.c_str(), force_https, DownloadDataTask::HttpProgressCallback, this);
-
- return std::make_pair(buf, buf_size);
- }
-
- public:
- DownloadDataTask() = default;
- };
}
#endif /* __DOWNLOAD_TASK_HPP__ */
diff --git a/include/gamecard_image_dump_task.hpp b/include/tasks/gamecard_image_dump_task.hpp
similarity index 100%
rename from include/gamecard_image_dump_task.hpp
rename to include/tasks/gamecard_image_dump_task.hpp
diff --git a/include/tasks/gamecard_status_task.hpp b/include/tasks/gamecard_status_task.hpp
new file mode 100644
index 0000000..c7ee3c5
--- /dev/null
+++ b/include/tasks/gamecard_status_task.hpp
@@ -0,0 +1,66 @@
+/*
+ * gamecard_status_task.hpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#ifndef __GAMECARD_STATUS_TASK_HPP__
+#define __GAMECARD_STATUS_TASK_HPP__
+
+#include
+
+#include "../core/nxdt_utils.h"
+#include "../core/gamecard.h"
+
+namespace nxdt::tasks
+{
+ /* Custom event type. */
+ typedef brls::Event GameCardStatusEvent;
+
+ /* Gamecard status task. */
+ /* Its event provides a const reference to a GameCardStatus value. */
+ class GameCardStatusTask: public brls::RepeatingTask
+ {
+ private:
+ GameCardStatusEvent gc_status_event;
+ GameCardStatus cur_gc_status = GameCardStatus_NotInserted;
+ GameCardStatus prev_gc_status = GameCardStatus_NotInserted;
+ bool first_notification = true;
+
+ protected:
+ void run(retro_time_t current_time) override;
+
+ public:
+ GameCardStatusTask();
+ ~GameCardStatusTask();
+
+ ALWAYS_INLINE GameCardStatusEvent::Subscription RegisterListener(GameCardStatusEvent::Callback cb)
+ {
+ return this->gc_status_event.subscribe(cb);
+ }
+
+ ALWAYS_INLINE void UnregisterListener(GameCardStatusEvent::Subscription subscription)
+ {
+ this->gc_status_event.unsubscribe(subscription);
+ }
+ };
+}
+
+#endif /* __GAMECARD_STATUS_TASK_HPP__ */
diff --git a/include/tasks/status_info_task.hpp b/include/tasks/status_info_task.hpp
new file mode 100644
index 0000000..0c9ec8e
--- /dev/null
+++ b/include/tasks/status_info_task.hpp
@@ -0,0 +1,75 @@
+/*
+ * status_info_task.hpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#ifndef __STATUS_INFO_TASK_HPP__
+#define __STATUS_INFO_TASK_HPP__
+
+#include
+
+#include "../core/nxdt_utils.h"
+
+namespace nxdt::tasks
+{
+ /* Used to hold status info data. */
+ typedef struct {
+ struct tm timeinfo;
+ u32 charge_percentage;
+ PsmChargerType charger_type;
+ bool connected;
+ NifmInternetConnectionType connection_type;
+ char ip_addr[16];
+ } StatusInfoData;
+
+ /* Custom event type. */
+ typedef brls::Event StatusInfoEvent;
+
+ /* Status info task. */
+ /* Its event provides a const reference to a StatusInfoData struct. */
+ class StatusInfoTask: public brls::RepeatingTask
+ {
+ private:
+ StatusInfoEvent status_info_event;
+ StatusInfoData status_info_data{};
+
+ protected:
+ void run(retro_time_t current_time) override;
+
+ public:
+ StatusInfoTask();
+ ~StatusInfoTask();
+
+ bool IsInternetConnectionAvailable(void);
+
+ ALWAYS_INLINE StatusInfoEvent::Subscription RegisterListener(StatusInfoEvent::Callback cb)
+ {
+ return this->status_info_event.subscribe(cb);
+ }
+
+ ALWAYS_INLINE void UnregisterListener(StatusInfoEvent::Subscription subscription)
+ {
+ this->status_info_event.unsubscribe(subscription);
+ }
+ };
+}
+
+#endif /* __STATUS_INFO_TASK_HPP__ */
diff --git a/include/tasks/title_metadata_task.hpp b/include/tasks/title_metadata_task.hpp
new file mode 100644
index 0000000..2c15cd7
--- /dev/null
+++ b/include/tasks/title_metadata_task.hpp
@@ -0,0 +1,74 @@
+/*
+ * title_metadata_task.hpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#ifndef __TITLE_METADATA_TASK_HPP__
+#define __TITLE_METADATA_TASK_HPP__
+
+#include
+
+#include "../core/nxdt_utils.h"
+#include "../core/title.h"
+
+namespace nxdt::tasks
+{
+ /* Used to hold pointers to application metadata entries. */
+ typedef std::vector TitleApplicationMetadataVector;
+
+ /* Custom event type. */
+ typedef brls::Event UserTitleEvent;
+
+ /* Title metadata task. */
+ /* Its event provides a const reference to a TitleApplicationMetadataVector with metadata for user titles (system titles don't change at runtime). */
+ class TitleMetadataTask: public brls::RepeatingTask
+ {
+ private:
+ UserTitleEvent user_title_event;
+
+ TitleApplicationMetadataVector system_metadata{};
+ TitleApplicationMetadataVector user_metadata{};
+
+ void PopulateApplicationMetadataVector(bool is_system);
+
+ protected:
+ void run(retro_time_t current_time) override;
+
+ public:
+ TitleMetadataTask();
+ ~TitleMetadataTask();
+
+ /* Intentionally left here to let views retrieve title metadata on-demand. */
+ const TitleApplicationMetadataVector& GetApplicationMetadata(bool is_system);
+
+ ALWAYS_INLINE UserTitleEvent::Subscription RegisterListener(UserTitleEvent::Callback cb)
+ {
+ return this->user_title_event.subscribe(cb);
+ }
+
+ ALWAYS_INLINE void UnregisterListener(UserTitleEvent::Subscription subscription)
+ {
+ this->user_title_event.unsubscribe(subscription);
+ }
+ };
+}
+
+#endif /* __TITLE_METADATA_TASK_HPP__ */
diff --git a/include/tasks/ums_task.hpp b/include/tasks/ums_task.hpp
new file mode 100644
index 0000000..d23db5a
--- /dev/null
+++ b/include/tasks/ums_task.hpp
@@ -0,0 +1,77 @@
+/*
+ * ums_task.hpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#ifndef __UMS_TASK_HPP__
+#define __UMS_TASK_HPP__
+
+#include
+
+#include "../core/nxdt_utils.h"
+#include "../core/ums.h"
+
+namespace nxdt::tasks
+{
+ /* Used to hold information from UMS devices. */
+ typedef std::pair UmsDeviceVectorEntry;
+ typedef std::vector UmsDeviceVector;
+
+ /* Custom event type. */
+ typedef brls::Event UmsEvent;
+
+ /* USB Mass Storage task. */
+ /* Its event provides a const reference to a UmsDeviceVector. */
+ class UmsTask: public brls::RepeatingTask
+ {
+ private:
+ UmsEvent ums_event;
+
+ UsbHsFsDevice *ums_devices = nullptr;
+ u32 ums_devices_count = 0;
+
+ UmsDeviceVector ums_devices_vector{};
+
+ void PopulateUmsDeviceVector(void);
+
+ protected:
+ void run(retro_time_t current_time) override;
+
+ public:
+ UmsTask();
+ ~UmsTask();
+
+ /* Intentionally left here to let views retrieve UMS device info on-demand. */
+ const UmsDeviceVector& GetUmsDevices(void);
+
+ ALWAYS_INLINE UmsEvent::Subscription RegisterListener(UmsEvent::Callback cb)
+ {
+ return this->ums_event.subscribe(cb);
+ }
+
+ ALWAYS_INLINE void UnregisterListener(UmsEvent::Subscription subscription)
+ {
+ this->ums_event.unsubscribe(subscription);
+ }
+ };
+}
+
+#endif /* __UMS_TASK_HPP__ */
diff --git a/include/tasks/usb_host_task.hpp b/include/tasks/usb_host_task.hpp
new file mode 100644
index 0000000..b849ad8
--- /dev/null
+++ b/include/tasks/usb_host_task.hpp
@@ -0,0 +1,67 @@
+/*
+ * usb_host_task.hpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#ifndef __USB_HOST_TASK_HPP__
+#define __USB_HOST_TASK_HPP__
+
+#include
+
+#include "../core/nxdt_utils.h"
+#include "../core/usb.h"
+
+namespace nxdt::tasks
+{
+ /* Custom event type. */
+ typedef brls::Event UsbHostEvent;
+
+ /* USB host device connection task. */
+ class UsbHostTask: public brls::RepeatingTask
+ {
+ private:
+ UsbHostEvent usb_host_event;
+ UsbHostSpeed cur_usb_host_speed = UsbHostSpeed_None;
+ UsbHostSpeed prev_usb_host_speed = UsbHostSpeed_None;
+
+ protected:
+ void run(retro_time_t current_time) override;
+
+ public:
+ UsbHostTask();
+ ~UsbHostTask();
+
+ /* Intentionally left here to let views retrieve USB host connection speed on-demand. */
+ const UsbHostSpeed& GetUsbHostSpeed(void);
+
+ ALWAYS_INLINE UsbHostEvent::Subscription RegisterListener(UsbHostEvent::Callback cb)
+ {
+ return this->usb_host_event.subscribe(cb);
+ }
+
+ ALWAYS_INLINE void UnregisterListener(UsbHostEvent::Subscription subscription)
+ {
+ this->usb_host_event.unsubscribe(subscription);
+ }
+ };
+}
+
+#endif /* __USB_HOST_TASK_HPP__ */
diff --git a/include/file_writer.hpp b/include/utils/file_writer.hpp
similarity index 98%
rename from include/file_writer.hpp
rename to include/utils/file_writer.hpp
index 4ffe2fe..39c2ee2 100644
--- a/include/file_writer.hpp
+++ b/include/utils/file_writer.hpp
@@ -27,8 +27,8 @@
#include
#include
-#include "core/nxdt_utils.h"
-#include "core/usb.h"
+#include "../core/nxdt_utils.h"
+#include "../core/usb.h"
namespace nxdt::utils
{
diff --git a/include/is_base_of_template.hpp b/include/utils/is_base_of_template.hpp
similarity index 100%
rename from include/is_base_of_template.hpp
rename to include/utils/is_base_of_template.hpp
diff --git a/include/scope_guard.hpp b/include/utils/scope_guard.hpp
similarity index 98%
rename from include/scope_guard.hpp
rename to include/utils/scope_guard.hpp
index 6babd2e..a7ad6ed 100644
--- a/include/scope_guard.hpp
+++ b/include/utils/scope_guard.hpp
@@ -27,7 +27,7 @@
#ifndef __SCOPE_GUARD_HPP__
#define __SCOPE_GUARD_HPP__
-#include "defines.h"
+#include "../defines.h"
#define SCOPE_GUARD ::nxdt::utils::ScopeGuardOnExit() + [&]() ALWAYS_INLINE_LAMBDA
#define ON_SCOPE_EXIT auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_) = SCOPE_GUARD
diff --git a/include/about_tab.hpp b/include/views/about_tab.hpp
similarity index 99%
rename from include/about_tab.hpp
rename to include/views/about_tab.hpp
index a7e5fbb..d01d78d 100644
--- a/include/about_tab.hpp
+++ b/include/views/about_tab.hpp
@@ -25,6 +25,7 @@
#define __ABOUT_TAB_HPP__
#include
+
#include "focusable_item.hpp"
namespace nxdt::views
diff --git a/include/data_transfer_progress_display.hpp b/include/views/data_transfer_progress_display.hpp
similarity index 97%
rename from include/data_transfer_progress_display.hpp
rename to include/views/data_transfer_progress_display.hpp
index 5e66447..d9f58a9 100644
--- a/include/data_transfer_progress_display.hpp
+++ b/include/views/data_transfer_progress_display.hpp
@@ -24,7 +24,7 @@
#ifndef __DATA_TRANSFER_PROGRESS_DISPLAY_HPP__
#define __DATA_TRANSFER_PROGRESS_DISPLAY_HPP__
-#include "data_transfer_task.hpp"
+#include "../tasks/data_transfer_task.hpp"
namespace nxdt::views
{
diff --git a/include/data_transfer_task_frame.hpp b/include/views/data_transfer_task_frame.hpp
similarity index 99%
rename from include/data_transfer_task_frame.hpp
rename to include/views/data_transfer_task_frame.hpp
index b68f174..5ecf3ab 100644
--- a/include/data_transfer_task_frame.hpp
+++ b/include/views/data_transfer_task_frame.hpp
@@ -24,7 +24,7 @@
#ifndef __DATA_TRANSFER_TASK_FRAME_HPP__
#define __DATA_TRANSFER_TASK_FRAME_HPP__
-#include "is_base_of_template.hpp"
+#include "../utils/is_base_of_template.hpp"
#include "error_frame.hpp"
#include "data_transfer_progress_display.hpp"
diff --git a/include/dump_options_frame.hpp b/include/views/dump_options_frame.hpp
similarity index 100%
rename from include/dump_options_frame.hpp
rename to include/views/dump_options_frame.hpp
diff --git a/include/error_frame.hpp b/include/views/error_frame.hpp
similarity index 100%
rename from include/error_frame.hpp
rename to include/views/error_frame.hpp
diff --git a/include/focusable_item.hpp b/include/views/focusable_item.hpp
similarity index 100%
rename from include/focusable_item.hpp
rename to include/views/focusable_item.hpp
diff --git a/include/gamecard_image_dump_options_frame.hpp b/include/views/gamecard_image_dump_options_frame.hpp
similarity index 100%
rename from include/gamecard_image_dump_options_frame.hpp
rename to include/views/gamecard_image_dump_options_frame.hpp
diff --git a/include/gamecard_image_dump_task_frame.hpp b/include/views/gamecard_image_dump_task_frame.hpp
similarity index 97%
rename from include/gamecard_image_dump_task_frame.hpp
rename to include/views/gamecard_image_dump_task_frame.hpp
index c5b52b7..d48cd78 100644
--- a/include/gamecard_image_dump_task_frame.hpp
+++ b/include/views/gamecard_image_dump_task_frame.hpp
@@ -25,7 +25,7 @@
#define __GAMECARD_IMAGE_DUMP_TASK_FRAME_HPP__
#include "data_transfer_task_frame.hpp"
-#include "gamecard_image_dump_task.hpp"
+#include "../tasks/gamecard_image_dump_task.hpp"
namespace nxdt::views
{
diff --git a/include/gamecard_tab.hpp b/include/views/gamecard_tab.hpp
similarity index 85%
rename from include/gamecard_tab.hpp
rename to include/views/gamecard_tab.hpp
index 3cbf8db..cc7212f 100644
--- a/include/gamecard_tab.hpp
+++ b/include/views/gamecard_tab.hpp
@@ -32,9 +32,9 @@ namespace nxdt::views
{
class GameCardTab: public LayeredErrorFrame
{
- typedef bool (*GameCardSizeFunc)(u64 *out_size);
-
private:
+ typedef bool (*GameCardSizeFunc)(u64 *out_size);
+
RootView *root_view = nullptr;
nxdt::tasks::GameCardStatusEvent::Subscription gc_status_task_sub;
@@ -44,9 +44,18 @@ namespace nxdt::views
std::string raw_filename_id_only = "";
void ProcessGameCardStatus(GameCardStatus gc_status);
- std::string GetFormattedSizeString(GameCardSizeFunc func);
- std::string GetCardIdSetString(FsGameCardIdSet *card_id_set);
+
+
+
void PopulateList(void);
+ void AddApplicationMetadataItems(void);
+ void AddPropertiesTable(void);
+
+ void GenerateRawFilenames(void);
+ std::string GetFormattedSizeString(GameCardSizeFunc func);
+ std::string GetCardIdSetString(const FsGameCardIdSet& card_id_set);
+
+
public:
GameCardTab(RootView *root_view);
diff --git a/include/layered_error_frame.hpp b/include/views/layered_error_frame.hpp
similarity index 100%
rename from include/layered_error_frame.hpp
rename to include/views/layered_error_frame.hpp
diff --git a/include/options_tab.hpp b/include/views/options_tab.hpp
similarity index 97%
rename from include/options_tab.hpp
rename to include/views/options_tab.hpp
index 0ff3a61..71bc228 100644
--- a/include/options_tab.hpp
+++ b/include/views/options_tab.hpp
@@ -26,6 +26,8 @@
#include "root_view.hpp"
#include "data_transfer_progress_display.hpp"
+#include "../tasks/download_file_task.hpp"
+#include "../tasks/download_data_task.hpp"
namespace nxdt::views
{
diff --git a/include/root_view.hpp b/include/views/root_view.hpp
similarity index 87%
rename from include/root_view.hpp
rename to include/views/root_view.hpp
index 2f173fc..6642625 100644
--- a/include/root_view.hpp
+++ b/include/views/root_view.hpp
@@ -24,7 +24,11 @@
#ifndef __ROOT_VIEW_HPP__
#define __ROOT_VIEW_HPP__
-#include "tasks.hpp"
+#include "../tasks/status_info_task.hpp"
+#include "../tasks/gamecard_status_task.hpp"
+#include "../tasks/title_metadata_task.hpp"
+#include "../tasks/ums_task.hpp"
+#include "../tasks/usb_host_task.hpp"
#define EVENT_SUBSCRIPTION(func_name, event_type, task_name) \
ALWAYS_INLINE nxdt::tasks::event_type::Subscription Register##func_name##Listener(nxdt::tasks::event_type::Callback cb) { return this->task_name->RegisterListener(cb); } \
@@ -47,8 +51,8 @@ namespace nxdt::views
brls::Label *cable_icon = nullptr, *usb_host_speed_lbl = nullptr;
nxdt::tasks::StatusInfoTask *status_info_task = nullptr;
- nxdt::tasks::GameCardTask *gc_status_task = nullptr;
- nxdt::tasks::TitleTask *title_task = nullptr;
+ nxdt::tasks::GameCardStatusTask *gc_status_task = nullptr;
+ nxdt::tasks::TitleMetadataTask *title_metadata_task = nullptr;
nxdt::tasks::UmsTask *ums_task = nullptr;
nxdt::tasks::UsbHostTask *usb_host_task = nullptr;
@@ -88,7 +92,7 @@ namespace nxdt::views
ALWAYS_INLINE const nxdt::tasks::TitleApplicationMetadataVector& GetApplicationMetadata(bool is_system)
{
- return this->title_task->GetApplicationMetadata(is_system);
+ return this->title_metadata_task->GetApplicationMetadata(is_system);
}
ALWAYS_INLINE const nxdt::tasks::UmsDeviceVector& GetUmsDevices(void)
@@ -102,8 +106,8 @@ namespace nxdt::views
}
EVENT_SUBSCRIPTION(StatusInfoTask, StatusInfoEvent, status_info_task);
- EVENT_SUBSCRIPTION(GameCardTask, GameCardStatusEvent, gc_status_task);
- EVENT_SUBSCRIPTION(TitleTask, UserTitleEvent, title_task);
+ EVENT_SUBSCRIPTION(GameCardStatusTask, GameCardStatusEvent, gc_status_task);
+ EVENT_SUBSCRIPTION(TitleMetadataTask, UserTitleEvent, title_metadata_task);
EVENT_SUBSCRIPTION(UmsTask, UmsEvent, ums_task);
EVENT_SUBSCRIPTION(UsbHostTask, UsbHostEvent, usb_host_task);
};
diff --git a/include/titles_tab.hpp b/include/views/titles_tab.hpp
similarity index 100%
rename from include/titles_tab.hpp
rename to include/views/titles_tab.hpp
diff --git a/libs/borealis b/libs/borealis
index e5cbe0d..0846ff5 160000
--- a/libs/borealis
+++ b/libs/borealis
@@ -1 +1 @@
-Subproject commit e5cbe0d97c32d1102a6ea253ed68a3a8ecfdc3a9
+Subproject commit 0846ff57b72a1bdd9fc86eee348258c0b52e0ece
diff --git a/source/core/aes.c b/source/core/aes.c
index 10e9a4e..9b13bf9 100644
--- a/source/core/aes.c
+++ b/source/core/aes.c
@@ -19,7 +19,7 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
+#include
void aes128EcbCrypt(void *dst, const void *src, const void *key, bool encrypt)
{
diff --git a/source/core/bfttf.c b/source/core/bfttf.c
index fdf0f95..b9c4e22 100644
--- a/source/core/bfttf.c
+++ b/source/core/bfttf.c
@@ -20,10 +20,10 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "bfttf.h"
-#include "romfs.h"
-#include "title.h"
+#include
+#include
+#include
+#include
/* Type definitions. */
diff --git a/source/core/bktr.c b/source/core/bktr.c
index 3d34c9b..5212941 100644
--- a/source/core/bktr.c
+++ b/source/core/bktr.c
@@ -20,9 +20,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "bktr.h"
-#include "aes.h"
+#include
+#include
+#include
/* Type definitions. */
diff --git a/source/core/cert.c b/source/core/cert.c
index 3c2537a..f057ed1 100644
--- a/source/core/cert.c
+++ b/source/core/cert.c
@@ -19,10 +19,10 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "cert.h"
-#include "save.h"
-#include "gamecard.h"
+#include
+#include
+#include
+#include
#define CERT_SAVEFILE_PATH BIS_SYSTEM_PARTITION_MOUNT_NAME "/save/80000000000000e0"
#define CERT_SAVEFILE_STORAGE_BASE_PATH "/certificate/"
diff --git a/source/core/cnmt.c b/source/core/cnmt.c
index 45301ba..eeac9d5 100644
--- a/source/core/cnmt.c
+++ b/source/core/cnmt.c
@@ -19,9 +19,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "cnmt.h"
-#include "title.h"
+#include
+#include
+#include
/* Helper macros. */
diff --git a/source/core/config.c b/source/core/config.c
index dbc1687..1b9d6c3 100644
--- a/source/core/config.c
+++ b/source/core/config.c
@@ -19,9 +19,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "config.h"
-#include "title.h"
+#include
+#include
+#include
#define CONFIG_VALIDATE_FIELD(type, name, ...) \
if (!strcmp(key, #name)) { \
diff --git a/source/devoptab/hfs_dev.c b/source/core/devoptab/hfs_dev.c
similarity index 99%
rename from source/devoptab/hfs_dev.c
rename to source/core/devoptab/hfs_dev.c
index 71bd0f6..ecc25b1 100644
--- a/source/devoptab/hfs_dev.c
+++ b/source/core/devoptab/hfs_dev.c
@@ -21,9 +21,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nxdt_devoptab.h"
-#include "ro_dev.h"
+#include
+#include
+#include
/* Helper macros. */
diff --git a/source/devoptab/nxdt_devoptab.c b/source/core/devoptab/nxdt_devoptab.c
similarity index 98%
rename from source/devoptab/nxdt_devoptab.c
rename to source/core/devoptab/nxdt_devoptab.c
index 81bc4e9..b11b7cb 100644
--- a/source/devoptab/nxdt_devoptab.c
+++ b/source/core/devoptab/nxdt_devoptab.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nxdt_devoptab.h"
+#include
+#include
#define DEVOPTAB_DEVICE_COUNT 4
diff --git a/source/devoptab/nxdt_romfs_dev.c b/source/core/devoptab/nxdt_romfs_dev.c
similarity index 99%
rename from source/devoptab/nxdt_romfs_dev.c
rename to source/core/devoptab/nxdt_romfs_dev.c
index c5571df..ca298a9 100644
--- a/source/devoptab/nxdt_romfs_dev.c
+++ b/source/core/devoptab/nxdt_romfs_dev.c
@@ -21,9 +21,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nxdt_devoptab.h"
-#include "ro_dev.h"
+#include
+#include
+#include
/* Helper macros. */
diff --git a/source/devoptab/pfs_dev.c b/source/core/devoptab/pfs_dev.c
similarity index 99%
rename from source/devoptab/pfs_dev.c
rename to source/core/devoptab/pfs_dev.c
index 6d5b22d..8e70aa6 100644
--- a/source/devoptab/pfs_dev.c
+++ b/source/core/devoptab/pfs_dev.c
@@ -21,9 +21,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nxdt_devoptab.h"
-#include "ro_dev.h"
+#include
+#include
+#include
/* Helper macros. */
diff --git a/source/devoptab/ro_dev.c b/source/core/devoptab/ro_dev.c
similarity index 97%
rename from source/devoptab/ro_dev.c
rename to source/core/devoptab/ro_dev.c
index 73eb667..6afb560 100644
--- a/source/devoptab/ro_dev.c
+++ b/source/core/devoptab/ro_dev.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nxdt_devoptab.h"
+#include
+#include
ssize_t rodev_write(struct _reent *r, void *fd, const char *ptr, size_t len)
{
diff --git a/source/core/es.c b/source/core/es.c
index ac48485..ddbaa5c 100644
--- a/source/core/es.c
+++ b/source/core/es.c
@@ -20,9 +20,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "es.h"
-#include "service_guard.h"
+#include
+#include
+#include
static Service g_esSrv = {0};
diff --git a/source/fatfs/diskio.c b/source/core/fatfs/diskio.c
similarity index 95%
rename from source/fatfs/diskio.c
rename to source/core/fatfs/diskio.c
index 9e985d4..271635e 100644
--- a/source/fatfs/diskio.c
+++ b/source/core/fatfs/diskio.c
@@ -7,12 +7,10 @@
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
-#include "ff.h" /* Obtains integer types */
-#include "diskio.h" /* Declarations of disk functions */
+#include
-#include
-
-#include "nxdt_utils.h"
+#include /* Obtains integer types */
+#include /* Declarations of disk functions */
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
diff --git a/source/fatfs/ff.c b/source/core/fatfs/ff.c
similarity index 99%
rename from source/fatfs/ff.c
rename to source/core/fatfs/ff.c
index 6709fd1..dc957c6 100644
--- a/source/fatfs/ff.c
+++ b/source/core/fatfs/ff.c
@@ -20,8 +20,8 @@
#include
-#include "ff.h" /* Declarations of FatFs API */
-#include "diskio.h" /* Declarations of device I/O functions */
+#include /* Declarations of FatFs API */
+#include /* Declarations of device I/O functions */
/*--------------------------------------------------------------------------
diff --git a/source/fatfs/ffsystem.c b/source/core/fatfs/ffsystem.c
similarity index 99%
rename from source/fatfs/ffsystem.c
rename to source/core/fatfs/ffsystem.c
index d23f545..fbd7bb0 100644
--- a/source/fatfs/ffsystem.c
+++ b/source/core/fatfs/ffsystem.c
@@ -2,7 +2,7 @@
/* A Sample Code of User Provided OS Dependent Functions for FatFs */
/*------------------------------------------------------------------------*/
-#include "ff.h"
+#include
#if FF_USE_LFN == 3 /* Use dynamic memory allocation */
diff --git a/source/fatfs/ffunicode.c b/source/core/fatfs/ffunicode.c
similarity index 99%
rename from source/fatfs/ffunicode.c
rename to source/core/fatfs/ffunicode.c
index e6bcaca..181c233 100644
--- a/source/fatfs/ffunicode.c
+++ b/source/core/fatfs/ffunicode.c
@@ -23,7 +23,7 @@
*/
-#include "ff.h"
+#include
#if FF_USE_LFN != 0 /* This module will be blanked if in non-LFN configuration */
diff --git a/source/core/fs_ext.c b/source/core/fs_ext.c
index ace2e9d..9ea8234 100644
--- a/source/core/fs_ext.c
+++ b/source/core/fs_ext.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "fs_ext.h"
+#include
+#include
/* IFileSystemProxy. */
Result fsOpenGameCardStorage(FsStorage *out, const FsGameCardHandle *handle, u32 partition)
diff --git a/source/core/gamecard.c b/source/core/gamecard.c
index 63577b7..52851f8 100644
--- a/source/core/gamecard.c
+++ b/source/core/gamecard.c
@@ -19,11 +19,11 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "mem.h"
-#include "gamecard.h"
-#include "keys.h"
-#include "rsa.h"
+#include
+#include
+#include
+#include
+#include
#define GAMECARD_READ_BUFFER_SIZE 0x800000 /* 8 MiB. */
diff --git a/source/core/hfs.c b/source/core/hfs.c
index a8c711a..4ee235e 100644
--- a/source/core/hfs.c
+++ b/source/core/hfs.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "gamecard.h"
+#include
+#include
#define HFS_PARTITION_NAME_INDEX(x) ((x) - 1)
diff --git a/source/core/http.c b/source/core/http.c
index 74df1d3..c49b7fa 100644
--- a/source/core/http.c
+++ b/source/core/http.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "http.h"
+#include
+#include
/* Global variables. */
diff --git a/source/core/keys.c b/source/core/keys.c
index e0877f9..0e21901 100644
--- a/source/core/keys.c
+++ b/source/core/keys.c
@@ -21,13 +21,13 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "keys.h"
-#include "nca.h"
-#include "rsa.h"
-#include "aes.h"
-#include "smc.h"
-#include "key_sources.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#define ETICKET_RSA_DEVICE_KEY_PUBLIC_EXPONENT 0x10001
diff --git a/source/core/legal_info.c b/source/core/legal_info.c
index a972016..db06fcd 100644
--- a/source/core/legal_info.c
+++ b/source/core/legal_info.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "legal_info.h"
+#include
+#include
bool legalInfoInitializeContext(LegalInfoContext *out, NcaContext *nca_ctx)
{
diff --git a/source/core/lz4.c b/source/core/lz4.c
index 654bfdf..35d7cc9 100644
--- a/source/core/lz4.c
+++ b/source/core/lz4.c
@@ -114,7 +114,7 @@
#endif
#define LZ4_STATIC_LINKING_ONLY /* LZ4_DISTANCE_MAX */
-#include "lz4.h"
+#include
/* see also "memory routines" below */
diff --git a/source/core/mem.c b/source/core/mem.c
index 56ac0d2..35ba478 100644
--- a/source/core/mem.c
+++ b/source/core/mem.c
@@ -20,8 +20,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "mem.h"
+#include
+#include
#define MEMLOG_DEBUG(fmt, ...) LOG_MSG_BUF_DEBUG(&g_memLogBuf, &g_memLogBufSize, fmt, ##__VA_ARGS__)
#define MEMLOG_ERROR(fmt, ...) LOG_MSG_BUF_ERROR(&g_memLogBuf, &g_memLogBufSize, fmt, ##__VA_ARGS__)
diff --git a/source/core/nacp.c b/source/core/nacp.c
index 6ad7ada..93cb6cd 100644
--- a/source/core/nacp.c
+++ b/source/core/nacp.c
@@ -19,9 +19,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nacp.h"
-#include "title.h"
+#include
+#include
+#include
/* Helper macros. */
diff --git a/source/core/nca.c b/source/core/nca.c
index b3c47da..c253c74 100644
--- a/source/core/nca.c
+++ b/source/core/nca.c
@@ -19,13 +19,13 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nca.h"
-#include "keys.h"
-#include "aes.h"
-#include "rsa.h"
-#include "gamecard.h"
-#include "title.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#define NCA_CRYPTO_BUFFER_SIZE 0x800000 /* 8 MiB. */
diff --git a/source/core/nca_storage.c b/source/core/nca_storage.c
index 92b0086..a6429ee 100644
--- a/source/core/nca_storage.c
+++ b/source/core/nca_storage.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nca_storage.h"
+#include
+#include
/* Function prototypes. */
diff --git a/source/core/npdm.c b/source/core/npdm.c
index a897765..b0a0c10 100644
--- a/source/core/npdm.c
+++ b/source/core/npdm.c
@@ -19,9 +19,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "npdm.h"
-#include "rsa.h"
+#include
+#include
+#include
bool npdmInitializeContext(NpdmContext *out, PartitionFileSystemContext *pfs_ctx)
{
diff --git a/source/core/nso.c b/source/core/nso.c
index 80d9240..1908cc3 100644
--- a/source/core/nso.c
+++ b/source/core/nso.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nso.h"
+#include
+#include
/* Function prototypes. */
diff --git a/source/core/nxdt_bfsar.c b/source/core/nxdt_bfsar.c
index 01c5ecd..14879b8 100644
--- a/source/core/nxdt_bfsar.c
+++ b/source/core/nxdt_bfsar.c
@@ -19,10 +19,10 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nxdt_bfsar.h"
-#include "romfs.h"
-#include "title.h"
+#include
+#include
+#include
+#include
#define BFSAR_FILENAME "qlaunch.bfsar"
#define BFSAR_ROMFS_PATH "/sound/" BFSAR_FILENAME
diff --git a/source/core/nxdt_json.c b/source/core/nxdt_json.c
index 48e71cb..d523267 100644
--- a/source/core/nxdt_json.c
+++ b/source/core/nxdt_json.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nxdt_json.h"
+#include
+#include
#define JSON_GETTER(functype, vartype, jsontype, ...) \
vartype jsonGet##functype(const struct json_object *obj, const char *path) { \
diff --git a/source/core/nxdt_log.c b/source/core/nxdt_log.c
index e28866d..71e312a 100644
--- a/source/core/nxdt_log.c
+++ b/source/core/nxdt_log.c
@@ -19,7 +19,7 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
+#include
#if (LOG_LEVEL >= LOG_LEVEL_DEBUG) && (LOG_LEVEL < LOG_LEVEL_NONE)
diff --git a/source/core/nxdt_utils.c b/source/core/nxdt_utils.c
index 8828a79..1c7d052 100644
--- a/source/core/nxdt_utils.c
+++ b/source/core/nxdt_utils.c
@@ -21,17 +21,17 @@
#include
-#include "nxdt_utils.h"
-#include "keys.h"
-#include "gamecard.h"
-#include "services.h"
-#include "nca.h"
-#include "usb.h"
-#include "title.h"
-#include "bfttf.h"
-#include "nxdt_bfsar.h"
-#include "nxdt_devoptab.h"
-#include "fatfs/ff.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
/* Type definitions. */
diff --git a/source/core/pfs.c b/source/core/pfs.c
index ee811f1..c4e32e2 100644
--- a/source/core/pfs.c
+++ b/source/core/pfs.c
@@ -19,9 +19,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "pfs.h"
-#include "npdm.h"
+#include
+#include
+#include
#define PFS_HEADER_PADDING_ALIGNMENT 0x20
diff --git a/source/core/program_info.c b/source/core/program_info.c
index c4143f0..5155d5d 100644
--- a/source/core/program_info.c
+++ b/source/core/program_info.c
@@ -21,9 +21,9 @@
#include
-#include "nxdt_utils.h"
-#include "program_info.h"
-#include "elf_symbol.h"
+#include
+#include
+#include
/* Helper macros. */
diff --git a/source/core/romfs.c b/source/core/romfs.c
index baea225..b4284ee 100644
--- a/source/core/romfs.c
+++ b/source/core/romfs.c
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "romfs.h"
+#include
+#include
/* Helper macros. */
diff --git a/source/core/rsa.c b/source/core/rsa.c
index c45a845..6e253c8 100644
--- a/source/core/rsa.c
+++ b/source/core/rsa.c
@@ -20,8 +20,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "rsa.h"
+#include
+#include
#include
#include
diff --git a/source/core/save.c b/source/core/save.c
index c846b13..1a86e68 100644
--- a/source/core/save.c
+++ b/source/core/save.c
@@ -20,8 +20,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "save.h"
+#include
+#include
static inline void save_bitmap_set_bit(void *buffer, size_t bit_offset)
{
diff --git a/source/core/services.c b/source/core/services.c
index 5fbb311..edbc362 100644
--- a/source/core/services.c
+++ b/source/core/services.c
@@ -19,9 +19,9 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "services.h"
-#include "es.h"
+#include
+#include
+#include
/* Type definitions. */
diff --git a/source/core/sha3.c b/source/core/sha3.c
index aa41f00..f55d8d7 100644
--- a/source/core/sha3.c
+++ b/source/core/sha3.c
@@ -21,8 +21,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "sha3.h"
+#include
+#include
#define SHA3_NUM_ROUNDS 24
diff --git a/source/core/tik.c b/source/core/tik.c
index 1e608d8..e2d51ea 100644
--- a/source/core/tik.c
+++ b/source/core/tik.c
@@ -20,16 +20,16 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "nca.h"
-#include "cert.h"
-#include "save.h"
-#include "es.h"
-#include "keys.h"
-#include "gamecard.h"
-#include "mem.h"
-#include "aes.h"
-#include "rsa.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#define TIK_COMMON_SAVEFILE_PATH BIS_SYSTEM_PARTITION_MOUNT_NAME "/save/80000000000000e1"
#define TIK_PERSONALIZED_SAVEFILE_PATH BIS_SYSTEM_PARTITION_MOUNT_NAME "/save/80000000000000e2"
diff --git a/source/core/title.c b/source/core/title.c
index 38fc255..11c4744 100644
--- a/source/core/title.c
+++ b/source/core/title.c
@@ -19,10 +19,10 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "title.h"
-#include "gamecard.h"
-#include "nacp.h"
+#include
+#include
+#include
+#include
#define NS_APPLICATION_RECORD_BLOCK_SIZE 1024
@@ -577,6 +577,7 @@ static TitleInfo *titleDuplicateTitleInfo(TitleInfo *title_info);
static int titleSystemTitleMetadataEntrySortFunction(const void *a, const void *b);
static int titleUserApplicationMetadataEntrySortFunction(const void *a, const void *b);
static int titleInfoEntrySortFunction(const void *a, const void *b);
+static int titleGameCardApplicationMetadataSortFunction(const void *a, const void *b);
static char *titleGetPatchVersionString(TitleInfo *title_info);
@@ -767,6 +768,7 @@ TitleGameCardApplicationMetadataEntry *titleGetGameCardApplicationMetadataEntrie
if (!app_info || app_info->meta_key.type != NcmContentMetaType_Application) continue;
u32 app_version = app_info->meta_key.version;
+ u32 dlc_count = 0;
/* Check if the inserted gamecard holds any bundled patches for the current user application. */
/* If so, we'll use the highest patch version available as part of the filename. */
@@ -782,6 +784,18 @@ TitleGameCardApplicationMetadataEntry *titleGetGameCardApplicationMetadataEntrie
app_version = cur_title_info->meta_key.version;
}
+ /* Count DLCs available for this application in the inserted gamecard. */
+ for(u32 j = 0; j < title_count; j++)
+ {
+ if (j == i) continue;
+
+ TitleInfo *cur_title_info = titles[j];
+ if (!cur_title_info || cur_title_info->meta_key.type != NcmContentMetaType_AddOnContent || \
+ !titleCheckIfAddOnContentIdBelongsToApplicationId(app_info->meta_key.id, cur_title_info->meta_key.id)) continue;
+
+ dlc_count++;
+ }
+
/* Reallocate application metadata pointer array. */
tmp_gc_app_metadata = realloc(gc_app_metadata, (app_count + 1) * sizeof(TitleGameCardApplicationMetadataEntry));
if (!tmp_gc_app_metadata)
@@ -801,6 +815,7 @@ TitleGameCardApplicationMetadataEntry *titleGetGameCardApplicationMetadataEntrie
memset(tmp_gc_app_metadata, 0, sizeof(TitleGameCardApplicationMetadataEntry));
tmp_gc_app_metadata->app_metadata = app_info->app_metadata;
tmp_gc_app_metadata->version.value = app_version;
+ tmp_gc_app_metadata->dlc_count = dlc_count;
/* Try to retrieve the display version. */
char *version_str = titleGetPatchVersionString(patch_info ? patch_info : app_info);
@@ -816,7 +831,13 @@ TitleGameCardApplicationMetadataEntry *titleGetGameCardApplicationMetadataEntrie
/* Update output counter. */
*out_count = app_count;
- if (!gc_app_metadata || !app_count) LOG_MSG_ERROR("No gamecard content data found for user applications!");
+ if (gc_app_metadata && app_count)
+ {
+ /* Reorder title metadata entries by name. */
+ if (app_count > 1) qsort(gc_app_metadata, app_count, sizeof(TitleGameCardApplicationMetadataEntry), &titleGameCardApplicationMetadataSortFunction);
+ } else {
+ LOG_MSG_ERROR("No gamecard content data found for user applications!");
+ }
}
return gc_app_metadata;
@@ -2061,7 +2082,7 @@ static bool titleGenerateTitleInfoEntriesForTitleStorage(TitleStorage *title_sto
if (extra_title_count < total) titleReallocateTitleInfoFromStorage(title_storage, 0, false);
/* Sort title info entries by title ID, version and storage ID. */
- qsort(title_storage->titles, title_storage->title_count, sizeof(TitleInfo*), &titleInfoEntrySortFunction);
+ if (title_storage->title_count > 1) qsort(title_storage->titles, title_storage->title_count, sizeof(TitleInfo*), &titleInfoEntrySortFunction);
/* Update linked lists for user applications, patches and add-on contents. */
/* This will also keep track of orphan titles - titles with no available application metadata. */
@@ -2770,6 +2791,14 @@ static int titleInfoEntrySortFunction(const void *a, const void *b)
return 0;
}
+static int titleGameCardApplicationMetadataSortFunction(const void *a, const void *b)
+{
+ const TitleGameCardApplicationMetadataEntry *gc_app_metadata_1 = (const TitleGameCardApplicationMetadataEntry*)a;
+ const TitleGameCardApplicationMetadataEntry *gc_app_metadata_2 = (const TitleGameCardApplicationMetadataEntry*)b;
+
+ return strcasecmp(gc_app_metadata_1->app_metadata->lang_entry.name, gc_app_metadata_2->app_metadata->lang_entry.name);
+}
+
static char *titleGetPatchVersionString(TitleInfo *title_info)
{
NcmContentInfo *nacp_content = NULL;
diff --git a/source/core/ums.c b/source/core/ums.c
index e53a557..b8a39dc 100644
--- a/source/core/ums.c
+++ b/source/core/ums.c
@@ -19,7 +19,7 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
+#include
/* Global variables. */
diff --git a/source/core/usb.c b/source/core/usb.c
index f21f25b..c7d0a0f 100644
--- a/source/core/usb.c
+++ b/source/core/usb.c
@@ -22,8 +22,8 @@
* along with this program. If not, see .
*/
-#include "nxdt_utils.h"
-#include "usb.h"
+#include
+#include
#define USB_ABI_VERSION_MAJOR 1
#define USB_ABI_VERSION_MINOR 2
diff --git a/source/main.cpp b/source/main.cpp
index 265d1f1..a807c4b 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -19,9 +19,9 @@
* along with this program. If not, see .
*/
-#include
-#include
-#include
+#include
+#include
+#include
namespace i18n = brls::i18n; /* For getStr(). */
using namespace i18n::literals; /* For _i18n. */
diff --git a/source/tasks.cpp b/source/tasks.cpp
deleted file mode 100644
index a2a3adb..0000000
--- a/source/tasks.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * tasks.cpp
- *
- * Copyright (c) 2020-2024, DarkMatterCore .
- *
- * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
- *
- * nxdumptool is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * nxdumptool is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include
-#include
-
-#define NXDT_TASK_INTERVAL 250 /* 250 ms. */
-
-using namespace brls::i18n::literals; /* For _i18n. */
-
-namespace nxdt::tasks
-{
- /* Status info task. */
-
- StatusInfoTask::StatusInfoTask() : brls::RepeatingTask(NXDT_TASK_INTERVAL)
- {
- brls::RepeatingTask::start();
- LOG_MSG_DEBUG("Status info task started.");
- }
-
- StatusInfoTask::~StatusInfoTask()
- {
- LOG_MSG_DEBUG("Status info task stopped.");
- }
-
- bool StatusInfoTask::IsInternetConnectionAvailable(void)
- {
- return this->status_info_data.connected;
- }
-
- void StatusInfoTask::run(retro_time_t current_time)
- {
- brls::RepeatingTask::run(current_time);
-
- StatusInfoData *status_info_data = &(this->status_info_data);
-
- /* Get current time. */
- time_t unix_time = time(nullptr);
- localtime_r(&unix_time, &(status_info_data->timeinfo));
-
- /* Get battery stats. */
- psmGetBatteryChargePercentage(&(status_info_data->charge_percentage));
- psmGetChargerType(&(status_info_data->charger_type));
-
- /* Get network connection status. */
- u32 signal_strength = 0;
- NifmInternetConnectionStatus connection_status{};
- char *ip_addr = nullptr;
-
- status_info_data->connected = false;
-
- Result rc = nifmGetInternetConnectionStatus(&(status_info_data->connection_type), &signal_strength, &connection_status);
- if (R_SUCCEEDED(rc) && status_info_data->connection_type && connection_status == NifmInternetConnectionStatus_Connected)
- {
- status_info_data->connected = true;
-
- struct in_addr addr = { .s_addr = INADDR_NONE };
- nifmGetCurrentIpAddress(&(addr.s_addr));
-
- if (addr.s_addr != INADDR_NONE && (ip_addr = inet_ntoa(addr))) snprintf(status_info_data->ip_addr, MAX_ELEMENTS(status_info_data->ip_addr), "%s", ip_addr);
- }
-
- /* Fire task event. */
- this->status_info_event.fire(this->status_info_data);
- }
-
- /* Gamecard task. */
-
- GameCardTask::GameCardTask() : brls::RepeatingTask(NXDT_TASK_INTERVAL)
- {
- brls::RepeatingTask::start();
- LOG_MSG_DEBUG("Gamecard task started.");
-
- this->first_notification = (gamecardGetStatus() >= GameCardStatus_Processing);
- }
-
- GameCardTask::~GameCardTask()
- {
- LOG_MSG_DEBUG("Gamecard task stopped.");
- }
-
- void GameCardTask::run(retro_time_t current_time)
- {
- brls::RepeatingTask::run(current_time);
-
- this->cur_gc_status = static_cast(gamecardGetStatus());
- if (this->cur_gc_status != this->prev_gc_status)
- {
- LOG_MSG_DEBUG("Gamecard status change triggered: %u.", this->cur_gc_status);
-
- if (!this->first_notification)
- {
- if (this->prev_gc_status == GameCardStatus_NotInserted && this->cur_gc_status == GameCardStatus_Processing)
- {
- brls::Application::notify("gamecard_tab/error_frame/processing"_i18n);
- } else
- if (this->prev_gc_status == GameCardStatus_Processing && this->cur_gc_status > GameCardStatus_Processing)
- {
- brls::Application::notify("tasks/notifications/gamecard_status_updated"_i18n);
- } else
- if (this->cur_gc_status == GameCardStatus_NotInserted)
- {
- brls::Application::notify("tasks/notifications/gamecard_ejected"_i18n);
- }
- } else {
- this->first_notification = false;
- }
-
- /* Update previous gamecard status. */
- this->prev_gc_status = this->cur_gc_status;
-
- /* Fire task event. */
- this->gc_status_event.fire(this->cur_gc_status);
- }
- }
-
- /* Title task. */
-
- TitleTask::TitleTask() : brls::RepeatingTask(NXDT_TASK_INTERVAL)
- {
- /* Get system metadata entries. */
- this->PopulateApplicationMetadataVector(true);
-
- /* Get user metadata entries. */
- this->PopulateApplicationMetadataVector(false);
-
- /* Start task. */
- brls::RepeatingTask::start();
- LOG_MSG_DEBUG("Title task started.");
- }
-
- TitleTask::~TitleTask()
- {
- /* Clear application metadata vectors. */
- this->system_metadata.clear();
- this->user_metadata.clear();
-
- LOG_MSG_DEBUG("Title task stopped.");
- }
-
- void TitleTask::run(retro_time_t current_time)
- {
- brls::RepeatingTask::run(current_time);
-
- if (titleIsGameCardInfoUpdated())
- {
- LOG_MSG_DEBUG("Title info updated.");
- //brls::Application::notify("tasks/notifications/user_titles"_i18n);
-
- /* Update user metadata vector. */
- this->PopulateApplicationMetadataVector(false);
-
- /* Fire task event. */
- this->user_title_event.fire(this->user_metadata);
- }
- }
-
- const TitleApplicationMetadataVector& TitleTask::GetApplicationMetadata(bool is_system)
- {
- return (is_system ? this->system_metadata : this->user_metadata);
- }
-
- void TitleTask::PopulateApplicationMetadataVector(bool is_system)
- {
- TitleApplicationMetadata **app_metadata = nullptr;
- u32 app_metadata_count = 0;
-
- /* Get pointer to output vector. */
- TitleApplicationMetadataVector& vector = (is_system ? this->system_metadata : this->user_metadata);
- vector.clear();
-
- /* Get application metadata entries. */
- app_metadata = titleGetApplicationMetadataEntries(is_system, &app_metadata_count);
- if (app_metadata)
- {
- /* Fill output vector. */
- for(u32 i = 0; i < app_metadata_count; i++) vector.push_back(app_metadata[i]);
-
- /* Free application metadata array. */
- free(app_metadata);
- }
-
- LOG_MSG_DEBUG("Retrieved %u %s metadata %s.", app_metadata_count, is_system ? "system" : "user", app_metadata_count == 1 ? "entry" : "entries");
- }
-
- /* USB Mass Storage task. */
-
- UmsTask::UmsTask() : brls::RepeatingTask(NXDT_TASK_INTERVAL)
- {
- brls::RepeatingTask::start();
- LOG_MSG_DEBUG("UMS task started.");
- }
-
- UmsTask::~UmsTask()
- {
- /* Clear UMS device vector. */
- this->ums_devices_vector.clear();
-
- /* Free UMS devices buffer. */
- if (this->ums_devices) free(this->ums_devices);
-
- LOG_MSG_DEBUG("UMS task stopped.");
- }
-
- void UmsTask::run(retro_time_t current_time)
- {
- brls::RepeatingTask::run(current_time);
-
- if (umsIsDeviceInfoUpdated())
- {
- LOG_MSG_DEBUG("UMS device info updated.");
- brls::Application::notify("tasks/notifications/ums_device"_i18n);
-
- /* Update UMS device vector. */
- this->PopulateUmsDeviceVector();
-
- /* Fire task event. */
- this->ums_event.fire(this->ums_devices_vector);
- }
- }
-
- const UmsDeviceVector& UmsTask::GetUmsDevices(void)
- {
- return this->ums_devices_vector;
- }
-
- void UmsTask::PopulateUmsDeviceVector(void)
- {
- /* Clear UMS device vector. */
- this->ums_devices_vector.clear();
-
- /* Free UMS devices buffer. */
- if (this->ums_devices) free(this->ums_devices);
-
- /* Reset UMS devices counter. */
- this->ums_devices_count = 0;
-
- /* Get UMS devices. */
- this->ums_devices = umsGetDevices(&(this->ums_devices_count));
- if (this->ums_devices)
- {
- /* Fill UMS device vector. */
- for(u32 i = 0; i < this->ums_devices_count; i++)
- {
- const UsbHsFsDevice *cur_ums_device = &(this->ums_devices[i]);
- int name_len = static_cast(strlen(cur_ums_device->name) - 1);
- std::string ums_info{};
-
- if (cur_ums_device->product_name[0])
- {
- ums_info = fmt::format("{1:.{0}} ({2}, LUN #{3}, FS#{4}, {5})", name_len, cur_ums_device->name, cur_ums_device->product_name, cur_ums_device->lun, cur_ums_device->fs_idx, LIBUSBHSFS_FS_TYPE_STR(cur_ums_device->fs_type));
- } else {
- ums_info = fmt::format("{1:.{0}} (LUN #{2}, FS#{3}, {4})", name_len, cur_ums_device->name, cur_ums_device->lun, cur_ums_device->fs_idx, LIBUSBHSFS_FS_TYPE_STR(cur_ums_device->fs_type));
- }
-
- this->ums_devices_vector.push_back(std::make_pair(cur_ums_device, ums_info));
- }
- }
-
- LOG_MSG_DEBUG("Retrieved info for %u UMS %s.", this->ums_devices_count, this->ums_devices_count == 1 ? "device" : "devices");
- }
-
- /* USB host device connection task. */
-
- UsbHostTask::UsbHostTask() : brls::RepeatingTask(NXDT_TASK_INTERVAL)
- {
- brls::RepeatingTask::start();
- LOG_MSG_DEBUG("USB host task started.");
- }
-
- UsbHostTask::~UsbHostTask()
- {
- LOG_MSG_DEBUG("USB host task stopped.");
- }
-
- void UsbHostTask::run(retro_time_t current_time)
- {
- brls::RepeatingTask::run(current_time);
-
- this->cur_usb_host_speed = static_cast(usbIsReady());
- if (this->cur_usb_host_speed != this->prev_usb_host_speed)
- {
- LOG_MSG_DEBUG("USB host speed changed: %u.", this->cur_usb_host_speed);
- brls::Application::notify(this->cur_usb_host_speed ? "tasks/notifications/usb_host_connected"_i18n : "tasks/notifications/usb_host_disconnected"_i18n);
-
- /* Update previous USB host speed. */
- this->prev_usb_host_speed = this->cur_usb_host_speed;
-
- /* Fire task event. */
- this->usb_host_event.fire(this->cur_usb_host_speed);
- }
- }
-
- const UsbHostSpeed& UsbHostTask::GetUsbHostSpeed(void)
- {
- return this->cur_usb_host_speed;
- }
-}
diff --git a/source/gamecard_image_dump_task.cpp b/source/tasks/gamecard_image_dump_task.cpp
similarity index 98%
rename from source/gamecard_image_dump_task.cpp
rename to source/tasks/gamecard_image_dump_task.cpp
index 240e568..c91e78b 100644
--- a/source/gamecard_image_dump_task.cpp
+++ b/source/tasks/gamecard_image_dump_task.cpp
@@ -19,10 +19,10 @@
* along with this program. If not, see .
*/
-#include
+#include
+#include
+#include
#include
-#include
-#include
namespace i18n = brls::i18n; /* For getStr(). */
using namespace i18n::literals; /* For _i18n. */
diff --git a/source/tasks/gamecard_status_task.cpp b/source/tasks/gamecard_status_task.cpp
new file mode 100644
index 0000000..1145767
--- /dev/null
+++ b/source/tasks/gamecard_status_task.cpp
@@ -0,0 +1,75 @@
+/*
+ * gamecard_status_task.cpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+using namespace brls::i18n::literals; /* For _i18n. */
+
+namespace nxdt::tasks
+{
+ GameCardStatusTask::GameCardStatusTask() : brls::RepeatingTask(REPEATING_TASK_INTERVAL)
+ {
+ brls::RepeatingTask::start();
+ LOG_MSG_DEBUG("Gamecard task started.");
+
+ this->first_notification = (gamecardGetStatus() >= GameCardStatus_Processing);
+ }
+
+ GameCardStatusTask::~GameCardStatusTask()
+ {
+ LOG_MSG_DEBUG("Gamecard task stopped.");
+ }
+
+ void GameCardStatusTask::run(retro_time_t current_time)
+ {
+ brls::RepeatingTask::run(current_time);
+
+ this->cur_gc_status = static_cast(gamecardGetStatus());
+ if (this->cur_gc_status != this->prev_gc_status)
+ {
+ LOG_MSG_DEBUG("Gamecard status change triggered: %u.", this->cur_gc_status);
+
+ if (!this->first_notification)
+ {
+ if (this->prev_gc_status == GameCardStatus_NotInserted && this->cur_gc_status == GameCardStatus_Processing)
+ {
+ brls::Application::notify("gamecard_tab/error_frame/processing"_i18n);
+ } else
+ if (this->prev_gc_status == GameCardStatus_Processing && this->cur_gc_status > GameCardStatus_Processing)
+ {
+ brls::Application::notify("tasks/notifications/gamecard_status_updated"_i18n);
+ } else
+ if (this->cur_gc_status == GameCardStatus_NotInserted)
+ {
+ brls::Application::notify("tasks/notifications/gamecard_ejected"_i18n);
+ }
+ } else {
+ this->first_notification = false;
+ }
+
+ /* Update previous gamecard status. */
+ this->prev_gc_status = this->cur_gc_status;
+
+ /* Fire task event. */
+ this->gc_status_event.fire(this->cur_gc_status);
+ }
+ }
+}
diff --git a/source/tasks/status_info_task.cpp b/source/tasks/status_info_task.cpp
new file mode 100644
index 0000000..edd1cc5
--- /dev/null
+++ b/source/tasks/status_info_task.cpp
@@ -0,0 +1,77 @@
+/*
+ * status_info_task.cpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+namespace nxdt::tasks
+{
+ StatusInfoTask::StatusInfoTask() : brls::RepeatingTask(REPEATING_TASK_INTERVAL)
+ {
+ brls::RepeatingTask::start();
+ LOG_MSG_DEBUG("Status info task started.");
+ }
+
+ StatusInfoTask::~StatusInfoTask()
+ {
+ LOG_MSG_DEBUG("Status info task stopped.");
+ }
+
+ bool StatusInfoTask::IsInternetConnectionAvailable(void)
+ {
+ return this->status_info_data.connected;
+ }
+
+ void StatusInfoTask::run(retro_time_t current_time)
+ {
+ brls::RepeatingTask::run(current_time);
+
+ StatusInfoData *status_info_data = &(this->status_info_data);
+
+ /* Get current time. */
+ time_t unix_time = time(nullptr);
+ localtime_r(&unix_time, &(status_info_data->timeinfo));
+
+ /* Get battery stats. */
+ psmGetBatteryChargePercentage(&(status_info_data->charge_percentage));
+ psmGetChargerType(&(status_info_data->charger_type));
+
+ /* Get network connection status. */
+ u32 signal_strength = 0;
+ NifmInternetConnectionStatus connection_status{};
+ char *ip_addr = nullptr;
+
+ status_info_data->connected = false;
+
+ Result rc = nifmGetInternetConnectionStatus(&(status_info_data->connection_type), &signal_strength, &connection_status);
+ if (R_SUCCEEDED(rc) && status_info_data->connection_type && connection_status == NifmInternetConnectionStatus_Connected)
+ {
+ status_info_data->connected = true;
+
+ struct in_addr addr = { .s_addr = INADDR_NONE };
+ nifmGetCurrentIpAddress(&(addr.s_addr));
+
+ if (addr.s_addr != INADDR_NONE && (ip_addr = inet_ntoa(addr))) snprintf(status_info_data->ip_addr, MAX_ELEMENTS(status_info_data->ip_addr), "%s", ip_addr);
+ }
+
+ /* Fire task event. */
+ this->status_info_event.fire(this->status_info_data);
+ }
+}
diff --git a/source/tasks/title_metadata_task.cpp b/source/tasks/title_metadata_task.cpp
new file mode 100644
index 0000000..3df6f46
--- /dev/null
+++ b/source/tasks/title_metadata_task.cpp
@@ -0,0 +1,94 @@
+/*
+ * title_metadata_task.cpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+using namespace brls::i18n::literals; /* For _i18n. */
+
+namespace nxdt::tasks
+{
+ TitleMetadataTask::TitleMetadataTask() : brls::RepeatingTask(REPEATING_TASK_INTERVAL)
+ {
+ /* Get system metadata entries. */
+ this->PopulateApplicationMetadataVector(true);
+
+ /* Get user metadata entries. */
+ this->PopulateApplicationMetadataVector(false);
+
+ /* Start task. */
+ brls::RepeatingTask::start();
+ LOG_MSG_DEBUG("Title metadata task started.");
+ }
+
+ TitleMetadataTask::~TitleMetadataTask()
+ {
+ /* Clear application metadata vectors. */
+ this->system_metadata.clear();
+ this->user_metadata.clear();
+
+ LOG_MSG_DEBUG("Title metadata task stopped.");
+ }
+
+ void TitleMetadataTask::run(retro_time_t current_time)
+ {
+ brls::RepeatingTask::run(current_time);
+
+ if (titleIsGameCardInfoUpdated())
+ {
+ LOG_MSG_DEBUG("Title info updated.");
+ //brls::Application::notify("tasks/notifications/user_titles"_i18n);
+
+ /* Update user metadata vector. */
+ this->PopulateApplicationMetadataVector(false);
+
+ /* Fire task event. */
+ this->user_title_event.fire(this->user_metadata);
+ }
+ }
+
+ const TitleApplicationMetadataVector& TitleMetadataTask::GetApplicationMetadata(bool is_system)
+ {
+ return (is_system ? this->system_metadata : this->user_metadata);
+ }
+
+ void TitleMetadataTask::PopulateApplicationMetadataVector(bool is_system)
+ {
+ TitleApplicationMetadata **app_metadata = nullptr;
+ u32 app_metadata_count = 0;
+
+ /* Get pointer to output vector. */
+ TitleApplicationMetadataVector& vector = (is_system ? this->system_metadata : this->user_metadata);
+ vector.clear();
+
+ /* Get application metadata entries. */
+ app_metadata = titleGetApplicationMetadataEntries(is_system, &app_metadata_count);
+ if (app_metadata)
+ {
+ /* Fill output vector. */
+ for(u32 i = 0; i < app_metadata_count; i++) vector.push_back(app_metadata[i]);
+
+ /* Free application metadata array. */
+ free(app_metadata);
+ }
+
+ LOG_MSG_DEBUG("Retrieved %u %s metadata %s.", app_metadata_count, is_system ? "system" : "user", app_metadata_count == 1 ? "entry" : "entries");
+ }
+}
diff --git a/source/tasks/ums_task.cpp b/source/tasks/ums_task.cpp
new file mode 100644
index 0000000..29a69c5
--- /dev/null
+++ b/source/tasks/ums_task.cpp
@@ -0,0 +1,102 @@
+/*
+ * ums_task.cpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+using namespace brls::i18n::literals; /* For _i18n. */
+
+namespace nxdt::tasks
+{
+ UmsTask::UmsTask() : brls::RepeatingTask(REPEATING_TASK_INTERVAL)
+ {
+ brls::RepeatingTask::start();
+ LOG_MSG_DEBUG("UMS task started.");
+ }
+
+ UmsTask::~UmsTask()
+ {
+ /* Clear UMS device vector. */
+ this->ums_devices_vector.clear();
+
+ /* Free UMS devices buffer. */
+ if (this->ums_devices) free(this->ums_devices);
+
+ LOG_MSG_DEBUG("UMS task stopped.");
+ }
+
+ void UmsTask::run(retro_time_t current_time)
+ {
+ brls::RepeatingTask::run(current_time);
+
+ if (umsIsDeviceInfoUpdated())
+ {
+ LOG_MSG_DEBUG("UMS device info updated.");
+ brls::Application::notify("tasks/notifications/ums_device"_i18n);
+
+ /* Update UMS device vector. */
+ this->PopulateUmsDeviceVector();
+
+ /* Fire task event. */
+ this->ums_event.fire(this->ums_devices_vector);
+ }
+ }
+
+ const UmsDeviceVector& UmsTask::GetUmsDevices(void)
+ {
+ return this->ums_devices_vector;
+ }
+
+ void UmsTask::PopulateUmsDeviceVector(void)
+ {
+ /* Clear UMS device vector. */
+ this->ums_devices_vector.clear();
+
+ /* Free UMS devices buffer. */
+ if (this->ums_devices) free(this->ums_devices);
+
+ /* Reset UMS devices counter. */
+ this->ums_devices_count = 0;
+
+ /* Get UMS devices. */
+ this->ums_devices = umsGetDevices(&(this->ums_devices_count));
+ if (this->ums_devices)
+ {
+ /* Fill UMS device vector. */
+ for(u32 i = 0; i < this->ums_devices_count; i++)
+ {
+ const UsbHsFsDevice *cur_ums_device = &(this->ums_devices[i]);
+ int name_len = static_cast(strlen(cur_ums_device->name) - 1);
+ std::string ums_info{};
+
+ if (cur_ums_device->product_name[0])
+ {
+ ums_info = fmt::format("{1:.{0}} ({2}, LUN #{3}, FS#{4}, {5})", name_len, cur_ums_device->name, cur_ums_device->product_name, cur_ums_device->lun, cur_ums_device->fs_idx, LIBUSBHSFS_FS_TYPE_STR(cur_ums_device->fs_type));
+ } else {
+ ums_info = fmt::format("{1:.{0}} (LUN #{2}, FS#{3}, {4})", name_len, cur_ums_device->name, cur_ums_device->lun, cur_ums_device->fs_idx, LIBUSBHSFS_FS_TYPE_STR(cur_ums_device->fs_type));
+ }
+
+ this->ums_devices_vector.push_back(std::make_pair(cur_ums_device, ums_info));
+ }
+ }
+
+ LOG_MSG_DEBUG("Retrieved info for %u UMS %s.", this->ums_devices_count, this->ums_devices_count == 1 ? "device" : "devices");
+ }
+}
diff --git a/source/tasks/usb_host_task.cpp b/source/tasks/usb_host_task.cpp
new file mode 100644
index 0000000..19f9a7b
--- /dev/null
+++ b/source/tasks/usb_host_task.cpp
@@ -0,0 +1,61 @@
+/*
+ * usb_host_task.cpp
+ *
+ * Copyright (c) 2020-2024, DarkMatterCore .
+ *
+ * This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
+ *
+ * nxdumptool is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nxdumptool is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+using namespace brls::i18n::literals; /* For _i18n. */
+
+namespace nxdt::tasks
+{
+ UsbHostTask::UsbHostTask() : brls::RepeatingTask(REPEATING_TASK_INTERVAL)
+ {
+ brls::RepeatingTask::start();
+ LOG_MSG_DEBUG("USB host task started.");
+ }
+
+ UsbHostTask::~UsbHostTask()
+ {
+ LOG_MSG_DEBUG("USB host task stopped.");
+ }
+
+ void UsbHostTask::run(retro_time_t current_time)
+ {
+ brls::RepeatingTask::run(current_time);
+
+ this->cur_usb_host_speed = static_cast(usbIsReady());
+ if (this->cur_usb_host_speed != this->prev_usb_host_speed)
+ {
+ LOG_MSG_DEBUG("USB host speed changed: %u.", this->cur_usb_host_speed);
+ brls::Application::notify(this->cur_usb_host_speed ? "tasks/notifications/usb_host_connected"_i18n : "tasks/notifications/usb_host_disconnected"_i18n);
+
+ /* Update previous USB host speed. */
+ this->prev_usb_host_speed = this->cur_usb_host_speed;
+
+ /* Fire task event. */
+ this->usb_host_event.fire(this->cur_usb_host_speed);
+ }
+ }
+
+ const UsbHostSpeed& UsbHostTask::GetUsbHostSpeed(void)
+ {
+ return this->cur_usb_host_speed;
+ }
+}
diff --git a/source/exception_handler.cpp b/source/utils/exception_handler.cpp
similarity index 99%
rename from source/exception_handler.cpp
rename to source/utils/exception_handler.cpp
index 9a0ca54..4be6f1b 100644
--- a/source/exception_handler.cpp
+++ b/source/utils/exception_handler.cpp
@@ -21,7 +21,7 @@
* along with this program. If not, see .
*/
-#include
+#include
#include
/* Helper macros. */
diff --git a/source/file_writer.cpp b/source/utils/file_writer.cpp
similarity index 99%
rename from source/file_writer.cpp
rename to source/utils/file_writer.cpp
index 181f205..e9ddd70 100644
--- a/source/file_writer.cpp
+++ b/source/utils/file_writer.cpp
@@ -19,7 +19,7 @@
* along with this program. If not, see .
*/
-#include
+#include
namespace i18n = brls::i18n; /* For getStr(). */
using namespace i18n::literals; /* For _i18n. */
diff --git a/source/about_tab.cpp b/source/views/about_tab.cpp
similarity index 98%
rename from source/about_tab.cpp
rename to source/views/about_tab.cpp
index 508563f..3ed621d 100644
--- a/source/about_tab.cpp
+++ b/source/views/about_tab.cpp
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include
-#include
+#include
+#include
#define LOGO_SIZE 256
diff --git a/source/data_transfer_progress_display.cpp b/source/views/data_transfer_progress_display.cpp
similarity index 98%
rename from source/data_transfer_progress_display.cpp
rename to source/views/data_transfer_progress_display.cpp
index a3c4482..0604ccd 100644
--- a/source/data_transfer_progress_display.cpp
+++ b/source/views/data_transfer_progress_display.cpp
@@ -19,7 +19,7 @@
* along with this program. If not, see .
*/
-#include
+#include
namespace nxdt::views
{
diff --git a/source/dump_options_frame.cpp b/source/views/dump_options_frame.cpp
similarity index 99%
rename from source/dump_options_frame.cpp
rename to source/views/dump_options_frame.cpp
index ac63b49..d25faa4 100644
--- a/source/dump_options_frame.cpp
+++ b/source/views/dump_options_frame.cpp
@@ -19,7 +19,7 @@
* along with this program. If not, see .
*/
-#include
+#include
namespace i18n = brls::i18n; /* For getStr(). */
using namespace i18n::literals; /* For _i18n. */
diff --git a/source/error_frame.cpp b/source/views/error_frame.cpp
similarity index 98%
rename from source/error_frame.cpp
rename to source/views/error_frame.cpp
index 64859fa..337a674 100644
--- a/source/error_frame.cpp
+++ b/source/views/error_frame.cpp
@@ -21,8 +21,8 @@
* along with this program. If not, see .
*/
-#include
-#include
+#include
+#include
namespace nxdt::views
{
diff --git a/source/gamecard_image_dump_options_frame.cpp b/source/views/gamecard_image_dump_options_frame.cpp
similarity index 94%
rename from source/gamecard_image_dump_options_frame.cpp
rename to source/views/gamecard_image_dump_options_frame.cpp
index 8cbc6e0..14a49ba 100644
--- a/source/gamecard_image_dump_options_frame.cpp
+++ b/source/views/gamecard_image_dump_options_frame.cpp
@@ -19,8 +19,8 @@
* along with this program. If not, see .
*/
-#include
-#include
+#include
+#include
namespace i18n = brls::i18n; /* For getStr(). */
using namespace i18n::literals; /* For _i18n. */
@@ -43,7 +43,7 @@ namespace nxdt::views
DumpOptionsFrame(root_view, "gamecard_tab/list/dump_card_image/label"_i18n, std::string(GAMECARD_SUBDIR), raw_filename)
{
/* Subscribe to the gamecard task event. */
- this->gc_task_sub = this->root_view->RegisterGameCardTaskListener([this](const GameCardStatus& gc_status) {
+ this->gc_task_sub = this->root_view->RegisterGameCardStatusTaskListener([this](const GameCardStatus& gc_status) {
/* Realistically speaking, this should always match a NotInserted status, but it's always better to be safe than sorry. */
if (gc_status != GameCardStatus_NotInserted) return;
@@ -113,6 +113,6 @@ namespace nxdt::views
this->gc_ejected_event.unsubscribeAll();
/* Unregister gamecard task listener. */
- this->root_view->UnregisterGameCardTaskListener(this->gc_task_sub);
+ this->root_view->UnregisterGameCardStatusTaskListener(this->gc_task_sub);
}
}
diff --git a/source/gamecard_tab.cpp b/source/views/gamecard_tab.cpp
similarity index 58%
rename from source/gamecard_tab.cpp
rename to source/views/gamecard_tab.cpp
index 295fde5..e1c13e6 100644
--- a/source/gamecard_tab.cpp
+++ b/source/views/gamecard_tab.cpp
@@ -19,10 +19,17 @@
* along with this program. If not, see .
*/
-#include
-#include
-#include
-#include
+#include
+#include
+#include
+#include
+#include
+
+#define GAMECARD_TAB_TABLE_PROPERTY(name) brls::TableRow *name = properties_table->addRow(brls::TableRowType::BODY, i18n::getStr("gamecard_tab/list/properties_table/" #name))
+
+#define GAMECARD_TAB_LISTITEM_ELEMENT(name, ...) \
+brls::ListItem *name = new brls::ListItem(i18n::getStr("gamecard_tab/list/" #name "/label"), i18n::getStr("gamecard_tab/list/" #name "/description", ##__VA_ARGS__)); \
+this->list->addView(name)
namespace i18n = brls::i18n; /* For getStr(). */
using namespace i18n::literals; /* For _i18n. */
@@ -36,7 +43,7 @@ namespace nxdt::views
this->list->setMarginBottom(20);
/* Subscribe to the gamecard status event. */
- this->gc_status_task_sub = this->root_view->RegisterGameCardTaskListener([this](GameCardStatus gc_status) {
+ this->gc_status_task_sub = this->root_view->RegisterGameCardStatusTaskListener([this](GameCardStatus gc_status) {
/* Process gamecard status. */
this->ProcessGameCardStatus(gc_status);
});
@@ -48,7 +55,7 @@ namespace nxdt::views
GameCardTab::~GameCardTab()
{
/* Unregister task listener. */
- this->root_view->UnregisterGameCardTaskListener(this->gc_status_task_sub);
+ this->root_view->UnregisterGameCardStatusTaskListener(this->gc_status_task_sub);
}
void GameCardTab::ProcessGameCardStatus(GameCardStatus gc_status)
@@ -85,41 +92,8 @@ namespace nxdt::views
this->gc_status = gc_status;
}
- std::string GameCardTab::GetFormattedSizeString(GameCardSizeFunc func)
- {
- u64 size = 0;
- char strbuf[0x40] = {0};
-
- func(&size);
- utilsGenerateFormattedSizeString(static_cast(size), strbuf, sizeof(strbuf));
-
- return std::string(strbuf);
- }
-
- std::string GameCardTab::GetCardIdSetString(FsGameCardIdSet *card_id_set)
- {
- char card_id_set_str[0x20] = {0};
-
- utilsGenerateHexString(card_id_set_str, sizeof(card_id_set_str), &(card_id_set->id1), sizeof(card_id_set->id1), true);
-
- card_id_set_str[8] = ' ';
- utilsGenerateHexString(card_id_set_str + 9, sizeof(card_id_set_str) - 9, &(card_id_set->id2), sizeof(card_id_set->id2), true);
-
- card_id_set_str[17] = ' ';
- utilsGenerateHexString(card_id_set_str + 18, sizeof(card_id_set_str) - 18, &(card_id_set->id3), sizeof(card_id_set->id3), true);
-
- return std::string(card_id_set_str);
- }
-
void GameCardTab::PopulateList(void)
{
- TitleGameCardApplicationMetadataEntry *gc_app_metadata = nullptr;
- u32 gc_app_metadata_count = 0;
- GameCardHeader card_header = {0};
- GameCardInfo card_info = {0};
- FsGameCardIdSet card_id_set = {0};
- char *raw_filename = nullptr;
-
bool update_focused_view = this->IsListItemFocused();
int focus_stack_index = this->GetFocusStackViewIndex();
@@ -127,83 +101,147 @@ namespace nxdt::views
this->list->clear();
this->list->invalidate(true);
+ /* Generate and store raw filenames. */
+ this->GenerateRawFilenames();
+
/* Information about how to handle HOS launch errors. */
/* TODO: remove this if we ever find a way to fix this issue. */
FocusableLabel *launch_error_info = new FocusableLabel(true, false, brls::LabelStyle::DESCRIPTION, "gamecard_tab/list/launch_error_info"_i18n, true);
launch_error_info->setHorizontalAlign(NVG_ALIGN_CENTER);
this->list->addView(launch_error_info);
+ /* Add gamecard application metadata information. */
+ this->AddApplicationMetadataItems();
+
+ /* Add gamecard properties table. */
+ this->AddPropertiesTable();
+
+ /* Add ListItem elements. */
+ this->list->addView(new brls::Header("gamecard_tab/list/dump_options"_i18n));
+
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_card_image);
+
+ this->list->addView(new brls::ListItemGroupSpacing(true));
+
+ brls::Label *advanced_disclaimer = new brls::Label(brls::LabelStyle::DESCRIPTION, "gamecard_tab/list/advanced_disclaimer"_i18n, true);
+ advanced_disclaimer->setHorizontalAlign(NVG_ALIGN_CENTER);
+ this->list->addView(advanced_disclaimer);
+
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_initial_data);
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_certificate, GAMECARD_CERT_OFFSET / GAMECARD_PAGE_SIZE);
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_card_id_set);
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_card_uid);
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_header, 0);
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_plaintext_cardinfo);
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_specific_data);
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_hfs_partitions);
+ GAMECARD_TAB_LISTITEM_ELEMENT(browse_hfs_partitions);
+ GAMECARD_TAB_LISTITEM_ELEMENT(dump_lafw);
+
+ /* Set ListItem callbacks. */
+ dump_card_image->getClickEvent()->subscribe([this](brls::View *view) {
+ /* Display gamecard image dump options. */
+ std::string& raw_filename = (configGetInteger("naming_convention") == TitleNamingConvention_Full ? raw_filename_full : raw_filename_id_only);
+ brls::Application::pushView(new GameCardImageDumpOptionsFrame(this->root_view, raw_filename), brls::ViewAnimation::SLIDE_LEFT);
+ });
+
+ /* Update focus stack, if needed. */
+ if (focus_stack_index > -1) this->UpdateFocusStackViewAtIndex(focus_stack_index, this->GetListFirstFocusableChild());
+
+ /* Switch to the list view. */
+ this->list->invalidate(true);
+ this->SwitchLayerView(false, update_focused_view, focus_stack_index < 0);
+ }
+
+ void GameCardTab::AddApplicationMetadataItems(void)
+ {
+ TitleGameCardApplicationMetadataEntry *gc_app_metadata = nullptr;
+ u32 gc_app_metadata_count = 0;
+
/* Retrieve gamecard application metadata. */
gc_app_metadata = titleGetGameCardApplicationMetadataEntries(&gc_app_metadata_count);
- if (gc_app_metadata)
+ if (!gc_app_metadata) return;
+
+ ON_SCOPE_EXIT { free(gc_app_metadata); };
+
+ /* Display the applications that are part of the inserted gamecard. */
+ this->list->addView(new brls::Header("gamecard_tab/list/user_titles/header"_i18n));
+
+ /* Add information about how to work with individual user titles. */
+ brls::Label *user_titles_info = new brls::Label(brls::LabelStyle::DESCRIPTION, i18n::getStr("gamecard_tab/list/user_titles/info"_i18n, \
+ "root_view/tabs/user_titles"_i18n), true);
+ user_titles_info->setHorizontalAlign(NVG_ALIGN_CENTER);
+ this->list->addView(user_titles_info);
+
+ /* Add gamecard application metadata items. */
+ for(u32 i = 0; i < gc_app_metadata_count; i++)
{
- /* Display the applications that are part of the inserted gamecard. */
- this->list->addView(new brls::Header("gamecard_tab/list/user_titles/header"_i18n));
+ TitleGameCardApplicationMetadataEntry *cur_gc_app_metadata = &(gc_app_metadata[i]);
- /* Information about how to handle user titles. */
- brls::Label *user_titles_info = new brls::Label(brls::LabelStyle::DESCRIPTION, i18n::getStr("gamecard_tab/list/user_titles/info"_i18n, \
- "root_view/tabs/user_titles"_i18n), true);
- user_titles_info->setHorizontalAlign(NVG_ALIGN_CENTER);
- this->list->addView(user_titles_info);
+ /* Create item. */
+ TitlesTabItem *title = new TitlesTabItem(cur_gc_app_metadata->app_metadata, false, false);
- /* Populate list. */
- for(u32 i = 0; i < gc_app_metadata_count; i++)
+ /* Unregister A button action. */
+ title->unregisterAction(brls::Key::A);
+
+ /* Set version information as the item sublabel instead of the title author. */
+ std::string sublabel = fmt::format("v{}", cur_gc_app_metadata->version.value);
+
+ if (cur_gc_app_metadata->display_version[0]) sublabel += fmt::format(" ({})", cur_gc_app_metadata->display_version);
+
+ if (cur_gc_app_metadata->dlc_count > 1)
{
- TitleGameCardApplicationMetadataEntry *cur_gc_app_metadata = &(gc_app_metadata[i]);
-
- /* Create item. */
- TitlesTabItem *title = new TitlesTabItem(cur_gc_app_metadata->app_metadata, false, false);
-
- /* Unregister A button action. */
- title->unregisterAction(brls::Key::A);
-
- /* Set version information as the item sublabel instead of the title author. */
- std::string sublabel{};
- if (cur_gc_app_metadata->display_version[0])
- {
- sublabel = fmt::format("v{} ({})", cur_gc_app_metadata->version.value, cur_gc_app_metadata->display_version);
- } else {
- sublabel = fmt::format("v{}", cur_gc_app_metadata->version.value);
- }
-
- title->setSubLabel(sublabel);
-
- /* Add view to item list. */
- this->list->addView(title);
+ sublabel += fmt::format(" (+{} DLCs)", cur_gc_app_metadata->dlc_count);
+ } else
+ if (cur_gc_app_metadata->dlc_count == 1)
+ {
+ sublabel += " (+1 DLC)";
}
- /* Free gamecard application metadata array. */
- free(gc_app_metadata);
+ title->setSubLabel(sublabel);
+
+ /* Add view to item list. */
+ this->list->addView(title);
}
+ }
+
+ void GameCardTab::AddPropertiesTable(void)
+ {
+ GameCardHeader card_header{};
+ GameCardInfo card_info{};
+ FsGameCardIdSet card_id_set_data{};
+
+ /* Get gamecard data. */
+ gamecardGetHeader(&card_header);
+ gamecardGetPlaintextCardInfoArea(&card_info);
+ gamecardGetCardIdSet(&card_id_set_data);
/* Populate gamecard properties table. */
this->list->addView(new brls::Header("gamecard_tab/list/properties_table/header"_i18n));
FocusableTable *properties_table = new FocusableTable(true, false);
- brls::TableRow *capacity = properties_table->addRow(brls::TableRowType::BODY, "gamecard_tab/list/properties_table/capacity"_i18n);
- brls::TableRow *total_size = properties_table->addRow(brls::TableRowType::BODY, "gamecard_tab/list/properties_table/total_size"_i18n);
- brls::TableRow *trimmed_size = properties_table->addRow(brls::TableRowType::BODY, "gamecard_tab/list/properties_table/trimmed_size"_i18n);
- brls::TableRow *update_version = properties_table->addRow(brls::TableRowType::BODY, "gamecard_tab/list/properties_table/update_version"_i18n);
- brls::TableRow *lafw_version = properties_table->addRow(brls::TableRowType::BODY, "gamecard_tab/list/properties_table/lafw_version"_i18n);
- brls::TableRow *sdk_version = properties_table->addRow(brls::TableRowType::BODY, "gamecard_tab/list/properties_table/sdk_version"_i18n);
- brls::TableRow *compatibility_type = properties_table->addRow(brls::TableRowType::BODY, "gamecard_tab/list/properties_table/compatibility_type"_i18n);
- brls::TableRow *package_id = properties_table->addRow(brls::TableRowType::BODY, "gamecard_tab/list/properties_table/package_id"_i18n);
- brls::TableRow *card_id_set_row = properties_table->addRow(brls::TableRowType::BODY, "gamecard_tab/list/properties_table/card_id_set"_i18n);
+ GAMECARD_TAB_TABLE_PROPERTY(capacity);
+ GAMECARD_TAB_TABLE_PROPERTY(total_size);
+ GAMECARD_TAB_TABLE_PROPERTY(trimmed_size);
+ GAMECARD_TAB_TABLE_PROPERTY(update_version);
+ GAMECARD_TAB_TABLE_PROPERTY(lafw_version);
+ GAMECARD_TAB_TABLE_PROPERTY(sdk_version);
+ GAMECARD_TAB_TABLE_PROPERTY(compatibility_type);
+ GAMECARD_TAB_TABLE_PROPERTY(package_id);
+ GAMECARD_TAB_TABLE_PROPERTY(card_id_set);
+ /* Set table row values. */
capacity->setValue(this->GetFormattedSizeString(&gamecardGetRomCapacity));
total_size->setValue(this->GetFormattedSizeString(&gamecardGetTotalSize));
trimmed_size->setValue(this->GetFormattedSizeString(&gamecardGetTrimmedSize));
- gamecardGetHeader(&card_header);
- gamecardGetPlaintextCardInfoArea(&card_info);
- gamecardGetCardIdSet(&card_id_set);
-
const SystemVersion upp_version = card_info.upp_version.system_version;
- /* TODO: move somewhere else? */
if (upp_version.major == 0 && upp_version.minor == 0)
{
- std::string upp_version_display = "";
+ /* Nintendo didn't start matching SystemVersion fields to the system version displayed in the Settings menu until HOS 3.0.0. */
+ /* So we need to manually handle those exceptions. */
+ std::string upp_version_display{};
switch(upp_version.micro)
{
@@ -228,38 +266,39 @@ namespace nxdt::views
if (upp_version_display != "")
{
- update_version->setValue(fmt::format("{} ({}.{}.{}-{}) (v{})", upp_version_display, upp_version.major, upp_version.minor, upp_version.micro, \
+ update_version->setValue(fmt::format("{} ({}.{}.{}-{}) (v{})", upp_version_display, upp_version.major, upp_version.minor, upp_version.micro,
upp_version.relstep, upp_version.value));
} else {
- update_version->setValue(fmt::format("{}.{}.{}-{} (v{})", upp_version.major, upp_version.minor, upp_version.micro, \
+ update_version->setValue(fmt::format("{}.{}.{}-{} (v{})", upp_version.major, upp_version.minor, upp_version.micro,
upp_version.relstep, upp_version.value));
}
} else {
- update_version->setValue(fmt::format("{}.{}.{}-{}.{} (v{})", upp_version.major, upp_version.minor, upp_version.micro, \
+ update_version->setValue(fmt::format("{}.{}.{}-{}.{} (v{})", upp_version.major, upp_version.minor, upp_version.micro,
upp_version.major_relstep, upp_version.minor_relstep, upp_version.value));
}
- u64 fw_version = card_info.fw_version;
+ const u64 fw_version = card_info.fw_version;
lafw_version->setValue(fmt::format("{} ({})", fw_version, fw_version >= GameCardFwVersion_Count ? "generic/unknown"_i18n : gamecardGetRequiredHosVersionString(fw_version)));
const SdkAddOnVersion fw_mode = card_info.fw_mode.sdk_addon_version;
sdk_version->setValue(fmt::format("{}.{}.{}-{} (v{})", fw_mode.major, fw_mode.minor, fw_mode.micro, fw_mode.relstep, fw_mode.value));
u8 compat_type = card_info.compatibility_type;
- compatibility_type->setValue(fmt::format("{} ({})", \
- compat_type >= GameCardCompatibilityType_Count ? "generic/unknown"_i18n : gamecardGetCompatibilityTypeString(compat_type), \
- compat_type));
+ compatibility_type->setValue(fmt::format("{} ({})",
+ compat_type >= GameCardCompatibilityType_Count ? "generic/unknown"_i18n : gamecardGetCompatibilityTypeString(compat_type), compat_type));
char package_id_str[0x11] = {0};
utilsGenerateHexString(package_id_str, sizeof(package_id_str), card_header.package_id, sizeof(card_header.package_id), true);
package_id->setValue(std::string(package_id_str));
- card_id_set_row->setValue(this->GetCardIdSetString(&card_id_set));
+ card_id_set->setValue(this->GetCardIdSetString(card_id_set_data));
this->list->addView(properties_table);
+ }
- /* ListItem elements. */
- this->list->addView(new brls::Header("gamecard_tab/list/dump_options"_i18n));
+ void GameCardTab::GenerateRawFilenames(void)
+ {
+ char *raw_filename = nullptr;
raw_filename = titleGenerateGameCardFileName(TitleNamingConvention_Full, TitleFileNameIllegalCharReplaceType_None);
this->raw_filename_full = std::string(raw_filename);
@@ -270,58 +309,31 @@ namespace nxdt::views
if (raw_filename) free(raw_filename);
raw_filename = nullptr;
+ }
- brls::ListItem *dump_card_image = new brls::ListItem("gamecard_tab/list/dump_card_image/label"_i18n, "gamecard_tab/list/dump_card_image/description"_i18n);
+ std::string GameCardTab::GetFormattedSizeString(GameCardSizeFunc func)
+ {
+ u64 size = 0;
+ char strbuf[0x40] = {0};
- dump_card_image->getClickEvent()->subscribe([this](brls::View *view) {
- /* Display gamecard image dump options. */
- std::string& raw_filename = (configGetInteger("naming_convention") == TitleNamingConvention_Full ? raw_filename_full : raw_filename_id_only);
- brls::Application::pushView(new GameCardImageDumpOptionsFrame(this->root_view, raw_filename), brls::ViewAnimation::SLIDE_LEFT);
- });
+ func(&size);
+ utilsGenerateFormattedSizeString(static_cast