rpcsx/rpcs3/Emu/SysCalls/Modules.h

171 lines
3.7 KiB
C
Raw Normal View History

#pragma once
2014-07-11 21:59:13 +10:00
#include "Emu/SysCalls/SC_FUNC.h"
#include "Emu/IdManager.h"
2014-08-23 18:51:51 +04:00
#include "ErrorCodes.h"
#include "LogBase.h"
class Module;
struct ModuleFunc
{
u32 id;
Module* module;
2015-02-20 20:58:15 +03:00
ps3_func_caller func;
2015-01-28 15:59:16 +03:00
vm::ptr<void()> lle_func;
2015-02-20 20:58:15 +03:00
ModuleFunc(u32 id, Module* module, ps3_func_caller func, vm::ptr<void()> lle_func = vm::ptr<void()>::make(0))
: id(id)
, module(module)
, func(func)
2014-11-29 15:16:53 +02:00
, lle_func(lle_func)
{
}
};
2014-03-06 15:40:50 +04:00
struct SFuncOp
{
u32 crc;
u32 mask;
};
struct SFunc
{
2015-02-19 22:17:30 +03:00
u32 index;
const char* name;
std::vector<SFuncOp> ops;
u64 group;
u32 found;
2014-03-06 15:40:50 +04:00
};
2014-08-23 18:51:51 +04:00
class StaticFuncManager;
class Module : public LogBase
{
2014-02-02 22:47:17 +02:00
std::string m_name;
bool m_is_loaded;
void(*m_init)();
2014-08-22 20:54:53 +04:00
IdManager& GetIdManager() const;
2014-08-23 18:51:51 +04:00
void PushNewFuncSub(SFunc* func);
2014-08-22 20:54:53 +04:00
Module() = delete;
public:
Module(const char* name, void(*init)());
Module(Module &other) = delete;
Module(Module &&other) = delete;
Module &operator =(Module &other) = delete;
Module &operator =(Module &&other) = delete;
~Module();
std::function<void()> on_load;
std::function<void()> on_unload;
std::function<void()> on_stop;
void Init();
void Load();
void Unload();
void SetLoaded(bool loaded = true);
bool IsLoaded() const;
virtual const std::string& GetName() const override;
2014-02-02 22:47:17 +02:00
void SetName(const std::string& name);
public:
bool CheckID(u32 id) const;
2014-12-24 02:38:13 +03:00
template<typename T> bool CheckId(u32 id, std::shared_ptr<T>& data)
{
ID* id_data;
if(!CheckID(id, id_data)) return false;
data = id_data->GetData()->get<T>();
return true;
}
2014-12-24 02:38:13 +03:00
template<typename T> bool CheckId(u32 id, std::shared_ptr<T>& data, IDType& type)
{
ID* id_data;
if(!CheckID(id, id_data)) return false;
data = id_data->GetData()->get<T>();
type = id_data->GetType();
return true;
}
2014-12-24 02:38:13 +03:00
bool CheckID(u32 id, ID*& _id) const;
template<typename T>
2014-12-24 02:38:13 +03:00
u32 GetNewId(std::shared_ptr<T>& data, IDType type = TYPE_OTHER)
{
2014-08-22 20:54:53 +04:00
return GetIdManager().GetNewID<T>(GetName(), data, type);
}
2014-08-24 00:40:04 +04:00
bool RemoveId(u32 id);
2015-02-20 20:58:15 +03:00
template<void* func, typename T> __forceinline u32 AddFunc(const u32 nid, T _func);
template<void* func, typename T> __forceinline u32 AddFunc(const char* name, T _func);
template<void* func, typename T> __forceinline u32 AddFuncSub(const char group[8], const u64 ops[], const char* name, T _func);
};
2015-02-18 19:28:09 +03:00
u32 add_ps3_func(ModuleFunc func);
ModuleFunc* get_ps3_func_by_nid(u32 nid, u32* out_index = nullptr);
ModuleFunc* get_ps3_func_by_index(u32 index);
void execute_ps3_func_by_index(PPUThread& CPU, u32 id);
void clear_ps3_functions();
u32 get_function_id(const char* name);
2015-02-20 20:58:15 +03:00
template<void* func, typename T>
__forceinline u32 Module::AddFunc(const u32 nid, T _func)
{
return add_ps3_func(ModuleFunc(nid, this, ppu_func_detail::_bind_func<func>(_func)));
}
2015-02-20 20:58:15 +03:00
template<void* func, typename T>
__forceinline u32 Module::AddFunc(const char* name, T _func)
{
return AddFunc<func>(get_function_id(name), _func);
}
2015-02-20 20:58:15 +03:00
template<void* func, typename T>
__forceinline u32 Module::AddFuncSub(const char group[8], const u64 ops[], const char* name, T _func)
2014-03-06 15:40:50 +04:00
{
SFunc* sf = new SFunc;
sf->index = AddFunc<func>(name, _func);
2014-03-06 15:40:50 +04:00
sf->name = name;
sf->group = *(u64*)group;
sf->found = 0;
2014-03-06 15:40:50 +04:00
// TODO: check for self-inclusions, use CRC
for (u32 i = 0; ops[i]; i++)
{
SFuncOp op;
op.mask = ops[i] >> 32;
2014-08-31 00:41:01 +04:00
op.crc = (u32)ops[i];
if (op.mask) op.crc &= op.mask;
op.mask = re32(op.mask);
op.crc = re32(op.crc);
sf->ops.push_back(op);
2014-03-06 15:40:50 +04:00
}
2014-08-23 18:51:51 +04:00
PushNewFuncSub(sf);
return sf->index;
2014-03-06 15:40:50 +04:00
}
2014-08-23 18:51:51 +04:00
#define REG_SUB(module, group, name, ...) \
static const u64 name ## _table[] = {__VA_ARGS__ , 0}; \
2015-02-20 20:58:15 +03:00
if (name ## _table[0]) module.AddFuncSub<_targ(name)>(group, name ## _table, #name, name)
2014-08-23 18:51:51 +04:00
2015-02-20 20:58:15 +03:00
#define REG_FUNC(module, name) module.AddFunc<_targ(name)>(#name, name)
2014-08-23 18:51:51 +04:00
2015-02-19 14:18:28 +03:00
#define UNIMPLEMENTED_FUNC(module) module.Error("%s", __FUNCTION__)