Skip to content

Commit a22b73a

Browse files
authored
Merge branch 'main' into metal
2 parents bba2bbc + c49296a commit a22b73a

File tree

11 files changed

+245
-68
lines changed

11 files changed

+245
-68
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ jobs:
225225
run: |
226226
brew update
227227
brew install llvm@15 ninja nasm automake libtool
228-
brew install cmake python3 ninja
228+
brew install cmake ninja
229229
230230
- name: "Build and install molten-vk"
231231
run: |

src/Cafe/Filesystem/FST/fstUtil.h

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <boost/container/small_vector.hpp>
55

6+
#include "../fsc.h"
7+
68
// path parser and utility class for Wii U paths
79
// optimized to be allocation-free for common path lengths
810
class FSCPath
@@ -119,9 +121,7 @@ class FSCPath
119121
template<typename F>
120122
class FSAFileTree
121123
{
122-
public:
123-
124-
private:
124+
private:
125125

126126
enum NODETYPE : uint8
127127
{
@@ -133,6 +133,7 @@ class FSAFileTree
133133
{
134134
std::string name;
135135
std::vector<node_t*> subnodes;
136+
size_t fileSize;
136137
F* custom;
137138
NODETYPE type;
138139
};
@@ -179,13 +180,54 @@ class FSAFileTree
179180
return newNode;
180181
}
181182

183+
class DirectoryIterator : public FSCVirtualFile
184+
{
185+
public:
186+
DirectoryIterator(node_t* node)
187+
: m_node(node), m_subnodeIndex(0)
188+
{
189+
}
190+
191+
sint32 fscGetType() override
192+
{
193+
return FSC_TYPE_DIRECTORY;
194+
}
195+
196+
bool fscDirNext(FSCDirEntry* dirEntry) override
197+
{
198+
if (m_subnodeIndex >= m_node->subnodes.size())
199+
return false;
200+
201+
const node_t* subnode = m_node->subnodes[m_subnodeIndex];
202+
203+
strncpy(dirEntry->path, subnode->name.c_str(), sizeof(dirEntry->path) - 1);
204+
dirEntry->path[sizeof(dirEntry->path) - 1] = '\0';
205+
dirEntry->isDirectory = subnode->type == FSAFileTree::NODETYPE_DIRECTORY;
206+
dirEntry->isFile = subnode->type == FSAFileTree::NODETYPE_FILE;
207+
dirEntry->fileSize = subnode->type == FSAFileTree::NODETYPE_FILE ? subnode->fileSize : 0;
208+
209+
++m_subnodeIndex;
210+
return true;
211+
}
212+
213+
bool fscRewindDir() override
214+
{
215+
m_subnodeIndex = 0;
216+
return true;
217+
}
218+
219+
private:
220+
node_t* m_node;
221+
size_t m_subnodeIndex;
222+
};
223+
182224
public:
183225
FSAFileTree()
184226
{
185227
rootNode.type = NODETYPE_DIRECTORY;
186228
}
187229

188-
bool addFile(std::string_view path, F* custom)
230+
bool addFile(std::string_view path, size_t fileSize, F* custom)
189231
{
190232
FSCPath p(path);
191233
if (p.GetNodeCount() == 0)
@@ -196,6 +238,7 @@ class FSAFileTree
196238
return false; // node already exists
197239
// add file node
198240
node_t* fileNode = newNode(directoryNode, NODETYPE_FILE, p.GetNodeName(p.GetNodeCount() - 1));
241+
fileNode->fileSize = fileSize;
199242
fileNode->custom = custom;
200243
return true;
201244
}
@@ -214,6 +257,20 @@ class FSAFileTree
214257
return true;
215258
}
216259

260+
bool getDirectory(std::string_view path, FSCVirtualFile*& dirIterator)
261+
{
262+
FSCPath p(path);
263+
if (p.GetNodeCount() == 0)
264+
return false;
265+
node_t* node = getByNodePath(p, p.GetNodeCount(), false);
266+
if (node == nullptr)
267+
return false;
268+
if (node->type != NODETYPE_DIRECTORY)
269+
return false;
270+
dirIterator = new DirectoryIterator(node);
271+
return true;
272+
}
273+
217274
bool removeFile(std::string_view path)
218275
{
219276
FSCPath p(path);

src/Cafe/Filesystem/fsc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,4 @@ bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTarg
212212

213213
// redirect device
214214
void fscDeviceRedirect_map();
215-
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority);
215+
void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority);

src/Cafe/Filesystem/fscDeviceRedirect.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ struct RedirectEntry
1111

1212
FSAFileTree<RedirectEntry> redirectTree;
1313

14-
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority)
14+
void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority)
1515
{
1616
// check if source already has a redirection
1717
RedirectEntry* existingEntry;
@@ -24,16 +24,23 @@ void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& t
2424
delete existingEntry;
2525
}
2626
RedirectEntry* entry = new RedirectEntry(targetFilePath, priority);
27-
redirectTree.addFile(virtualSourcePath, entry);
27+
redirectTree.addFile(virtualSourcePath, fileSize, entry);
2828
}
2929

3030
class fscDeviceTypeRedirect : public fscDeviceC
3131
{
3232
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
3333
{
3434
RedirectEntry* redirectionEntry;
35-
if (redirectTree.getFile(path, redirectionEntry))
35+
36+
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE) && redirectTree.getFile(path, redirectionEntry))
3637
return FSCVirtualFile_Host::OpenFile(redirectionEntry->dstPath, accessFlags, *fscStatus);
38+
39+
FSCVirtualFile* dirIterator;
40+
41+
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR) && redirectTree.getDirectory(path, dirIterator))
42+
return dirIterator;
43+
3744
return nullptr;
3845
}
3946

