nn_boss: Reimplementation

This is a full rewrite of our nn_boss (SpotPass) implementation. The previous code was based on a lot of incorrect guesswork so rather than updating that it made more sense to redo it all.

In short what changed:
- More API implemented than before, but nn_boss is very complex so we are still missing stuff (e.g. PlayReports and Task scheduling)
- Avoids redownloading nbdl files if they are already present locally (matches IOSU behavior)
- The API should be more robust in general and file hashes are now verified
- Emulated IOSU interface is compatible with nn_boss.rpl
- Added an UI option to clear the SpotPass cache
This commit is contained in:
Exzap 2025-06-14 12:59:30 +02:00
parent 3f6974fc95
commit 4fa0df6dcf
24 changed files with 3232 additions and 2223 deletions

View file

@ -7,12 +7,23 @@ template <size_t N>
class CafeString // fixed buffer size, null-terminated, PPC char
{
public:
constexpr static size_t Size()
{
return N;
}
// checks whether the string and a null terminator can fit into the buffer
bool CanHoldString(std::string_view sv) const
{
return sv.size() < N;
}
bool assign(std::string_view sv)
{
if (sv.size()+1 >= N)
if (sv.size() >= N)
{
memcpy(data, sv.data(), sv.size()-1);
data[sv.size()-1] = '\0';
memcpy(data, sv.data(), N-1);
data[N-1] = '\0';
return false;
}
memcpy(data, sv.data(), sv.size());
@ -20,11 +31,50 @@ class CafeString // fixed buffer size, null-terminated, PPC char
return true;
}
const char* c_str()
void Copy(CafeString<N>& other)
{
memcpy(data, other.data, N);
}
bool empty() const
{
return data[0] == '\0';
}
const char* c_str() const
{
return (const char*)data;
}
void ClearAllBytes()
{
memset(data, 0, N);
}
auto operator<=>(const CafeString<N>& other) const
{
for (size_t i = 0; i < N; i++)
{
if (data[i] != other.data[i])
return data[i] <=> other.data[i];
if (data[i] == '\0')
return std::strong_ordering::equal;
}
return std::strong_ordering::equal;
}
bool operator==(const CafeString<N>& other) const
{
for (size_t i = 0; i < N; i++)
{
if (data[i] != other.data[i])
return false;
if (data[i] == '\0')
return true;
}
return true;
}
uint8be data[N];
};