Merge branch 'main' into metal

This commit is contained in:
SamoZ256 2024-08-14 15:17:35 +02:00 committed by GitHub
commit 52062bd285
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 258 additions and 81 deletions

View File

@ -225,7 +225,7 @@ jobs:
run: | run: |
brew update brew update
brew install llvm@15 ninja nasm automake libtool brew install llvm@15 ninja nasm automake libtool
brew install cmake python3 ninja brew install cmake ninja
- name: "Build and install molten-vk" - name: "Build and install molten-vk"
run: | run: |

View File

@ -3,6 +3,8 @@
#include <boost/container/small_vector.hpp> #include <boost/container/small_vector.hpp>
#include "../fsc.h"
// path parser and utility class for Wii U paths // path parser and utility class for Wii U paths
// optimized to be allocation-free for common path lengths // optimized to be allocation-free for common path lengths
class FSCPath class FSCPath
@ -119,9 +121,7 @@ public:
template<typename F> template<typename F>
class FSAFileTree class FSAFileTree
{ {
public: private:
private:
enum NODETYPE : uint8 enum NODETYPE : uint8
{ {
@ -133,6 +133,7 @@ private:
{ {
std::string name; std::string name;
std::vector<node_t*> subnodes; std::vector<node_t*> subnodes;
size_t fileSize;
F* custom; F* custom;
NODETYPE type; NODETYPE type;
}; };
@ -179,13 +180,54 @@ private:
return newNode; return newNode;
} }
class DirectoryIterator : public FSCVirtualFile
{
public:
DirectoryIterator(node_t* node)
: m_node(node), m_subnodeIndex(0)
{
}
sint32 fscGetType() override
{
return FSC_TYPE_DIRECTORY;
}
bool fscDirNext(FSCDirEntry* dirEntry) override
{
if (m_subnodeIndex >= m_node->subnodes.size())
return false;
const node_t* subnode = m_node->subnodes[m_subnodeIndex];
strncpy(dirEntry->path, subnode->name.c_str(), sizeof(dirEntry->path) - 1);
dirEntry->path[sizeof(dirEntry->path) - 1] = '\0';
dirEntry->isDirectory = subnode->type == FSAFileTree::NODETYPE_DIRECTORY;
dirEntry->isFile = subnode->type == FSAFileTree::NODETYPE_FILE;
dirEntry->fileSize = subnode->type == FSAFileTree::NODETYPE_FILE ? subnode->fileSize : 0;
++m_subnodeIndex;
return true;
}
bool fscRewindDir() override
{
m_subnodeIndex = 0;
return true;
}
private:
node_t* m_node;
size_t m_subnodeIndex;
};
public: public:
FSAFileTree() FSAFileTree()
{ {
rootNode.type = NODETYPE_DIRECTORY; rootNode.type = NODETYPE_DIRECTORY;
} }
bool addFile(std::string_view path, F* custom) bool addFile(std::string_view path, size_t fileSize, F* custom)
{ {
FSCPath p(path); FSCPath p(path);
if (p.GetNodeCount() == 0) if (p.GetNodeCount() == 0)
@ -196,6 +238,7 @@ public:
return false; // node already exists return false; // node already exists
// add file node // add file node
node_t* fileNode = newNode(directoryNode, NODETYPE_FILE, p.GetNodeName(p.GetNodeCount() - 1)); node_t* fileNode = newNode(directoryNode, NODETYPE_FILE, p.GetNodeName(p.GetNodeCount() - 1));
fileNode->fileSize = fileSize;
fileNode->custom = custom; fileNode->custom = custom;
return true; return true;
} }
@ -214,6 +257,20 @@ public:
return true; return true;
} }
bool getDirectory(std::string_view path, FSCVirtualFile*& dirIterator)
{
FSCPath p(path);
if (p.GetNodeCount() == 0)
return false;
node_t* node = getByNodePath(p, p.GetNodeCount(), false);
if (node == nullptr)
return false;
if (node->type != NODETYPE_DIRECTORY)
return false;
dirIterator = new DirectoryIterator(node);
return true;
}
bool removeFile(std::string_view path) bool removeFile(std::string_view path)
{ {
FSCPath p(path); FSCPath p(path);

View File

@ -212,4 +212,4 @@ bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTarg
// redirect device // redirect device
void fscDeviceRedirect_map(); void fscDeviceRedirect_map();
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority); void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority);

