diff --git a/include/controller/nin/seadNinJoyNpadDevice.h b/include/controller/nin/seadNinJoyNpadDevice.h index 22b7066a..88f18d90 100644 --- a/include/controller/nin/seadNinJoyNpadDevice.h +++ b/include/controller/nin/seadNinJoyNpadDevice.h @@ -31,7 +31,11 @@ class NinJoyNpadDevice : public ControlDevice CriticalSection mCS; }; +#if SEAD_HOSTIO_NONVIRTUAL + static_assert(sizeof(VibrationThread) == 0x290); +#else static_assert(sizeof(VibrationThread) == 0x298); +#endif struct SixAxisState { diff --git a/include/hostio/seadHostIONode.h b/include/hostio/seadHostIONode.h index b3edc0c8..8b61beb1 100644 --- a/include/hostio/seadHostIONode.h +++ b/include/hostio/seadHostIONode.h @@ -8,7 +8,9 @@ namespace sead::hostio class Node : public Reflexible { public: +#if not SEAD_HOSTIO_NONVIRTUAL NodeClassType getNodeClassType() const override { return Reflexible::NodeClassType::Node; } +#endif #ifdef SEAD_DEBUG public: diff --git a/include/hostio/seadHostIOReflexible.h b/include/hostio/seadHostIOReflexible.h index bbb77f14..aa06946e 100644 --- a/include/hostio/seadHostIOReflexible.h +++ b/include/hostio/seadHostIOReflexible.h @@ -26,7 +26,9 @@ class Reflexible : public NodeEventListener Other = 2, }; +#if not SEAD_HOSTIO_NONVIRTUAL virtual NodeClassType getNodeClassType() const { return NodeClassType::Reflexible; } +#endif enum class AllocFlg { diff --git a/include/seadVersion.h b/include/seadVersion.h index 4d0cc607..e485907c 100644 --- a/include/seadVersion.h +++ b/include/seadVersion.h @@ -5,6 +5,7 @@ #define SEAD_VERSION_SPL3 3 #define SEAD_VERSION_TOTK 4 #define SEAD_VERSION_SMBW 5 +#define SEAD_VERSION_SMM2 6 #define SEAD_VERSION_CUSTOM 0 #ifndef SEAD_VERSION @@ -39,6 +40,12 @@ /// Make most functions in sead::ArchiveRes const /// SEAD_HASHCRC_WITHCONTEXT: /// Add calcHashWithContext and calcStringHashWithContext to HashCRC16/32 +/// SEAD_HOSTIO_NONVIRTUAL: +/// Removes getNodeClassType() and the vtable from hostio::Reflexible and ::Node +/// SEAD_FINDCONTAINHEAPCACHE_FIXED: +/// Fixes two bugs on FindContainHeapCache (incomplete locks and 64-bit pointers) +/// SEAD_THREAD_SETAFFINITY_RELOAD: +/// Store new affinity into member, then reload instead of reusing parameter #if SEAD_VERSION == SEAD_VERSION_BOTW #define SEAD_SAFESTRING_NONVIRTUAL 0 @@ -54,6 +61,9 @@ #define SEAD_ARCHIVERES_ISEXISTFILEIMPL 1 #define SEAD_ARCHIVERES_ISCONST 1 #define SEAD_HASHCRC_WITHCONTEXT 1 +#define SEAD_HOSTIO_NONVIRTUAL 0 +#define SEAD_FINDCONTAINHEAPCACHE_FIXED 0 +#define SEAD_THREAD_SETAFFINITY_RELOAD 1 #elif SEAD_VERSION == SEAD_VERSION_SMO #define SEAD_SAFESTRING_NONVIRTUAL 0 #define SEAD_RESOURCEMGR_TRYCREATE_NO_FACTORY_NAME 0 @@ -68,6 +78,9 @@ #define SEAD_ARCHIVERES_ISEXISTFILEIMPL 0 #define SEAD_ARCHIVERES_ISCONST 0 #define SEAD_HASHCRC_WITHCONTEXT 0 +#define SEAD_HOSTIO_NONVIRTUAL 0 +#define SEAD_FINDCONTAINHEAPCACHE_FIXED 0 +#define SEAD_THREAD_SETAFFINITY_RELOAD 1 #elif SEAD_VERSION == SEAD_VERSION_SPL3 or SEAD_VERSION == SEAD_VERSION_TOTK or \ SEAD_VERSION == SEAD_VERSION_SMBW #define SEAD_SAFESTRING_NONVIRTUAL 1 @@ -83,6 +96,26 @@ #define SEAD_ARCHIVERES_ISEXISTFILEIMPL 1 #define SEAD_ARCHIVERES_ISCONST 1 #define SEAD_HASHCRC_WITHCONTEXT 1 +#define SEAD_HOSTIO_NONVIRTUAL 0 +#define SEAD_FINDCONTAINHEAPCACHE_FIXED 0 +#define SEAD_THREAD_SETAFFINITY_RELOAD 1 +#elif SEAD_VERSION == SEAD_VERSION_SMM2 +#define SEAD_SAFESTRING_NONVIRTUAL 0 // TODO: figure this out +#define SEAD_RESOURCEMGR_TRYCREATE_NO_FACTORY_NAME 0 // TODO: figure this out +#define SEAD_CRITICALSECTION_PURE 0 +#define SEAD_THREADMGR_MOVED_SINGLETON_DISPOSER 0 // TODO: figure this out +#define SEAD_HEAP_FREEANDGETALLOCATABLESIZE_VIRTUAL 0 // TODO: figure this out +#define SEAD_RTTI_CHECKDERIVEDRUNTIMETYPEINFO_RETURNS_INSTANCE 0 // TODO: figure this out +#define SEAD_THREAD_GETFIBER 0 // TODO: figure this out +#define SEAD_DELEGATE_ISNODUMMY 1 // TODO: figure this out +#define SEAD_FRAMEBUFFER_BINDCLEAR_UNBIND 0 // TODO: figure this out +#define SEAD_ARCHIVERES_TRYGETFILEPATH 0 // TODO: figure this out +#define SEAD_ARCHIVERES_ISEXISTFILEIMPL 1 // TODO: figure this out +#define SEAD_ARCHIVERES_ISCONST 1 // TODO: figure this out +#define SEAD_HASHCRC_WITHCONTEXT 1 // TODO: figure this out +#define SEAD_HOSTIO_NONVIRTUAL 1 +#define SEAD_FINDCONTAINHEAPCACHE_FIXED 1 +#define SEAD_THREAD_SETAFFINITY_RELOAD 0 #endif /// feature-specific macros diff --git a/include/thread/seadThread.h b/include/thread/seadThread.h index c635f19a..2202e71c 100644 --- a/include/thread/seadThread.h +++ b/include/thread/seadThread.h @@ -155,6 +155,22 @@ class ThreadMgr : public hostio::Node CriticalSection* getListCS() { return &mListCS; } +#if SEAD_FINDCONTAINHEAPCACHE_FIXED + bool tryRemoveFromFindContainHeapCache(Heap* heap) + { + ScopedLock lock(getListCS()); + const auto end = mList.end(); + bool found = false; + for (auto it = mList.begin(); it != end; ++it) + { + bool result = !(*it)->getFindContainHeapCache()->tryRemoveHeap(heap); + found |= result; + if (found) + break; + } + return found; + } +#else bool tryRemoveFromFindContainHeapCache(Heap* heap) { const auto end = mList.end(); @@ -169,6 +185,7 @@ class ThreadMgr : public hostio::Node } return found; } +#endif #ifdef SEAD_DEBUG void initHostIO(); diff --git a/modules/src/heap/seadHeapMgr.cpp b/modules/src/heap/seadHeapMgr.cpp index f388a493..3adfdd59 100644 --- a/modules/src/heap/seadHeapMgr.cpp +++ b/modules/src/heap/seadHeapMgr.cpp @@ -195,6 +195,10 @@ bool FindContainHeapCache::tryRemoveHeap(Heap* heap) uintptr_t original; if (mHeap.compareExchange(uintptr_t(heap), 0, &original)) return true; +#if SEAD_FINDCONTAINHEAPCACHE_FIXED + return (original & ~1ul) != uintptr_t(heap); +#else return (original & ~1u) != uintptr_t(heap); +#endif } } // namespace sead diff --git a/modules/src/thread/nin/seadThreadNin.cpp b/modules/src/thread/nin/seadThreadNin.cpp index d80463fc..1f785730 100644 --- a/modules/src/thread/nin/seadThreadNin.cpp +++ b/modules/src/thread/nin/seadThreadNin.cpp @@ -112,8 +112,13 @@ s32 Thread::getPriority() const void Thread::setAffinity(const CoreIdMask& affinity) { +#if SEAD_THREAD_SETAFFINITY_RELOAD mAffinity = affinity; u64 mask = mAffinity; +#else + u64 mask = affinity; + mAffinity = affinity; +#endif const auto available_mask = nn::os::GetThreadAvailableCoreMask(); SEAD_ASSERT_MSG((~u32(available_mask) & mask) == 0, "invalid core mask. ( mask = %ld )", mask); nn::os::SetThreadCoreMask(mThreadInner, -1, mask);