Skip to content

Commit

Permalink
Merge branch 'main' into metal
Browse files Browse the repository at this point in the history
  • Loading branch information
SamoZ256 authored Aug 14, 2024
2 parents bba2bbc + c49296a commit a22b73a
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ jobs:
run: |
brew update
brew install llvm@15 ninja nasm automake libtool
brew install cmake python3 ninja
brew install cmake ninja
- name: "Build and install molten-vk"
run: |
Expand Down
65 changes: 61 additions & 4 deletions src/Cafe/Filesystem/FST/fstUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <boost/container/small_vector.hpp>

#include "../fsc.h"

// path parser and utility class for Wii U paths
// optimized to be allocation-free for common path lengths
class FSCPath
Expand Down Expand Up @@ -119,9 +121,7 @@ class FSCPath
template<typename F>
class FSAFileTree
{
public:

private:
private:

enum NODETYPE : uint8
{
Expand All @@ -133,6 +133,7 @@ class FSAFileTree
{
std::string name;
std::vector<node_t*> subnodes;
size_t fileSize;
F* custom;
NODETYPE type;
};
Expand Down Expand Up @@ -179,13 +180,54 @@ class FSAFileTree
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:
FSAFileTree()
{
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);
if (p.GetNodeCount() == 0)
Expand All @@ -196,6 +238,7 @@ class FSAFileTree
return false; // node already exists
// add file node
node_t* fileNode = newNode(directoryNode, NODETYPE_FILE, p.GetNodeName(p.GetNodeCount() - 1));
fileNode->fileSize = fileSize;
fileNode->custom = custom;
return true;
}
Expand All @@ -214,6 +257,20 @@ class FSAFileTree
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)
{
FSCPath p(path);
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/Filesystem/fsc.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,4 @@ bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTarg

// redirect device
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);
13 changes: 10 additions & 3 deletions src/Cafe/Filesystem/fscDeviceRedirect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct RedirectEntry

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
RedirectEntry* existingEntry;
Expand All @@ -24,16 +24,23 @@ void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& t
delete existingEntry;
}
RedirectEntry* entry = new RedirectEntry(targetFilePath, priority);
redirectTree.addFile(virtualSourcePath, entry);
redirectTree.addFile(virtualSourcePath, fileSize, entry);
}

class fscDeviceTypeRedirect : public fscDeviceC
{
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
{
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);

FSCVirtualFile* dirIterator;

if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR) && redirectTree.getDirectory(path, dirIterator))
return dirIterator;

return nullptr;
}

Expand Down
4 changes: 2 additions & 2 deletions src/Cafe/GraphicPack/GraphicPack2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -832,8 +832,8 @@ void GraphicPack2::_iterateReplacedFiles(const fs::path& currentPath, bool isAOC
{
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);
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2200,6 +2200,8 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
else
{
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)
{
// RGBA formats
Expand Down
83 changes: 83 additions & 0 deletions src/Cafe/OS/common/OSCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,86 @@ void osLib_returnFromFunction64(PPCInterpreter_t* hCPU, uint64 returnValue64);

// utility functions
#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;
}
}
Loading

0 comments on commit a22b73a

Please sign in to comment.