Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various small changes #1343

Merged
merged 16 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ if (ENABLE_CUBEB)
option(BUILD_TOOLS "" OFF)
option(BUNDLE_SPEEX "" OFF)
set(USE_WINMM OFF CACHE BOOL "")
add_subdirectory("dependencies/cubeb" EXCLUDE_FROM_ALL)
add_subdirectory("dependencies/cubeb" EXCLUDE_FROM_ALL SYSTEM)
set_property(TARGET cubeb PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
add_library(cubeb::cubeb ALIAS cubeb)
endif()
Expand Down
4 changes: 2 additions & 2 deletions src/Cafe/OS/libs/nn_olv/nn_olv_OfflineDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ namespace nn

nnResult _Async_OfflineDB_DownloadPostDataListParam_DownloadPostDataList(coreinit::OSEvent* event, DownloadedTopicData* downloadedTopicData, DownloadedPostData* downloadedPostData, uint32be* postCountOut, uint32 maxCount, DownloadPostDataListParam* param)
{
scope_exit _se([&](){coreinit::OSSignalEvent(event);});
stdx::scope_exit _se([&](){coreinit::OSSignalEvent(event);});

uint64 titleId = CafeSystem::GetForegroundTitleId();

Expand Down Expand Up @@ -184,7 +184,7 @@ namespace nn

nnResult _Async_OfflineDB_DownloadPostDataListParam_DownloadExternalImageData(coreinit::OSEvent* event, DownloadedDataBase* _this, void* imageDataOut, uint32be* imageSizeOut, uint32 maxSize)
{
scope_exit _se([&](){coreinit::OSSignalEvent(event);});
stdx::scope_exit _se([&](){coreinit::OSSignalEvent(event);});

if (!_this->TestFlags(_this, DownloadedDataBase::FLAGS::HAS_EXTERNAL_IMAGE))
return OLV_RESULT_MISSING_DATA;
Expand Down
6 changes: 1 addition & 5 deletions src/Cafe/OS/libs/nsyshid/Infinity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1017,11 +1017,7 @@ namespace nsyshid
std::array<uint8, 16> InfinityUSB::GenerateInfinityFigureKey(const std::vector<uint8>& sha1Data)
{
std::array<uint8, 20> digest = {};
SHA_CTX ctx;
SHA1_Init(&ctx);
SHA1_Update(&ctx, sha1Data.data(), sha1Data.size());
SHA1_Final(digest.data(), &ctx);
OPENSSL_cleanse(&ctx, sizeof(ctx));
SHA1(sha1Data.data(), sha1Data.size(), digest.data());
// Infinity AES keys are the first 16 bytes of the SHA1 Digest, every set of 4 bytes need to be
// reversed due to endianness
std::array<uint8, 16> key = {};
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/OS/libs/ntag/ntag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ namespace ntag
noftHeader->writeCount = _swapEndianU16(_swapEndianU16(noftHeader->writeCount) + 1);
}

memcpy(decryptedBuffer + 0x20, noftHeader, sizeof(noftHeader));
memcpy(decryptedBuffer + 0x20, noftHeader, sizeof(NTAGNoftHeader));
memcpy(decryptedBuffer + _swapEndianU16(rwHeader->offset), data, dataSize);

// Encrypt
Expand Down
8 changes: 4 additions & 4 deletions src/Cafe/OS/libs/snd_core/ax_out.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,10 +522,10 @@ namespace snd_core
// called periodically to check for AX updates
void AXOut_update()
{
constexpr auto kTimeout = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds(((IAudioAPI::kBlockCount * 3) / 4) * (AX_FRAMES_PER_GROUP * 3)));
constexpr auto kWaitDuration = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds(3));
constexpr auto kWaitDurationFast = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::microseconds(2900));
constexpr auto kWaitDurationMinimum = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::microseconds(1700));
constexpr static auto kTimeout = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds(((IAudioAPI::kBlockCount * 3) / 4) * (AX_FRAMES_PER_GROUP * 3)));
constexpr static auto kWaitDuration = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds(3));
constexpr static auto kWaitDurationFast = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::microseconds(2900));
constexpr static auto kWaitDurationMinimum = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::microseconds(1700));

// if we haven't buffered any blocks, we will wait less time than usual
bool additional_blocks_required = false;
Expand Down
160 changes: 99 additions & 61 deletions src/Common/MemPtr.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

using MPTR = uint32; // generic address in PowerPC memory space

#define MPTR_NULL (0)
#define MPTR_NULL (0)

using VAddr = uint32; // virtual address
using PAddr = uint32; // physical address
Expand All @@ -14,137 +14,175 @@ extern uint8* PPCInterpreterGetStackPointer();
extern uint8* PPCInterpreter_PushAndReturnStackPointer(sint32 offset);
extern void PPCInterpreterModifyStackPointer(sint32 offset);

class MEMPTRBase {};
class MEMPTRBase
{
};

