Add all the files

This commit is contained in:
Exzap 2022-08-22 22:21:23 +02:00
parent e3db07a16a
commit d60742f52b
1445 changed files with 430238 additions and 0 deletions

View file

@ -0,0 +1,220 @@
#include "Cafe/HW/Espresso/PPCState.h"
#include "Cafe/OS/libs/proc_ui/proc_ui.h"
#include "Cafe/OS/libs/nsysnet/nsysnet.h"
#include "Cafe/OS/libs/nlibnss/nlibnss.h"
#include "Cafe/OS/libs/nlibcurl/nlibcurl.h"
#include "Cafe/OS/libs/nn_nfp/nn_nfp.h"
#include "Cafe/OS/libs/nn_act/nn_act.h"
#include "Cafe/OS/libs/nn_acp/nn_acp.h"
#include "Cafe/OS/libs/nn_ac/nn_ac.h"
#include "Cafe/OS/libs/nn_uds/nn_uds.h"
#include "Cafe/OS/libs/nn_nim/nn_nim.h"
#include "Cafe/OS/libs/nn_ndm/nn_ndm.h"
#include "Cafe/OS/libs/nn_ec/nn_ec.h"
#include "Cafe/OS/libs/nn_boss/nn_boss.h"
#include "Cafe/OS/libs/nn_fp/nn_fp.h"
#include "Cafe/OS/libs/nn_olv/nn_olv.h"
#include "Cafe/OS/libs/nn_idbe/nn_idbe.h"
#include "Cafe/OS/libs/nn_save/nn_save.h"
#include "Cafe/OS/libs/erreula/erreula.h"
#include "Cafe/OS/libs/sysapp/sysapp.h"
#include "Cafe/OS/libs/dmae/dmae.h"
#include "Cafe/OS/libs/snd_core/ax.h"
#include "Cafe/OS/libs/gx2/GX2.h"
#include "Cafe/OS/libs/vpad/vpad.h"
#include "Cafe/OS/libs/nsyskbd/nsyskbd.h"
#include "Cafe/OS/libs/nsyshid/nsyshid.h"
#include "Cafe/OS/libs/snd_user/snd_user.h"
#include "Cafe/OS/libs/zlib125/zlib125.h"
#include "Cafe/OS/libs/padscore/padscore.h"
#include "Cafe/OS/libs/camera/camera.h"
#include "../libs/swkbd/swkbd.h"
struct osFunctionEntry_t
{
uint32 libHashA;
uint32 libHashB;
uint32 funcHashA;
uint32 funcHashB;
std::string name;
HLEIDX hleFunc;
osFunctionEntry_t(uint32 libHashA, uint32 libHashB, uint32 funcHashA, uint32 funcHashB, std::string_view name, HLEIDX hleFunc) :
libHashA(libHashA), libHashB(libHashB), funcHashA(funcHashA), funcHashB(funcHashB), name(name), hleFunc(hleFunc) {};
};
typedef struct
{
uint32 libHashA;
uint32 libHashB;
uint32 funcHashA;
uint32 funcHashB;
uint32 vPtr;
}osPointerEntry_t;
std::vector<osFunctionEntry_t>* s_osFunctionTable;
std::vector<osPointerEntry_t> osDataTable;
void osLib_generateHashFromName(const char* name, uint32* hashA, uint32* hashB)
{
uint32 h1 = 0x688BA2BA;
uint32 h2 = 0xF64A71D5;
while( *name )
{
uint32 c = (uint32)*name;
h1 += c;
h1 = (h1<<3)|((h1>>29));
h2 ^= c;
h2 = (h2<<7)|((h2>>25));
h1 += h2;
h2 += c;
h2 = (h2<<3)|((h2>>29));
name++;
}
*hashA = h1;
*hashB = h2;
}
void osLib_addFunctionInternal(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU))
{
if (!s_osFunctionTable)
s_osFunctionTable = new std::vector<osFunctionEntry_t>(); // replace with static allocation + constinit once we have C++20 available
// calculate hash
uint32 libHashA, libHashB;
uint32 funcHashA, funcHashB;
osLib_generateHashFromName(libraryName, &libHashA, &libHashB);
osLib_generateHashFromName(functionName, &funcHashA, &funcHashB);
// if entry already exists, update it
for (auto& it : *s_osFunctionTable)
{
if (it.libHashA == libHashA &&
it.libHashB == libHashB &&
it.funcHashA == funcHashA &&
it.funcHashB == funcHashB)
{
it.hleFunc = PPCInterpreter_registerHLECall(osFunction);
return;
}
}
s_osFunctionTable->emplace_back(libHashA, libHashB, funcHashA, funcHashB, fmt::format("{}.{}", libraryName, functionName), PPCInterpreter_registerHLECall(osFunction));
}
__declspec(dllexport) void osLib_registerHLEFunction(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU))
{
osLib_addFunctionInternal(libraryName, functionName, osFunction);
}
sint32 osLib_getFunctionIndex(const char* libraryName, const char* functionName)
{
uint32 libHashA, libHashB;
uint32 funcHashA, funcHashB;
osLib_generateHashFromName(libraryName, &libHashA, &libHashB);
osLib_generateHashFromName(functionName, &funcHashA, &funcHashB);
for (auto& it : *s_osFunctionTable)
{
if (it.libHashA == libHashA &&
it.libHashB == libHashB &&
it.funcHashA == funcHashA &&
it.funcHashB == funcHashB)
{
return it.hleFunc;
}
}
return -1;
}
void osLib_addVirtualPointer(const char* libraryName, const char* functionName, uint32 vPtr)
{
// calculate hash
uint32 libHashA, libHashB;
uint32 funcHashA, funcHashB;
osLib_generateHashFromName(libraryName, &libHashA, &libHashB);
osLib_generateHashFromName(functionName, &funcHashA, &funcHashB);
// if entry already exists, update it
for (auto& it : osDataTable)
{
if (it.libHashA == libHashA &&
it.libHashB == libHashB &&
it.funcHashA == funcHashA &&
it.funcHashB == funcHashB)
{
it.vPtr = vPtr;
return;
}
}
// add entry
auto writeIndex = osDataTable.size();
osDataTable.resize(osDataTable.size() + 1);
osDataTable[writeIndex].libHashA = libHashA;
osDataTable[writeIndex].libHashB = libHashB;
osDataTable[writeIndex].funcHashA = funcHashA;
osDataTable[writeIndex].funcHashB = funcHashB;
osDataTable[writeIndex].vPtr = vPtr;
}
uint32 osLib_getPointer(const char* libraryName, const char* functionName)
{
uint32 libHashA, libHashB;
uint32 funcHashA, funcHashB;
osLib_generateHashFromName(libraryName, &libHashA, &libHashB);
osLib_generateHashFromName(functionName, &funcHashA, &funcHashB);
for (auto& it : osDataTable)
{
if (it.libHashA == libHashA &&
it.libHashB == libHashB &&
it.funcHashA == funcHashA &&
it.funcHashB == funcHashB)
{
return it.vPtr;
}
}
return 0xFFFFFFFF;
}
void osLib_returnFromFunction(PPCInterpreter_t* hCPU, uint32 returnValue)
{
hCPU->gpr[3] = returnValue;
hCPU->instructionPointer = hCPU->spr.LR;
}
void osLib_returnFromFunction64(PPCInterpreter_t* hCPU, uint64 returnValue64)
{
hCPU->gpr[3] = (returnValue64>>32)&0xFFFFFFFF;
hCPU->gpr[4] = (returnValue64>>0)&0xFFFFFFFF;
hCPU->instructionPointer = hCPU->spr.LR;
}
void osLib_load()
{
// load HLE modules
coreinit_load();
zlib::load();
gx2_load();
dmae_load();
padscore::load();
vpad::load();
snd_core::loadExports();
nn::erreula::load();
nnAct_load();
nn::acp::load();
nnAc_load();
nnEc_load();
nnBoss_load();
nn::nfp::load();
nnUds_load();
nn::nim::load();
nn::ndm::load();
nn::save::load();
nsysnet_load();
nn::fp::load();
nn::olv::load();
nn::idbe::load();
nlibnss::load();
nlibcurl::load();
sysapp_load();
nsyshid::load();
nsyskbd::nsyskbd_load();
swkbd::load();
camera::load();
procui_load();
}