src/Cafe/GraphicPack/GraphicPack2.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -832,8 +832,8 @@ void GraphicPack2::_iterateReplacedFiles(const fs::path& currentPath, bool isAOC
832832
{
833833
virtualMountPath = fs::path("vol/content/") / virtualMountPath;
834834
}
835-
fscDeviceRedirect_add(virtualMountPath.generic_string(), it.path().generic_string(), m_fs_priority);
836-
}
835+
fscDeviceRedirect_add(virtualMountPath.generic_string(), it.file_size(), it.path().generic_string(), m_fs_priority);
836+
}
837837
}
838838
}
839839

src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,6 +2200,8 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
22002200
else
22012201
{
22022202
formatInfoOut->vkImageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
2203+
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?
2204+
format = Latte::E_GX2SURFFMT::R16_G16_B16_A16_FLOAT;
22032205
switch (format)
22042206
{
22052207
// RGBA formats

src/Cafe/OS/common/OSCommon.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,86 @@ void osLib_returnFromFunction64(PPCInterpreter_t* hCPU, uint64 returnValue64);
2323

2424
// utility functions
2525
#include "Cafe/OS/common/OSUtil.h"
26+
27+
// va_list
28+
struct ppc_va_list
29+
{
30+
uint8be gprIndex;
31+
uint8be fprIndex;
32+
uint8be _padding2[2];
33+
MEMPTR<uint8be> overflow_arg_area;
34+
MEMPTR<uint8be> reg_save_area;
35+
};
36+
static_assert(sizeof(ppc_va_list) == 0xC);
37+
38+
struct ppc_va_list_reg_storage
39+
{
40+
uint32be gpr_save_area[8]; // 32 bytes, r3 to r10
41+
float64be fpr_save_area[8]; // 64 bytes, f1 to f8
42+
ppc_va_list vargs;
43+
uint32be padding;
44+
};
45+
static_assert(sizeof(ppc_va_list_reg_storage) == 0x70);
46+
47+
// Equivalent of va_start for PPC HLE functions. Must be called before any StackAllocator<> definitions
48+
#define ppc_define_va_list(__gprIndex, __fprIndex) \
49+
MPTR vaOriginalR1 = PPCInterpreter_getCurrentInstance()->gpr[1]; \
50+
StackAllocator<ppc_va_list_reg_storage> va_list_storage; \
51+
for(int i=3; i<=10; i++) va_list_storage->gpr_save_area[i-3] = PPCInterpreter_getCurrentInstance()->gpr[i]; \
52+
for(int i=1; i<=8; i++) va_list_storage->fpr_save_area[i-1] = PPCInterpreter_getCurrentInstance()->fpr[i].fp0; \
53+
va_list_storage->vargs.gprIndex = __gprIndex; \
54+
va_list_storage->vargs.fprIndex = __fprIndex; \
55+
va_list_storage->vargs.reg_save_area = (uint8be*)&va_list_storage; \
56+
va_list_storage->vargs.overflow_arg_area = {vaOriginalR1 + 8}; \
57+
ppc_va_list& vargs = va_list_storage->vargs;
58+
59+
enum class ppc_va_type
60+
{
61+
INT32 = 1,
62+
INT64 = 2,
63+
FLOAT_OR_DOUBLE = 3,
64+
};
65+
66+
static void* _ppc_va_arg(ppc_va_list* vargs, ppc_va_type argType)
67+
{
68+
void* r;
69+
switch ( argType )
70+
{
71+
default:
72+
cemu_assert_suspicious();
73+
case ppc_va_type::INT32:
74+
if ( vargs[0].gprIndex < 8u )
75+
{
76+
r = &vargs->reg_save_area[4 * vargs->gprIndex];
77+
vargs->gprIndex++;
78+
return r;
79+
}
80+
r = vargs->overflow_arg_area;
81+
vargs->overflow_arg_area += 4;
82+
return r;
83+
case ppc_va_type::INT64:
84+
if ( (vargs->gprIndex & 1) != 0 )
85+
vargs->gprIndex++;
86+
if ( vargs->gprIndex < 8 )
87+
{
88+
r = &vargs->reg_save_area[4 * vargs->gprIndex];
89+
vargs->gprIndex += 2;
90+
return r;
91+
}
92+
vargs->overflow_arg_area = {(vargs->overflow_arg_area.GetMPTR()+7) & 0xFFFFFFF8};
93+
r = vargs->overflow_arg_area;
94+
vargs->overflow_arg_area += 8;
95+
return r;
96+
case ppc_va_type::FLOAT_OR_DOUBLE:
97+
if ( vargs->fprIndex < 8 )
98+
{
99+
r = &vargs->reg_save_area[0x20 + 8 * vargs->fprIndex];
100+
vargs->fprIndex++;
101+
return r;
102+
}
103+
vargs->overflow_arg_area = {(vargs->overflow_arg_area.GetMPTR()+7) & 0xFFFFFFF8};
104+
r = vargs->overflow_arg_area;
105+
vargs->overflow_arg_area += 8;
106+
return r;
107+
}
108+
}

0 commit comments

Comments
 (0)