template <typename T>
template<typename T>
class MEMPTR : MEMPTRBase
{
public:
constexpr MEMPTR()
: m_value(0) { }
public:
constexpr MEMPTR() noexcept
: m_value(0) {}

explicit constexpr MEMPTR(uint32 offset)
: m_value(offset) { }
explicit constexpr MEMPTR(uint32 offset) noexcept
: m_value(offset) {}

explicit constexpr MEMPTR(const uint32be& offset)
: m_value(offset) { }
explicit constexpr MEMPTR(const uint32be& offset) noexcept
: m_value(offset) {}

constexpr MEMPTR(std::nullptr_t)
: m_value(0) { }
constexpr MEMPTR(std::nullptr_t) noexcept
: m_value(0) {}

MEMPTR(T* ptr)
MEMPTR(T* ptr) noexcept
{
if (ptr == nullptr)
m_value = 0;
else
{
cemu_assert_debug((uint8*)ptr >= memory_base && (uint8*)ptr <= memory_base + 0x100000000);
m_value = (uint32)((uintptr_t)ptr - (uintptr_t)memory_base);
}
{
cemu_assert_debug((uint8*)ptr >= memory_base && (uint8*)ptr <= memory_base + 0x100000000);
m_value = (uint32)((uintptr_t)ptr - (uintptr_t)memory_base);
}
}

constexpr MEMPTR(const MEMPTR& memptr)
: m_value(memptr.m_value) { }
constexpr MEMPTR(const MEMPTR&) noexcept = default;

constexpr MEMPTR& operator=(const MEMPTR& memptr)
{
m_value = memptr.m_value;
return *this;
}
constexpr MEMPTR& operator=(const MEMPTR&) noexcept = default;

constexpr MEMPTR& operator=(const uint32& offset)
constexpr MEMPTR& operator=(const uint32& offset) noexcept
{
m_value = offset;
return *this;
}

constexpr MEMPTR& operator=(const std::nullptr_t rhs)
constexpr MEMPTR& operator=(std::nullptr_t) noexcept
{
m_value = 0;
return *this;
}

MEMPTR& operator=(T* ptr)
MEMPTR& operator=(T* ptr) noexcept
{
if (ptr == nullptr)
if (ptr == nullptr)
m_value = 0;
else
{
cemu_assert_debug((uint8*)ptr >= memory_base && (uint8*)ptr <= memory_base + 0x100000000);
m_value = (uint32)((uintptr_t)ptr - (uintptr_t)memory_base);
}
{
cemu_assert_debug((uint8*)ptr >= memory_base && (uint8*)ptr <= memory_base + 0x100000000);
m_value = (uint32)((uintptr_t)ptr - (uintptr_t)memory_base);
}
return *this;
}

bool atomic_compare_exchange(T* comparePtr, T* newPtr)
bool atomic_compare_exchange(T* comparePtr, T* newPtr) noexcept
{
MEMPTR<T> mp_compare = comparePtr;
MEMPTR<T> mp_new = newPtr;
std::atomic<uint32be>* thisValueAtomic = (std::atomic<uint32be>*)&m_value;
auto* thisValueAtomic = reinterpret_cast<std::atomic<uint32be>*>(&m_value);
return thisValueAtomic->compare_exchange_strong(mp_compare.m_value, mp_new.m_value);
}

explicit constexpr operator bool() const noexcept { return m_value != 0; }

constexpr operator T*() const noexcept { return GetPtr(); } // allow implicit cast to wrapped pointer type
explicit constexpr operator bool() const noexcept
{
return m_value != 0;
}

// allow implicit cast to wrapped pointer type
constexpr operator T*() const noexcept
{
return GetPtr();
}

template <typename X>
explicit operator MEMPTR<X>() const { return MEMPTR<X>(this->m_value); }
template<typename X>
explicit operator MEMPTR<X>() const noexcept
{
return MEMPTR<X>(this->m_value);
}

MEMPTR operator+(const MEMPTR& ptr) { return MEMPTR(this->GetMPTR() + ptr.GetMPTR()); }
MEMPTR operator-(const MEMPTR& ptr) { return MEMPTR(this->GetMPTR() - ptr.GetMPTR()); }
MEMPTR operator+(const MEMPTR& ptr) noexcept
{
return MEMPTR(this->GetMPTR() + ptr.GetMPTR());
}
MEMPTR operator-(const MEMPTR& ptr) noexcept
{
return MEMPTR(this->GetMPTR() - ptr.GetMPTR());
}

MEMPTR operator+(sint32 v)
MEMPTR operator+(sint32 v) noexcept
{
// pointer arithmetic
return MEMPTR(this->GetMPTR() + v * 4);
}

MEMPTR operator-(sint32 v)
MEMPTR operator-(sint32 v) noexcept
{
// pointer arithmetic
return MEMPTR(this->GetMPTR() - v * 4);
}

MEMPTR& operator+=(sint32 v)
MEMPTR& operator+=(sint32 v) noexcept
{
m_value += v * sizeof(T);
return *this;
}

template <class Q = T>
typename std::enable_if<!std::is_same<Q, void>::value, Q>::type&
operator*() const { return *GetPtr(); }
template<typename Q = T>
std::enable_if_t<!std::is_same_v<Q, void>, Q>& operator*() const noexcept
{
return *GetPtr();
}

T* operator->() const { return GetPtr(); }
constexpr T* operator->() const noexcept
{
return GetPtr();
}

template <class Q = T>
typename std::enable_if<!std::is_same<Q, void>::value, Q>::type&
operator[](int index) { return GetPtr()[index]; }
template<typename Q = T>
std::enable_if_t<!std::is_same_v<Q, void>, Q>& operator[](int index) noexcept
{
return GetPtr()[index];
}

T* GetPtr() const { return (T*)(m_value == 0 ? nullptr : memory_base + (uint32)m_value); }
T* GetPtr() const noexcept
{
return (T*)(m_value == 0 ? nullptr : memory_base + (uint32)m_value);
}

template <typename C>
C* GetPtr() const { return (C*)(GetPtr()); }
template<typename C>
C* GetPtr() const noexcept
{
return static_cast<C*>(GetPtr());
}

constexpr uint32 GetMPTR() const { return m_value.value(); }
constexpr const uint32be& GetBEValue() const { return m_value; }
[[nodiscard]] constexpr uint32 GetMPTR() const noexcept
{
return m_value.value();
}
[[nodiscard]] constexpr const uint32be& GetBEValue() const noexcept
{
return m_value;
}

constexpr bool IsNull() const { return m_value == 0; }
[[nodiscard]] constexpr bool IsNull() const noexcept
{
return m_value == 0;
}

private:
private:
uint32be m_value;
};

