diff --git a/src/RPXLoading.cpp b/src/RPXLoading.cpp index 4d64fb4..8c4f37c 100644 --- a/src/RPXLoading.cpp +++ b/src/RPXLoading.cpp @@ -16,13 +16,10 @@ #include std::mutex fileReaderListMutex; -std::vector openFileReaders; +std::forward_list> openFileReaders; void RPXLoadingCleanUp() { const std::lock_guard lock(fileReaderListMutex); - for (auto &reader : openFileReaders) { - delete reader; - } openFileReaders.clear(); } @@ -46,18 +43,18 @@ DECL_FUNCTION(int32_t, HBM_NN_ACP_ACPGetTitleMetaXmlByDevice, uint32_t titleid_u return result; } -DECL_FUNCTION(int, RPX_FSOpenFile, FSClient *client, FSCmdBlock *block, char *path, const char *mode, int *handle, int error) { +DECL_FUNCTION(int, RPX_FSOpenFile, FSClient *client, FSCmdBlock *block, char *path, const char *mode, uint32_t *handle, int error) { const char *iconTex = "iconTex.tga"; std::string_view pathView = path; if (gReplacementInfo.rpxReplacementInfo.isRPXReplaced && pathView.ends_with(iconTex)) { const std::lock_guard lock(fileReaderListMutex); - auto *reader = new (std::nothrow) FileReader(reinterpret_cast(gReplacementInfo.rpxReplacementInfo.iconCache), ICON_SIZE); + auto reader = make_unique_nothrow(reinterpret_cast(gReplacementInfo.rpxReplacementInfo.iconCache), ICON_SIZE); if (!reader) { DEBUG_FUNCTION_LINE_ERR("Failed to allocate memory for the FileReader"); return FS_STATUS_FATAL_ERROR; } - openFileReaders.push_back(reader); - *handle = reinterpret_cast(reader); + *handle = reader->getHandle(); + openFileReaders.push_front(std::move(reader)); return FS_STATUS_OK; } int result = real_RPX_FSOpenFile(client, block, path, mode, handle, error); @@ -68,7 +65,7 @@ DECL_FUNCTION(FSStatus, RPX_FSReadFile, FSClient *client, FSCmdBlock *block, uin if (gReplacementInfo.rpxReplacementInfo.isRPXReplaced) { const std::lock_guard lock(fileReaderListMutex); for (auto &reader : openFileReaders) { - if ((uint32_t) reader == (uint32_t) handle) { + if ((uint32_t) reader->getHandle() == (uint32_t) handle) { return (FSStatus) (reader->read(buffer, size * count) / size); } } @@ -78,21 +75,7 @@ DECL_FUNCTION(FSStatus, RPX_FSReadFile, FSClient *client, FSCmdBlock *block, uin DECL_FUNCTION(FSStatus, RPX_FSCloseFile, FSClient *client, FSCmdBlock *block, FSFileHandle handle, uint32_t flags) { if (gReplacementInfo.rpxReplacementInfo.isRPXReplaced) { - const std::lock_guard lock(fileReaderListMutex); - bool found = false; - int index = 0; - FileReader *reader = nullptr; - for (auto &cur : openFileReaders) { - if ((uint32_t) cur == (uint32_t) handle) { - found = true; - reader = cur; - break; - } - index++; - } - if (found) { - openFileReaders.erase(openFileReaders.begin() + index); - delete reader; + if (remove_locked_first_if(fileReaderListMutex, openFileReaders, [handle](auto &cur) { return cur->getHandle() == (uint32_t) handle; })) { return FS_STATUS_OK; } } diff --git a/src/utils/FileReader.h b/src/utils/FileReader.h index 0af542b..bfe541e 100644 --- a/src/utils/FileReader.h +++ b/src/utils/FileReader.h @@ -17,6 +17,10 @@ public: virtual int64_t read(uint8_t *buffer, uint32_t size); + uint32_t getHandle() { + return (uint32_t) this; + } + private: bool isReadFromBuffer = false; uint8_t *input_buffer = nullptr; diff --git a/src/utils/utils.h b/src/utils/utils.h index e4b9b5e..d8b796f 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -1,38 +1,35 @@ #pragma once +#include +#include #include +#include +#include -#ifdef __cplusplus -extern "C" { -#endif +template +std::unique_ptr make_unique_nothrow(Args &&...args) noexcept(noexcept(T(std::forward(args)...))) { + return std::unique_ptr(new (std::nothrow) T(std::forward(args)...)); +} -#define LIMIT(x, min, max) \ - ({ \ - typeof(x) _x = x; \ - typeof(min) _min = min; \ - typeof(max) _max = max; \ - (((_x) < (_min)) ? (_min) : ((_x) > (_max)) ? (_max) \ - : (_x)); \ - }) +template +std::shared_ptr make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std::forward(args)...))) { + return std::shared_ptr(new (std::nothrow) T(std::forward(args)...)); +} -#define DegToRad(a) ((a) *0.01745329252f) -#define RadToDeg(a) ((a) *57.29577951f) - -#define ALIGN4(x) (((x) + 3) & ~3) -#define ALIGN32(x) (((x) + 31) & ~31) +template +bool remove_locked_first_if(std::mutex &mutex, std::forward_list &list, Predicate pred) { + std::lock_guard lock(mutex); + auto oit = list.before_begin(), it = std::next(oit); + while (it != list.end()) { + if (pred(*it)) { + list.erase_after(oit); + return true; + } + oit = it++; + } + return false; +} // those work only in powers of 2 #define ROUNDDOWN(val, align) ((val) & ~(align - 1)) -#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align - 1)), align) - - -#define le16(i) ((((uint16_t) ((i) &0xFF)) << 8) | ((uint16_t) (((i) &0xFF00) >> 8))) -#define le32(i) ((((uint32_t) le16((i) &0xFFFF)) << 16) | ((uint32_t) le16(((i) &0xFFFF0000) >> 16))) -#define le64(i) ((((uint64_t) le32((i) &0xFFFFFFFFLL)) << 32) | ((uint64_t) le32(((i) &0xFFFFFFFF00000000LL) >> 32))) - -//Needs to have log_init() called beforehand. -void dumpHex(const void *data, size_t size); - -#ifdef __cplusplus -} -#endif \ No newline at end of file +#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align - 1)), align) \ No newline at end of file