View File

@ -11,7 +11,7 @@ struct RedirectEntry
FSAFileTree<RedirectEntry> redirectTree; FSAFileTree<RedirectEntry> redirectTree;
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority) void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority)
{ {
// check if source already has a redirection // check if source already has a redirection
RedirectEntry* existingEntry; RedirectEntry* existingEntry;
@ -24,7 +24,7 @@ void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& t
delete existingEntry; delete existingEntry;
} }
RedirectEntry* entry = new RedirectEntry(targetFilePath, priority); RedirectEntry* entry = new RedirectEntry(targetFilePath, priority);
redirectTree.addFile(virtualSourcePath, entry); redirectTree.addFile(virtualSourcePath, fileSize, entry);
} }
class fscDeviceTypeRedirect : public fscDeviceC class fscDeviceTypeRedirect : public fscDeviceC
@ -32,8 +32,15 @@ class fscDeviceTypeRedirect : public fscDeviceC
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
{ {
RedirectEntry* redirectionEntry; RedirectEntry* redirectionEntry;
if (redirectTree.getFile(path, redirectionEntry))
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE) && redirectTree.getFile(path, redirectionEntry))
return FSCVirtualFile_Host::OpenFile(redirectionEntry->dstPath, accessFlags, *fscStatus); return FSCVirtualFile_Host::OpenFile(redirectionEntry->dstPath, accessFlags, *fscStatus);
FSCVirtualFile* dirIterator;
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR) && redirectTree.getDirectory(path, dirIterator))
return dirIterator;
return nullptr; return nullptr;
} }

View File

@ -832,7 +832,7 @@ void GraphicPack2::_iterateReplacedFiles(const fs::path& currentPath, bool isAOC
{ {
virtualMountPath = fs::path("vol/content/") / virtualMountPath; virtualMountPath = fs::path("vol/content/") / virtualMountPath;
} }
fscDeviceRedirect_add(virtualMountPath.generic_string(), it.path().generic_string(), m_fs_priority); fscDeviceRedirect_add(virtualMountPath.generic_string(), it.file_size(), it.path().generic_string(), m_fs_priority);
} }
} }
} }

View File