static_assert(sizeof(MEMPTR<void*>) == sizeof(uint32be));
static_assert(std::is_trivially_copyable_v<MEMPTR<void*>>);

#include "StackAllocator.h"
#include "SysAllocator.h"

template <typename T>
template<typename T>
struct fmt::formatter<MEMPTR<T>> : formatter<string_view>
{
template <typename FormatContext>
auto format(const MEMPTR<T>& v, FormatContext& ctx) const -> format_context::iterator { return fmt::format_to(ctx.out(), "{:#x}", v.GetMPTR()); }
template<typename FormatContext>
auto format(const MEMPTR<T>& v, FormatContext& ctx) const -> format_context::iterator
{
return fmt::format_to(ctx.out(), "{:#x}", v.GetMPTR());
}
};
48 changes: 29 additions & 19 deletions src/Common/precompiled.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,16 +394,10 @@ void vectorRemoveByIndex(std::vector<T>& vec, const size_t index)
vec.erase(vec.begin() + index);
}

template<typename T1, typename T2>
int match_any_of(T1 value, T2 compareTo)
template<typename T1, typename... Types>
bool match_any_of(T1&& value, Types&&... others)
{
return value == compareTo;
}

template<typename T1, typename T2, typename... Types>
bool match_any_of(T1 value, T2 compareTo, Types&&... others)
{
return value == compareTo || match_any_of(value, others...);
return ((value == others) || ...);
}

// we cache the frequency in a static variable
Expand Down Expand Up @@ -501,20 +495,15 @@ bool future_is_ready(std::future<T>& f)
#endif
}

// replace with std::scope_exit once available
struct scope_exit
{
std::function<void()> f_;
explicit scope_exit(std::function<void()> f) noexcept : f_(std::move(f)) {}
~scope_exit() { if (f_) f_(); }
};

// helper function to cast raw pointers to std::atomic
// this is technically not legal but works on most platforms as long as alignment restrictions are met and the implementation of atomic doesnt come with additional members

template<typename T>
std::atomic<T>* _rawPtrToAtomic(T* ptr)
{
static_assert(sizeof(T) == sizeof(std::atomic<T>));
cemu_assert_debug((reinterpret_cast<std::uintptr_t>(ptr) % alignof(std::atomic<T>)) == 0);
return reinterpret_cast<std::atomic<T>*>(ptr);
}

Expand Down Expand Up @@ -578,13 +567,34 @@ struct fmt::formatter<betype<T>> : fmt::formatter<T>
}
};

// useful C++23 stuff that isn't yet widely supported

// std::to_underlying
// useful future C++ stuff
namespace stdx
{
// std::to_underlying
template <typename EnumT, typename = std::enable_if_t < std::is_enum<EnumT>{} >>
constexpr std::underlying_type_t<EnumT> to_underlying(EnumT e) noexcept {
return static_cast<std::underlying_type_t<EnumT>>(e);
};

// std::scope_exit
template <typename Fn>
class scope_exit
{
Fn m_func;
bool m_released = false;
public:
explicit scope_exit(Fn&& f) noexcept
: m_func(std::forward<Fn>(f))
{}
~scope_exit()
{
if (!m_released) m_func();
}
scope_exit(scope_exit&& other) noexcept
: m_func(std::move(other.m_func)), m_released(std::exchange(other.m_released, true))
{}
scope_exit(const scope_exit&) = delete;
scope_exit& operator=(scope_exit) = delete;
void release() { m_released = true;}
};
}
Loading
Loading