View file

@ -0,0 +1,25 @@
#pragma once
struct PPCInterpreter_t;
#define OSLIB_FUNCTIONTABLE_TYPE_FUNCTION (1)
#define OSLIB_FUNCTIONTABLE_TYPE_POINTER (2)
void osLib_load();
void osLib_generateHashFromName(const char* name, uint32* hashA, uint32* hashB);
sint32 osLib_getFunctionIndex(const char* libraryName, const char* functionName);
uint32 osLib_getPointer(const char* libraryName, const char* functionName);
void osLib_addFunctionInternal(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU));
#define osLib_addFunction(__p1, __p2, __p3) osLib_addFunctionInternal((const char*)__p1, __p2, __p3)
void osLib_addVirtualPointer(const char* libraryName, const char* functionName, uint32 vPtr);
void osLib_returnFromFunction(PPCInterpreter_t* hCPU, uint32 returnValue);
void osLib_returnFromFunction64(PPCInterpreter_t* hCPU, uint64 returnValue64);
// libs
#include "Cafe/OS/libs/coreinit/coreinit.h"
// utility functions
#include "Cafe/OS/common/OSUtil.h"

233
src/Cafe/OS/common/OSUtil.h Normal file
View file

@ -0,0 +1,233 @@
#pragma once
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
#include "Cafe/HW/Espresso/PPCState.h"
#include "Cafe/HW/MMU/MMU.h"
#include <fmt/ostream.h>
#include <fmt/compile.h>
#include <fmt/ranges.h>
class cafeExportParamWrapper
{
public:
template <typename T>
static void getParamWrapper(PPCInterpreter_t* hCPU, int& gprIndex, int& fprIndex, T& v)
{
if constexpr (std::is_pointer_v<T>)
{
uint32be addr;
if (gprIndex >= 8)
addr = memory_readU32(hCPU->gpr[1] + 8 + (gprIndex - 8) * 4);
else
addr = hCPU->gpr[3 + gprIndex];
using TPtr = std::remove_pointer_t<T>;
v = MEMPTR<TPtr>(addr).GetPtr();
gprIndex++;
}
else if constexpr (std::is_base_of_v<MEMPTRBase, T>)
{
uint32be addr;
if (gprIndex >= 8)
addr = memory_readU32(hCPU->gpr[1] + 8 + (gprIndex - 8) * 4);
else
addr = hCPU->gpr[3 + gprIndex];
v = addr.value();
gprIndex++;
}
else if constexpr (std::is_enum_v<T>)
{
using TEnum = std::underlying_type_t<T>;
getParamWrapper<TEnum>(hCPU, gprIndex, fprIndex, (TEnum&)v);
}
else if constexpr (std::is_integral_v<T>)
{
if constexpr (sizeof(T) == sizeof(uint64))
{
gprIndex = (gprIndex + 1)&~1;
if (gprIndex >= 8)
v = (T)memory_readU64(hCPU->gpr[1] + 8 + (gprIndex - 8) * 4);
else
v = (T)(((uint64)hCPU->gpr[3 + gprIndex]) << 32) | ((uint64)hCPU->gpr[3 + gprIndex + 1]);
gprIndex += 2;
}
else
{
if (gprIndex >= 8)
v = (T)memory_readU32(hCPU->gpr[1] + 8 + (gprIndex - 8) * 4);
else
v = (T)hCPU->gpr[3 + gprIndex];
gprIndex++;
}
}
else if constexpr (std::is_floating_point_v<T>)
{
v = (T)ppcInterpreterCurrentInstance->fpr[1 + fprIndex].fpr;
fprIndex++;
}
else
{
assert_dbg();
}
}
template<typename T>
static void setReturnResult(PPCInterpreter_t* hCPU, T r)
{
if constexpr (std::is_pointer_v<T>)
{
hCPU->gpr[3] = MEMPTR(r).GetMPTR();
}
else if constexpr (std::is_reference_v<T>)
{
hCPU->gpr[3] = MEMPTR(&r).GetMPTR();
}
else if constexpr (std::is_enum_v<T>)
{
using TEnum = std::underlying_type_t<T>;
setReturnResult<TEnum>(hCPU, (TEnum)r);
}
else if constexpr (std::is_integral_v<T>)
{
if constexpr(sizeof(T) == 8)
{
const auto t = static_cast<uint64>(r);
hCPU->gpr[3] = (uint32)(t >> 32); // high
hCPU->gpr[4] = (uint32)(t); // low
}
else
{
hCPU->gpr[3] = (uint32)r;
}
}
else
{
cemu_assert_unimplemented();
//static_assert(false);
}
}
template<typename T>
static auto getFormatResult(T r)
{
if constexpr (std::is_pointer_v<T>)
return MEMPTR(r).GetMPTR();
else if constexpr (std::is_enum_v<T>)
return static_cast<std::underlying_type_t<T>>(r);
else if constexpr(!std::is_fundamental_v<T>)
return MEMPTR(&r).GetMPTR();
else
return r;
}
};
template<typename T>
T cafeExportGetParamWrapper(PPCInterpreter_t* hCPU, int& gprIndex, int& fprIndex)
{
T v;
cafeExportParamWrapper::getParamWrapper(hCPU, gprIndex, fprIndex, v);
return v;
}
template <typename R, typename ... Args>
static std::tuple<Args...> cafeExportBuildArgTuple(PPCInterpreter_t* hCPU, R(fn)(Args...))
{
int gprIndex = 0;
int fprIndex = 0;
return std::tuple<Args...>{ cafeExportGetParamWrapper<Args>(hCPU, gprIndex, fprIndex)... };
}
template<typename T>
using _CAFE_FORMAT_ARG = std::conditional_t<std::is_pointer_v<T>,
std::conditional_t<std::is_same_v<T, char*> || std::is_same_v<T, const char*>, T, MEMPTR<T>>, T>;
template <typename R, typename... Args>
static auto cafeExportBuildFormatTuple(PPCInterpreter_t* hCPU, R(fn)(Args...))
{
int gprIndex = 0;
int fprIndex = 0;
return std::tuple<_CAFE_FORMAT_ARG<Args>...>{
cafeExportGetParamWrapper<_CAFE_FORMAT_ARG<Args>>(hCPU, gprIndex, fprIndex)...
};
}
template<auto fn, typename TNames, LogType TLogType>
void cafeExportCallWrapper(PPCInterpreter_t* hCPU)
{
auto tup = cafeExportBuildArgTuple(hCPU, fn);
bool shouldLog = false;
if (cemuLog_isLoggingEnabled(TLogType))
{
const auto format_tup = cafeExportBuildFormatTuple(hCPU, fn);
if(cemuLog_advancedPPCLoggingEnabled())
{
MPTR threadMPTR = memory_getVirtualOffsetFromPointer(coreinit::OSGetCurrentThread());
if constexpr (std::tuple_size<decltype(format_tup)>::value > 0)
shouldLog = cemuLog_log(TLogType, "{}.{}{} # LR: {:#x} | Thread: {:#x}", TNames::GetLib(), TNames::GetFunc(), format_tup, hCPU->spr.LR, threadMPTR);
else
shouldLog = cemuLog_log(TLogType, "{}.{}() # LR: {:#x} | Thread: {:#x}", TNames::GetLib(), TNames::GetFunc(), hCPU->spr.LR, threadMPTR);
}
else
{
if constexpr (std::tuple_size<decltype(format_tup)>::value > 0)
{
shouldLog = cemuLog_log(TLogType, "{}.{}{}", TNames::GetLib(), TNames::GetFunc(), format_tup);
}
else
shouldLog = cemuLog_log(TLogType, "{}.{}()", TNames::GetLib(), TNames::GetFunc());
}
}
if constexpr (!std::is_void<decltype(std::apply(fn, tup))>::value)
{
// has non-void return type
decltype(auto) result = std::apply(fn, tup);
cafeExportParamWrapper::setReturnResult<decltype(std::apply(fn, tup))>(hCPU, result);
if(shouldLog)
cemuLog_log(TLogType, "\t\t{}.{} -> {}", TNames::GetLib(), TNames::GetFunc(), cafeExportParamWrapper::getFormatResult(result));
}
else
{
// return type is void
std::apply(fn, tup);
}
// return from func
hCPU->instructionPointer = hCPU->spr.LR;
}
void osLib_addFunctionInternal(const char* libraryName, const char* functionName, void(*osFunction)(PPCInterpreter_t* hCPU));
template<auto fn, typename TNames, LogType TLogType>
void cafeExportMakeWrapper(const char* libname, const char* funcname)
{
osLib_addFunctionInternal(libname, funcname, &cafeExportCallWrapper<fn, TNames, TLogType>);
}
#define cafeExportRegister(__libname, __func, __logtype) \
{ \
struct StringWrapper { \
static const char* GetLib() { return __libname; }; \
static const char* GetFunc() { return #__func; }; \
}; \
cafeExportMakeWrapper<__func, StringWrapper, __logtype>(__libname, # __func);\
}
#define cafeExportRegisterFunc(__func, __libname, __funcname, __logtype) \
{\
struct StringWrapper { \
static const char* GetLib() { return __libname; }; \
static const char* GetFunc() { return __funcname; }; \
}; \
cafeExportMakeWrapper<__func, StringWrapper, __logtype>(__libname, __funcname);\
}
template<auto fn>
MPTR makeCallableExport()
{
return PPCInterpreter_makeCallableExportDepr(&cafeExportCallWrapper<fn, "CALLABLE_EXPORT">);
}
void osLib_addVirtualPointer(const char* libraryName, const char* functionName, uint32 vPtr);

View file

@ -0,0 +1,68 @@
#pragma once
#include <mutex>
#include <condition_variable>
#include <queue>
#include "Cafe/OS/libs/coreinit/coreinit_Thread.h"
template <typename T>
class PPCConcurrentQueue
{
public:
PPCConcurrentQueue() {}
PPCConcurrentQueue(const PPCConcurrentQueue&) = delete;
PPCConcurrentQueue& operator=(const PPCConcurrentQueue&) = delete;
void push(const T& item, OSThread_t* thread)
{
//if(thread == nullptr)
// thread = coreinitThread_getCurrentThread(ppcInterpreterCurrentInstance);
//OSThread_t* currentThread = coreinit::OSGetCurrentThread();
//cemu_assert_debug(thread == nullptr || currentThread == thread);
// forceLogDebug_printf("push suspend count: %d", _swapEndianU32(thread->suspend) - m_suspendCount);
//__OSLockScheduler();
__OSLockScheduler();
m_queue.push(item);
coreinit::__OSResumeThreadInternal(thread, 1);
__OSUnlockScheduler();
//__OSUnlockScheduler();
//m_prevSuspendCount = _swapEndianU32(thread->suspend) - m_suspendCount;
//coreinit_resumeThread(thread, _swapEndianU32(thread->suspend));
}
T pop(OSThread_t* thread = nullptr)
{
//if (thread == nullptr)
// thread = coreinitThread_getCurrentThread(ppcInterpreterCurrentInstance);
OSThread_t* currentThread = coreinit::OSGetCurrentThread();
cemu_assert_debug(thread == nullptr || currentThread == thread);
//thread = coreinitThread_getCurrentThread(ppcInterpreterCurrentInstance);
// forceLogDebug_printf("pop suspend count: %d", _swapEndianU32(thread->suspend) + m_suspendCount);
__OSLockScheduler();
if (m_queue.empty())
coreinit::__OSSuspendThreadInternal(thread);
auto val = m_queue.front();
m_queue.pop();
__OSUnlockScheduler();
//coreinit_suspendThread(thread, m_suspendCount + m_prevSuspendCount);
//m_prevSuspendCount = 0;
//PPCCore_switchToScheduler();
return val;
}
private:
//const int m_suspendCount = 8000;
std::queue<T> m_queue;
//std::atomic<uint32> m_prevSuspendCount;
};