@ -2200,6 +2200,8 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
else else
{ {
formatInfoOut->vkImageAspect = VK_IMAGE_ASPECT_COLOR_BIT; formatInfoOut->vkImageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
if(format == (Latte::E_GX2SURFFMT::R16_G16_B16_A16_FLOAT | Latte::E_GX2SURFFMT::FMT_BIT_SRGB)) // Seen in Sonic Transformed level Starry Speedway. SRGB should just be ignored for native float formats?
format = Latte::E_GX2SURFFMT::R16_G16_B16_A16_FLOAT;
switch (format) switch (format)
{ {
// RGBA formats // RGBA formats

View File

@ -23,3 +23,86 @@ void osLib_returnFromFunction64(PPCInterpreter_t* hCPU, uint64 returnValue64);
// utility functions // utility functions
#include "Cafe/OS/common/OSUtil.h" #include "Cafe/OS/common/OSUtil.h"
// va_list
struct ppc_va_list
{
uint8be gprIndex;
uint8be fprIndex;
uint8be _padding2[2];
MEMPTR<uint8be> overflow_arg_area;
MEMPTR<uint8be> reg_save_area;
};
static_assert(sizeof(ppc_va_list) == 0xC);
struct ppc_va_list_reg_storage
{
uint32be gpr_save_area[8]; // 32 bytes, r3 to r10
float64be fpr_save_area[8]; // 64 bytes, f1 to f8
ppc_va_list vargs;
uint32be padding;
};
static_assert(sizeof(ppc_va_list_reg_storage) == 0x70);
// Equivalent of va_start for PPC HLE functions. Must be called before any StackAllocator<> definitions
#define ppc_define_va_list(__gprIndex, __fprIndex) \
MPTR vaOriginalR1 = PPCInterpreter_getCurrentInstance()->gpr[1]; \
StackAllocator<ppc_va_list_reg_storage> va_list_storage; \
for(int i=3; i<=10; i++) va_list_storage->gpr_save_area[i-3] = PPCInterpreter_getCurrentInstance()->gpr[i]; \
for(int i=1; i<=8; i++) va_list_storage->fpr_save_area[i-1] = PPCInterpreter_getCurrentInstance()->fpr[i].fp0; \
va_list_storage->vargs.gprIndex = __gprIndex; \
va_list_storage->vargs.fprIndex = __fprIndex; \
va_list_storage->vargs.reg_save_area = (uint8be*)&va_list_storage; \
va_list_storage->vargs.overflow_arg_area = {vaOriginalR1 + 8}; \
ppc_va_list& vargs = va_list_storage->vargs;
enum class ppc_va_type
{
INT32 = 1,
INT64 = 2,
FLOAT_OR_DOUBLE = 3,
};
static void* _ppc_va_arg(ppc_va_list* vargs, ppc_va_type argType)
{
void* r;
switch ( argType )
{
default:
cemu_assert_suspicious();
case ppc_va_type::INT32:
if ( vargs[0].gprIndex < 8u )
{
r = &vargs->reg_save_area[4 * vargs->gprIndex];
vargs->gprIndex++;
return r;
}
r = vargs->overflow_arg_area;
vargs->overflow_arg_area += 4;
return r;
case ppc_va_type::INT64:
if ( (vargs->gprIndex & 1) != 0 )
vargs->gprIndex++;
if ( vargs->gprIndex < 8 )
{
r = &vargs->reg_save_area[4 * vargs->gprIndex];
vargs->gprIndex += 2;
return r;
}
vargs->overflow_arg_area = {(vargs->overflow_arg_area.GetMPTR()+7) & 0xFFFFFFF8};
r = vargs->overflow_arg_area;
vargs->overflow_arg_area += 8;
return r;
case ppc_va_type::FLOAT_OR_DOUBLE:
if ( vargs->fprIndex < 8 )
{
r = &vargs->reg_save_area[0x20 + 8 * vargs->fprIndex];
vargs->fprIndex++;
return r;
}
vargs->overflow_arg_area = {(vargs->overflow_arg_area.GetMPTR()+7) & 0xFFFFFFF8};
r = vargs->overflow_arg_area;
vargs->overflow_arg_area += 8;
return r;
}
}

View File

@ -7,14 +7,9 @@
namespace coreinit namespace coreinit
{ {
sint32 ppc_vprintf(const char* formatStr, char* strOut, sint32 maxLength, ppc_va_list* vargs)
/* coreinit logging and string format */
sint32 ppcSprintf(const char* formatStr, char* strOut, sint32 maxLength, PPCInterpreter_t* hCPU, sint32 initialParamIndex)
{ {
char tempStr[4096]; char tempStr[4096];
sint32 integerParamIndex = initialParamIndex;
sint32 floatParamIndex = 0;
sint32 writeIndex = 0; sint32 writeIndex = 0;
while (*formatStr) while (*formatStr)
{ {
@ -101,8 +96,7 @@ namespace coreinit
tempFormat[(formatStr - formatStart)] = '\0'; tempFormat[(formatStr - formatStart)] = '\0';
else else
tempFormat[sizeof(tempFormat) - 1] = '\0'; tempFormat[sizeof(tempFormat) - 1] = '\0';
sint32 tempLen = sprintf(tempStr, tempFormat, PPCInterpreter_getCallParamU32(hCPU, integerParamIndex)); sint32 tempLen = sprintf(tempStr, tempFormat, (uint32)*(uint32be*)_ppc_va_arg(vargs, ppc_va_type::INT32));
integerParamIndex++;
for (sint32 i = 0; i < tempLen; i++) for (sint32 i = 0; i < tempLen; i++)
{ {
if (writeIndex >= maxLength) if (writeIndex >= maxLength)
@ -120,13 +114,12 @@ namespace coreinit
tempFormat[(formatStr - formatStart)] = '\0'; tempFormat[(formatStr - formatStart)] = '\0';
else else
tempFormat[sizeof(tempFormat) - 1] = '\0'; tempFormat[sizeof(tempFormat) - 1] = '\0';
MPTR strOffset = PPCInterpreter_getCallParamU32(hCPU, integerParamIndex); MPTR strOffset = *(uint32be*)_ppc_va_arg(vargs, ppc_va_type::INT32);
sint32 tempLen = 0; sint32 tempLen = 0;
if (strOffset == MPTR_NULL) if (strOffset == MPTR_NULL)
tempLen = sprintf(tempStr, "NULL"); tempLen = sprintf(tempStr, "NULL");
else else
tempLen = sprintf(tempStr, tempFormat, memory_getPointerFromVirtualOffset(strOffset)); tempLen = sprintf(tempStr, tempFormat, memory_getPointerFromVirtualOffset(strOffset));
integerParamIndex++;
for (sint32 i = 0; i < tempLen; i++) for (sint32 i = 0; i < tempLen; i++)
{ {
if (writeIndex >= maxLength) if (writeIndex >= maxLength)
@ -136,25 +129,6 @@ namespace coreinit
} }
strOut[std::min(maxLength - 1, writeIndex)] = '\0'; strOut[std::min(maxLength - 1, writeIndex)] = '\0';
} }
else if (*formatStr == 'f')
{
// float
formatStr++;
strncpy(tempFormat, formatStart, std::min((std::ptrdiff_t)sizeof(tempFormat) - 1, formatStr - formatStart));
if ((formatStr - formatStart) < sizeof(tempFormat))
tempFormat[(formatStr - formatStart)] = '\0';
else
tempFormat[sizeof(tempFormat) - 1] = '\0';
sint32 tempLen = sprintf(tempStr, tempFormat, (float)hCPU->fpr[1 + floatParamIndex].fp0);
floatParamIndex++;
for (sint32 i = 0; i < tempLen; i++)
{
if (writeIndex >= maxLength)
break;
strOut[writeIndex] = tempStr[i];
writeIndex++;
}
}
else if (*formatStr == 'c') else if (*formatStr == 'c')
{ {
// character // character
@ -164,8 +138,24 @@ namespace coreinit
tempFormat[(formatStr - formatStart)] = '\0'; tempFormat[(formatStr - formatStart)] = '\0';
else else
tempFormat[sizeof(tempFormat) - 1] = '\0'; tempFormat[sizeof(tempFormat) - 1] = '\0';
sint32 tempLen = sprintf(tempStr, tempFormat, PPCInterpreter_getCallParamU32(hCPU, integerParamIndex)); sint32 tempLen = sprintf(tempStr, tempFormat, (uint32)*(uint32be*)_ppc_va_arg(vargs, ppc_va_type::INT32));
integerParamIndex++; for (sint32 i = 0; i < tempLen; i++)
{
if (writeIndex >= maxLength)
break;
strOut[writeIndex] = tempStr[i];
writeIndex++;
}
}
else if (*formatStr == 'f' || *formatStr == 'g' || *formatStr == 'G')
{
formatStr++;
strncpy(tempFormat, formatStart, std::min((std::ptrdiff_t)sizeof(tempFormat) - 1, formatStr - formatStart));
if ((formatStr - formatStart) < sizeof(tempFormat))
tempFormat[(formatStr - formatStart)] = '\0';
else
tempFormat[sizeof(tempFormat) - 1] = '\0';
sint32 tempLen = sprintf(tempStr, tempFormat, (double)*(betype<double>*)_ppc_va_arg(vargs, ppc_va_type::FLOAT_OR_DOUBLE));
for (sint32 i = 0; i < tempLen; i++) for (sint32 i = 0; i < tempLen; i++)
{ {
if (writeIndex >= maxLength) if (writeIndex >= maxLength)
@ -183,8 +173,7 @@ namespace coreinit
tempFormat[(formatStr - formatStart)] = '\0'; tempFormat[(formatStr - formatStart)] = '\0';
else else
tempFormat[sizeof(tempFormat) - 1] = '\0'; tempFormat[sizeof(tempFormat) - 1] = '\0';
sint32 tempLen = sprintf(tempStr, tempFormat, (double)hCPU->fpr[1 + floatParamIndex].fp0); sint32 tempLen = sprintf(tempStr, tempFormat, (double)*(betype<double>*)_ppc_va_arg(vargs, ppc_va_type::FLOAT_OR_DOUBLE));
floatParamIndex++;
for (sint32 i = 0; i < tempLen; i++) for (sint32 i = 0; i < tempLen; i++)
{ {
if (writeIndex >= maxLength) if (writeIndex >= maxLength)
@ -196,16 +185,13 @@ namespace coreinit
else if ((formatStr[0] == 'l' && formatStr[1] == 'l' && (formatStr[2] == 'x' || formatStr[2] == 'X'))) else if ((formatStr[0] == 'l' && formatStr[1] == 'l' && (formatStr[2] == 'x' || formatStr[2] == 'X')))
{ {
formatStr += 3; formatStr += 3;
// double (64bit) // 64bit int
strncpy(tempFormat, formatStart, std::min((std::ptrdiff_t)sizeof(tempFormat) - 1, formatStr - formatStart)); strncpy(tempFormat, formatStart, std::min((std::ptrdiff_t)sizeof(tempFormat) - 1, formatStr - formatStart));
if ((formatStr - formatStart) < sizeof(tempFormat)) if ((formatStr - formatStart) < sizeof(tempFormat))
tempFormat[(formatStr - formatStart)] = '\0'; tempFormat[(formatStr - formatStart)] = '\0';
else else
tempFormat[sizeof(tempFormat) - 1] = '\0'; tempFormat[sizeof(tempFormat) - 1] = '\0';
if (integerParamIndex & 1) sint32 tempLen = sprintf(tempStr, tempFormat, (uint64)*(uint64be*)_ppc_va_arg(vargs, ppc_va_type::INT64));
integerParamIndex++;
sint32 tempLen = sprintf(tempStr, tempFormat, PPCInterpreter_getCallParamU64(hCPU, integerParamIndex));
integerParamIndex += 2;
for (sint32 i = 0; i < tempLen; i++) for (sint32 i = 0; i < tempLen; i++)
{ {
if (writeIndex >= maxLength) if (writeIndex >= maxLength)
@ -223,10 +209,7 @@ namespace coreinit
tempFormat[(formatStr - formatStart)] = '\0'; tempFormat[(formatStr - formatStart)] = '\0';
else else
tempFormat[sizeof(tempFormat) - 1] = '\0'; tempFormat[sizeof(tempFormat) - 1] = '\0';
if (integerParamIndex & 1) sint32 tempLen = sprintf(tempStr, tempFormat, (sint64)*(sint64be*)_ppc_va_arg(vargs, ppc_va_type::INT64));
integerParamIndex++;
sint32 tempLen = sprintf(tempStr, tempFormat, PPCInterpreter_getCallParamU64(hCPU, integerParamIndex));
integerParamIndex += 2;
for (sint32 i = 0; i < tempLen; i++) for (sint32 i = 0; i < tempLen; i++)
{ {
if (writeIndex >= maxLength) if (writeIndex >= maxLength)
@ -255,9 +238,12 @@ namespace coreinit
return std::min(writeIndex, maxLength - 1); return std::min(writeIndex, maxLength - 1);
} }
/* coreinit logging and string format */
sint32 __os_snprintf(char* outputStr, sint32 maxLength, const char* formatStr) sint32 __os_snprintf(char* outputStr, sint32 maxLength, const char* formatStr)
{ {
sint32 r = ppcSprintf(formatStr, outputStr, maxLength, PPCInterpreter_getCurrentInstance(), 3); ppc_define_va_list(3, 0);
sint32 r = ppc_vprintf(formatStr, outputStr, maxLength, &vargs);
return r; return r;
} }
@ -322,32 +308,40 @@ namespace coreinit
} }
} }
void OSReport(const char* format) void COSVReport(COSReportModule module, COSReportLevel level, const char* format, ppc_va_list* vargs)
{ {
char buffer[1024 * 2]; char tmpBuffer[1024];
sint32 len = ppcSprintf(format, buffer, sizeof(buffer), PPCInterpreter_getCurrentInstance(), 1); sint32 len = ppc_vprintf(format, tmpBuffer, sizeof(tmpBuffer), vargs);
WriteCafeConsole(CafeLogType::OSCONSOLE, buffer, len); WriteCafeConsole(CafeLogType::OSCONSOLE, tmpBuffer, len);
} }
void OSVReport(const char* format, MPTR vaArgs) void OSReport(const char* format)
{ {
cemu_assert_unimplemented(); ppc_define_va_list(1, 0);
COSVReport(COSReportModule::coreinit, COSReportLevel::Info, format, &vargs);
}
void OSVReport(const char* format, ppc_va_list* vargs)
{
COSVReport(COSReportModule::coreinit, COSReportLevel::Info, format, vargs);
} }
void COSWarn(int moduleId, const char* format) void COSWarn(int moduleId, const char* format)
{ {
char buffer[1024 * 2]; ppc_define_va_list(2, 0);
int prefixLen = sprintf(buffer, "[COSWarn-%d] ", moduleId); char tmpBuffer[1024];
sint32 len = ppcSprintf(format, buffer + prefixLen, sizeof(buffer) - prefixLen, PPCInterpreter_getCurrentInstance(), 2); int prefixLen = sprintf(tmpBuffer, "[COSWarn-%d] ", moduleId);
WriteCafeConsole(CafeLogType::OSCONSOLE, buffer, len + prefixLen); sint32 len = ppc_vprintf(format, tmpBuffer + prefixLen, sizeof(tmpBuffer) - prefixLen, &vargs);
WriteCafeConsole(CafeLogType::OSCONSOLE, tmpBuffer, len + prefixLen);
} }
void OSLogPrintf(int ukn1, int ukn2, int ukn3, const char* format) void OSLogPrintf(int ukn1, int ukn2, int ukn3, const char* format)
{ {
char buffer[1024 * 2]; ppc_define_va_list(4, 0);
int prefixLen = sprintf(buffer, "[OSLogPrintf-%d-%d-%d] ", ukn1, ukn2, ukn3); char tmpBuffer[1024];
sint32 len = ppcSprintf(format, buffer + prefixLen, sizeof(buffer) - prefixLen, PPCInterpreter_getCurrentInstance(), 4); int prefixLen = sprintf(tmpBuffer, "[OSLogPrintf-%d-%d-%d] ", ukn1, ukn2, ukn3);
WriteCafeConsole(CafeLogType::OSCONSOLE, buffer, len + prefixLen); sint32 len = ppc_vprintf(format, tmpBuffer + prefixLen, sizeof(tmpBuffer) - prefixLen, &vargs);
WriteCafeConsole(CafeLogType::OSCONSOLE, tmpBuffer, len + prefixLen);
} }
void OSConsoleWrite(const char* strPtr, sint32 length) void OSConsoleWrite(const char* strPtr, sint32 length)
@ -562,9 +556,11 @@ namespace coreinit
s_transitionToForeground = false; s_transitionToForeground = false;
cafeExportRegister("coreinit", __os_snprintf, LogType::Placeholder); cafeExportRegister("coreinit", __os_snprintf, LogType::Placeholder);
cafeExportRegister("coreinit", COSVReport, LogType::Placeholder);
cafeExportRegister("coreinit", COSWarn, LogType::Placeholder);
cafeExportRegister("coreinit", OSReport, LogType::Placeholder); cafeExportRegister("coreinit", OSReport, LogType::Placeholder);
cafeExportRegister("coreinit", OSVReport, LogType::Placeholder); cafeExportRegister("coreinit", OSVReport, LogType::Placeholder);
cafeExportRegister("coreinit", COSWarn, LogType::Placeholder);
cafeExportRegister("coreinit", OSLogPrintf, LogType::Placeholder); cafeExportRegister("coreinit", OSLogPrintf, LogType::Placeholder);
cafeExportRegister("coreinit", OSConsoleWrite, LogType::Placeholder); cafeExportRegister("coreinit", OSConsoleWrite, LogType::Placeholder);

View File

@ -26,5 +26,19 @@ namespace coreinit
uint32 OSDriver_Register(uint32 moduleHandle, sint32 priority, OSDriverInterface* driverCallbacks, sint32 driverId, uint32be* outUkn1, uint32be* outUkn2, uint32be* outUkn3); uint32 OSDriver_Register(uint32 moduleHandle, sint32 priority, OSDriverInterface* driverCallbacks, sint32 driverId, uint32be* outUkn1, uint32be* outUkn2, uint32be* outUkn3);
uint32 OSDriver_Deregister(uint32 moduleHandle, sint32 driverId); uint32 OSDriver_Deregister(uint32 moduleHandle, sint32 driverId);
enum class COSReportModule
{
coreinit = 0,
};
enum class COSReportLevel
{
Error = 0,
Warn = 1,
Info = 2
};
sint32 ppc_vprintf(const char* formatStr, char* strOut, sint32 maxLength, ppc_va_list* vargs);
void miscInit(); void miscInit();
}; };

View File

@ -92,19 +92,6 @@ public:
template <typename X> template <typename X>
explicit operator MEMPTR<X>() const { return MEMPTR<X>(this->m_value); } explicit operator MEMPTR<X>() const { return MEMPTR<X>(this->m_value); }
//bool operator==(const MEMPTR<T>& v) const { return m_value == v.m_value; }
//bool operator==(const T* rhs) const { return (T*)(m_value == 0 ? nullptr : memory_base + (uint32)m_value) == rhs; } -> ambigious (implicit cast to T* allows for T* == T*)
//bool operator==(std::nullptr_t rhs) const { return m_value == 0; }
//bool operator!=(const MEMPTR<T>& v) const { return !(*this == v); }
//bool operator!=(const void* rhs) const { return !(*this == rhs); }
//bool operator!=(int rhs) const { return !(*this == rhs); }
//bool operator==(const void* rhs) const { return (void*)(m_value == 0 ? nullptr : memory_base + (uint32)m_value) == rhs; }
//explicit bool operator==(int rhs) const { return *this == (const void*)(size_t)rhs; }
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) { return MEMPTR(this->GetMPTR() - ptr.GetMPTR()); } MEMPTR operator-(const MEMPTR& ptr) { return MEMPTR(this->GetMPTR() - ptr.GetMPTR()); }
@ -120,6 +107,12 @@ public:
return MEMPTR(this->GetMPTR() - v * 4); return MEMPTR(this->GetMPTR() - v * 4);
} }
MEMPTR& operator+=(sint32 v)
{
m_value += v * sizeof(T);
return *this;
}
template <class Q = T> template <class Q = T>
typename std::enable_if<!std::is_same<Q, void>::value, Q>::type& typename std::enable_if<!std::is_same<Q, void>::value, Q>::type&
operator*() const { return *GetPtr(); } operator*() const { return *GetPtr(); }

View File

@ -121,6 +121,12 @@ public:
return *this; return *this;
} }
betype<T>& operator+=(const T& v) requires std::integral<T>
{
m_value = SwapEndian(T(value() + v));
return *this;
}
betype<T>& operator-=(const betype<T>& v) betype<T>& operator-=(const betype<T>& v)
{ {
m_value = SwapEndian(T(value() - v.value())); m_value = SwapEndian(T(value() - v.value()));
@ -188,17 +194,36 @@ public:
return from_bevalue(T(~m_value)); return from_bevalue(T(~m_value));
} }
// pre-increment
betype<T>& operator++() requires std::integral<T> betype<T>& operator++() requires std::integral<T>
{ {
m_value = SwapEndian(T(value() + 1)); m_value = SwapEndian(T(value() + 1));
return *this; return *this;
} }
// post-increment
betype<T> operator++(int) requires std::integral<T>
{
betype<T> tmp(*this);
m_value = SwapEndian(T(value() + 1));
return tmp;
}
// pre-decrement
betype<T>& operator--() requires std::integral<T> betype<T>& operator--() requires std::integral<T>
{ {
m_value = SwapEndian(T(value() - 1)); m_value = SwapEndian(T(value() - 1));
return *this; return *this;
} }
// post-decrement
betype<T> operator--(int) requires std::integral<T>
{
betype<T> tmp(*this);
m_value = SwapEndian(T(value() - 1));
return tmp;
}
private: private:
//T m_value{}; // before 1.26.2 //T m_value{}; // before 1.26.2
T m_value; T m_value;