mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
Fixed conflicts
This commit is contained in:
commit
d16dbedaa1
@ -63,7 +63,7 @@ public:
|
||||
FromBE(value.ToBE());
|
||||
}
|
||||
|
||||
T ToBE() const
|
||||
const T& ToBE() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
@ -1,21 +1,58 @@
|
||||
#pragma once
|
||||
#include "Array.h"
|
||||
#include <unordered_map>
|
||||
|
||||
typedef u32 ID_TYPE;
|
||||
|
||||
class IDData
|
||||
{
|
||||
protected:
|
||||
void* m_ptr;
|
||||
std::function<void(void*)> m_destr;
|
||||
|
||||
public:
|
||||
IDData(void* ptr, std::function<void(void*)> destr)
|
||||
: m_ptr(ptr)
|
||||
, m_destr(destr)
|
||||
{
|
||||
}
|
||||
|
||||
~IDData()
|
||||
{
|
||||
m_destr(m_ptr);
|
||||
}
|
||||
|
||||
template<typename T> T* get()
|
||||
{
|
||||
return (T*)m_ptr;
|
||||
}
|
||||
|
||||
template<typename T> const T* get() const
|
||||
{
|
||||
return (const T*)m_ptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct ID
|
||||
{
|
||||
bool m_used;
|
||||
wxString m_name;
|
||||
u8 m_attr;
|
||||
void* m_data;
|
||||
IDData* m_data;
|
||||
|
||||
ID(bool used = false, const wxString& name = wxEmptyString, void* data = NULL, const u8 attr = 0)
|
||||
: m_used(used)
|
||||
, m_name(name)
|
||||
, m_data(data)
|
||||
template<typename T>
|
||||
ID(const wxString& name, T* data, const u8 attr)
|
||||
: m_name(name)
|
||||
, m_attr(attr)
|
||||
{
|
||||
m_data = new IDData(data, [](void *ptr) -> void { delete (T*)ptr; });
|
||||
}
|
||||
|
||||
ID() : m_data(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void Kill()
|
||||
{
|
||||
delete m_data;
|
||||
}
|
||||
};
|
||||
|
||||
@ -23,21 +60,16 @@ class IdManager
|
||||
{
|
||||
ArrayF<ID> IDs;
|
||||
|
||||
static const u64 first_id = 1;
|
||||
static const ID_TYPE s_first_id = 1;
|
||||
static const ID_TYPE s_max_id = -1;
|
||||
|
||||
std::unordered_map<ID_TYPE, ID> m_id_map;
|
||||
std::mutex m_mtx_main;
|
||||
|
||||
ID_TYPE m_cur_id;
|
||||
|
||||
void Cleanup()
|
||||
{
|
||||
while(IDs.GetCount())
|
||||
{
|
||||
const u32 num = IDs.GetCount()-1;
|
||||
ID& id = IDs[num];
|
||||
if(id.m_used) break;
|
||||
IDs.RemoveAt(num);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
IdManager()
|
||||
IdManager() : m_cur_id(s_first_id)
|
||||
{
|
||||
}
|
||||
|
||||
@ -45,92 +77,82 @@ public:
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
static ID_TYPE GetMaxID()
|
||||
{
|
||||
return (ID_TYPE)-1;
|
||||
}
|
||||
|
||||
bool CheckID(const u64 id)
|
||||
{
|
||||
if(id == 0 || id > (u64)NumToID(IDs.GetCount()-1) || id >= GetMaxID()) return false;
|
||||
|
||||
return IDs[IDToNum(id)].m_used;
|
||||
}
|
||||
|
||||
__forceinline const ID_TYPE NumToID(const ID_TYPE num) const
|
||||
bool CheckID(const ID_TYPE id)
|
||||
{
|
||||
return num + first_id;
|
||||
}
|
||||
|
||||
__forceinline const ID_TYPE IDToNum(const ID_TYPE id) const
|
||||
{
|
||||
return id - first_id;
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
return m_id_map.find(id) != m_id_map.end();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
IDs.Clear();
|
||||
}
|
||||
|
||||
virtual ID_TYPE GetNewID(const wxString& name = wxEmptyString, void* data = NULL, const u8 attr = 0)
|
||||
{
|
||||
for(uint i=0; i<IDs.GetCount(); ++i)
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
for(auto& i : m_id_map)
|
||||
{
|
||||
if(IDs[i].m_used) continue;
|
||||
return NumToID(i);
|
||||
i.second.Kill();
|
||||
}
|
||||
|
||||
const ID_TYPE pos = IDs.GetCount();
|
||||
if(NumToID(pos) >= GetMaxID()) return 0;
|
||||
IDs.Add(new ID(true, name, data, attr));
|
||||
return NumToID(pos);
|
||||
m_id_map.clear();
|
||||
m_cur_id = s_first_id;
|
||||
}
|
||||
|
||||
ID& GetIDData(const ID_TYPE _id)
|
||||
template<typename T>
|
||||
ID_TYPE GetNewID(const wxString& name = wxEmptyString, T* data = nullptr, const u8 attr = 0)
|
||||
{
|
||||
//if(!CheckID(_id)) return IDs.Get(0); //TODO
|
||||
return IDs[IDToNum(_id)];
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
bool GetFirst(ID& dst, ID_TYPE* _id = NULL)
|
||||
m_id_map[m_cur_id] = std::move(ID(name, data, attr));
|
||||
|
||||
return m_cur_id++;
|
||||
}
|
||||
|
||||
ID& GetID(const ID_TYPE id)
|
||||
{
|
||||
u32 pos = 0;
|
||||
return GetNext(pos, dst, _id);
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
return m_id_map[id];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GetIDData(const ID_TYPE id, T*& result)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
auto f = m_id_map.find(id);
|
||||
|
||||
if(f == m_id_map.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
result = f->second.m_data->get<T>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasID(const s64 id)
|
||||
{
|
||||
if(id == wxID_ANY) return IDs.GetCount() != 0;
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
if(id == wxID_ANY)
|
||||
return m_id_map.begin() != m_id_map.end();
|
||||
|
||||
return CheckID(id);
|
||||
}
|
||||
|
||||
bool GetNext(u32& pos, ID& dst, ID_TYPE* _id = NULL)
|
||||
bool RemoveID(const ID_TYPE id)
|
||||
{
|
||||
while(pos < IDs.GetCount())
|
||||
{
|
||||
ID& id = IDs[pos++];
|
||||
if(!id.m_used) continue;
|
||||
dst = id;
|
||||
if(_id) *_id = NumToID(pos - 1);
|
||||
return true;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(m_mtx_main);
|
||||
|
||||
return false;
|
||||
}
|
||||
auto item = m_id_map.find(id);
|
||||
|
||||
if(item == m_id_map.end()) return false;
|
||||
|
||||
item->second.Kill();
|
||||
m_id_map.erase(item);
|
||||
|
||||
virtual bool RemoveID(const ID_TYPE _id, bool free_data = true)
|
||||
{
|
||||
if(!CheckID(_id)) return false;
|
||||
ID& id = IDs[IDToNum(_id)];
|
||||
if(!id.m_used) return false;
|
||||
id.m_used = false;
|
||||
id.m_attr = 0;
|
||||
id.m_name.Clear();
|
||||
if(free_data) delete id.m_data;
|
||||
id.m_data = NULL;
|
||||
if(IDToNum(_id) == IDs.GetCount()-1) Cleanup();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
@ -32,14 +32,13 @@ void CPUThread::Close()
|
||||
if(IsAlive())
|
||||
{
|
||||
m_free_data = true;
|
||||
ThreadBase::Stop(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_dec;
|
||||
m_dec = nullptr;
|
||||
}
|
||||
|
||||
Stop();
|
||||
}
|
||||
|
||||
void CPUThread::Reset()
|
||||
|
@ -66,20 +66,20 @@ void CPUThreadManager::RemoveThread(const u32 id)
|
||||
#endif
|
||||
if(thr->IsAlive())
|
||||
{
|
||||
thr->Close();
|
||||
//thr->Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
thr->Close();
|
||||
delete thr;
|
||||
//thr->Close();
|
||||
//delete thr;
|
||||
}
|
||||
|
||||
|
||||
m_threads.RemoveFAt(i);
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(id, false);
|
||||
Emu.GetIdManager().RemoveID(id);
|
||||
Emu.CheckStatus();
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,11 @@ private:
|
||||
SysCalls::DoSyscall(CPU.GPR[11]);
|
||||
|
||||
if(enable_log)
|
||||
{
|
||||
ConLog.Warning("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC);
|
||||
if(CPU.GPR[11] > 1024)
|
||||
SysCalls::DoFunc(CPU.GPR[11]);
|
||||
}
|
||||
#ifdef HLE_CALL_DEBUG
|
||||
ConLog.Write("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC);
|
||||
#endif
|
||||
|
@ -3,22 +3,25 @@
|
||||
|
||||
RawSPUThread::RawSPUThread(u32 index, CPUThreadType type)
|
||||
: SPUThread(type)
|
||||
, MemoryBlock()
|
||||
, m_index(index)
|
||||
{
|
||||
Memory.MemoryBlocks.Add(MemoryBlock::SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_OFFSET));
|
||||
Memory.MemoryBlocks.push_back(SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_OFFSET));
|
||||
Reset();
|
||||
}
|
||||
|
||||
RawSPUThread::~RawSPUThread()
|
||||
{
|
||||
for(int i=0; i<Memory.MemoryBlocks.GetCount(); ++i)
|
||||
for(int i=0; i<Memory.MemoryBlocks.size(); ++i)
|
||||
{
|
||||
if(&Memory.MemoryBlocks[i] == this)
|
||||
if(Memory.MemoryBlocks[i]->GetStartAddr() == GetStartAddr())
|
||||
{
|
||||
Memory.MemoryBlocks.RemoveFAt(i);
|
||||
return;
|
||||
Memory.MemoryBlocks.erase(Memory.MemoryBlocks.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
bool RawSPUThread::Read8(const u64 addr, u8* value)
|
||||
|
@ -42,12 +42,18 @@ u32 vfsDevice::CmpPs3Path(const wxString& ps3_path)
|
||||
|
||||
u32 vfsDevice::CmpLocalPath(const wxString& local_path)
|
||||
{
|
||||
if(local_path.Len() < m_local_path.Len())
|
||||
return 0;
|
||||
|
||||
const u32 lim = min(m_local_path.Len(), local_path.Len());
|
||||
u32 ret = 0;
|
||||
|
||||
for(u32 i=0; i<lim; ++i, ++ret)
|
||||
{
|
||||
if(m_local_path[i] != local_path[i]) break;
|
||||
if(m_local_path[i] != local_path[i])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -87,6 +93,7 @@ wxString vfsDevice::ErasePath(const wxString& path, u32 start_dir_count, u32 end
|
||||
|
||||
wxString vfsDevice::GetRoot(const wxString& path)
|
||||
{
|
||||
//return wxFileName(path, wxPATH_UNIX).GetPath();
|
||||
if(path.IsEmpty()) return wxEmptyString;
|
||||
|
||||
u32 first_dir = path.Len() - 1;
|
||||
|
@ -45,7 +45,7 @@ bool vfsLocalFile::Open(const wxString& path, vfsOpenMode mode)
|
||||
{
|
||||
Close();
|
||||
|
||||
if(mode == vfsRead && !m_file.Access(vfsDevice::GetWinPath(GetLocalPath(), path), vfs2wx_mode(mode))) return false;
|
||||
if(!m_file.Access(vfsDevice::GetWinPath(GetLocalPath(), path), vfs2wx_mode(mode))) return false;
|
||||
|
||||
return m_file.Open(vfsDevice::GetWinPath(GetLocalPath(), path), vfs2wx_mode(mode)) &&
|
||||
vfsFileBase::Open(vfsDevice::GetPs3Path(GetPs3Path(), path), mode);
|
||||
@ -53,10 +53,31 @@ bool vfsLocalFile::Open(const wxString& path, vfsOpenMode mode)
|
||||
|
||||
bool vfsLocalFile::Create(const wxString& path)
|
||||
{
|
||||
if(wxFileExists(path)) return false;
|
||||
ConLog.Warning("vfsLocalFile::Create('%s')", path.c_str());
|
||||
for(uint p=1;p<path.Length();p++)
|
||||
{
|
||||
for(; path[p] != '\0'; p++)
|
||||
if(path[p] == '\\') break;
|
||||
|
||||
wxFile f;
|
||||
return f.Create(path);
|
||||
if(path[p] == '\0')
|
||||
break;
|
||||
|
||||
const wxString& dir = path(0, p);
|
||||
if(!wxDirExists(dir))
|
||||
{
|
||||
ConLog.Write("create dir: %s", dir.c_str());
|
||||
wxMkdir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
//create file
|
||||
if(path(path.Len() - 1, 1) != '\\' && !wxFileExists(path))
|
||||
{
|
||||
wxFile f;
|
||||
return f.Create(path);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vfsLocalFile::Close()
|
||||
|
@ -15,6 +15,7 @@ gcmBuffer gcmBuffers[8];
|
||||
|
||||
int last_width = 0, last_height = 0, last_depth_format = 0;
|
||||
|
||||
GLenum g_last_gl_error = GL_NO_ERROR;
|
||||
void printGlError(GLenum err, const char* situation)
|
||||
{
|
||||
if(err != GL_NO_ERROR)
|
||||
@ -24,11 +25,6 @@ void printGlError(GLenum err, const char* situation)
|
||||
}
|
||||
}
|
||||
|
||||
void checkForGlError(const char* situation)
|
||||
{
|
||||
printGlError(glGetError(), situation);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define checkForGlError(x) /*x*/
|
||||
#endif
|
||||
@ -415,25 +411,6 @@ bool GLGSRender::LoadProgram()
|
||||
m_prog_buffer.Add(m_program, m_shader_prog, *m_cur_shader_prog, m_vertex_prog, *m_cur_vertex_prog);
|
||||
checkForGlError("m_prog_buffer.Add");
|
||||
m_program.Use();
|
||||
|
||||
GLint r = GL_FALSE;
|
||||
glGetProgramiv(m_program.id, GL_VALIDATE_STATUS, &r);
|
||||
if(r != GL_TRUE)
|
||||
{
|
||||
glGetProgramiv(m_program.id, GL_INFO_LOG_LENGTH, &r);
|
||||
|
||||
if(r)
|
||||
{
|
||||
char* buf = new char[r+1];
|
||||
GLsizei len;
|
||||
memset(buf, 0, r+1);
|
||||
glGetProgramInfoLog(m_program.id, r, &len, buf);
|
||||
ConLog.Error("Failed to validate program: %s", buf);
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
Emu.Pause();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -639,6 +616,7 @@ void GLGSRender::OnReset()
|
||||
|
||||
void GLGSRender::ExecCMD()
|
||||
{
|
||||
//return;
|
||||
if(!LoadProgram())
|
||||
{
|
||||
ConLog.Error("LoadProgram failed.");
|
||||
@ -1085,5 +1063,13 @@ void GLGSRender::Flip()
|
||||
m_fbo.Bind();
|
||||
}
|
||||
|
||||
for(uint i=0; i<m_post_draw_objs.GetCount(); ++i)
|
||||
{
|
||||
m_post_draw_objs[i].Draw();
|
||||
}
|
||||
|
||||
m_frame->Flip();
|
||||
|
||||
if(m_fbo.IsCreated())
|
||||
m_fbo.Bind();
|
||||
}
|
||||
|
@ -10,8 +10,16 @@
|
||||
#pragma comment(lib, "opengl32.lib")
|
||||
#pragma comment(lib, "gl.lib")
|
||||
|
||||
#define RSX_DEBUG 1
|
||||
|
||||
extern GLenum g_last_gl_error;
|
||||
void printGlError(GLenum err, const char* situation);
|
||||
void checkForGlError(const char* situation);
|
||||
|
||||
#if RSX_DEBUG
|
||||
#define checkForGlError(sit) if((g_last_gl_error = glGetError()) != GL_NO_ERROR) printGlError(g_last_gl_error, sit)
|
||||
#else
|
||||
#define checkForGlError(sit)
|
||||
#endif
|
||||
|
||||
class GLTexture
|
||||
{
|
||||
@ -324,6 +332,10 @@ public:
|
||||
s_is_initialized = true;
|
||||
Initialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_program.Use();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void InitializeShaders() = 0;
|
||||
@ -340,25 +352,107 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DrawCursorObj : PostDrawObj
|
||||
class DrawCursorObj : public PostDrawObj
|
||||
{
|
||||
u32 m_tex_id;
|
||||
void* m_pixels;
|
||||
u32 m_width, m_height;
|
||||
double m_pos_x, m_pos_y, m_pos_z;
|
||||
bool m_update_texture, m_update_pos;
|
||||
|
||||
public:
|
||||
DrawCursorObj() : m_tex_id(0)
|
||||
DrawCursorObj() : PostDrawObj()
|
||||
, m_tex_id(0)
|
||||
, m_update_texture(false)
|
||||
, m_update_pos(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Draw()
|
||||
{
|
||||
checkForGlError("PostDrawObj : Unknown error.");
|
||||
|
||||
PostDrawObj::Draw();
|
||||
checkForGlError("PostDrawObj::Draw");
|
||||
|
||||
if(!m_fbo.IsCreated())
|
||||
{
|
||||
m_fbo.Create();
|
||||
checkForGlError("DrawCursorObj : m_fbo.Create");
|
||||
m_fbo.Bind();
|
||||
checkForGlError("DrawCursorObj : m_fbo.Bind");
|
||||
|
||||
m_rbo.Create();
|
||||
checkForGlError("DrawCursorObj : m_rbo.Create");
|
||||
m_rbo.Bind();
|
||||
checkForGlError("DrawCursorObj : m_rbo.Bind");
|
||||
m_rbo.Storage(GL_RGBA, m_width, m_height);
|
||||
checkForGlError("DrawCursorObj : m_rbo.Storage");
|
||||
|
||||
m_fbo.Renderbuffer(GL_COLOR_ATTACHMENT0, m_rbo.GetId());
|
||||
checkForGlError("DrawCursorObj : m_fbo.Renderbuffer");
|
||||
}
|
||||
|
||||
m_fbo.Bind();
|
||||
checkForGlError("DrawCursorObj : m_fbo.Bind");
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
checkForGlError("DrawCursorObj : glDrawBuffer");
|
||||
|
||||
m_program.Use();
|
||||
checkForGlError("DrawCursorObj : m_program.Use");
|
||||
|
||||
if(m_update_texture)
|
||||
{
|
||||
//m_update_texture = false;
|
||||
|
||||
glUniform2f(m_program.GetLocation("in_tc"), m_width, m_height);
|
||||
checkForGlError("DrawCursorObj : glUniform2f");
|
||||
if(!m_tex_id)
|
||||
{
|
||||
glGenTextures(1, &m_tex_id);
|
||||
checkForGlError("DrawCursorObj : glGenTextures");
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
checkForGlError("DrawCursorObj : glActiveTexture");
|
||||
glBindTexture(GL_TEXTURE_2D, m_tex_id);
|
||||
checkForGlError("DrawCursorObj : glBindTexture");
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
|
||||
checkForGlError("DrawCursorObj : glTexImage2D");
|
||||
m_program.SetTex(0);
|
||||
}
|
||||
|
||||
if(m_update_pos)
|
||||
{
|
||||
//m_update_pos = false;
|
||||
|
||||
glUniform4f(m_program.GetLocation("in_pos"), m_pos_x, m_pos_y, m_pos_z, 1.0f);
|
||||
checkForGlError("DrawCursorObj : glUniform4f");
|
||||
}
|
||||
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
checkForGlError("DrawCursorObj : glDrawArrays");
|
||||
|
||||
m_fbo.Bind(GL_READ_FRAMEBUFFER);
|
||||
checkForGlError("DrawCursorObj : m_fbo.Bind(GL_READ_FRAMEBUFFER)");
|
||||
GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0);
|
||||
checkForGlError("DrawCursorObj : GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0)");
|
||||
GLfbo::Blit(
|
||||
0, 0, m_width, m_height,
|
||||
0, 0, m_width, m_height,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
checkForGlError("DrawCursorObj : GLfbo::Blit");
|
||||
m_fbo.Bind();
|
||||
checkForGlError("DrawCursorObj : m_fbo.Bind");
|
||||
}
|
||||
|
||||
virtual void InitializeShaders()
|
||||
{
|
||||
m_vp.shader =
|
||||
"layout (location = 0) in vec4 in_pos;\n"
|
||||
"layout (location = 1) in vec2 in_tc;\n"
|
||||
"#version 330\n"
|
||||
"\n"
|
||||
"uniform vec4 in_pos;\n"
|
||||
"uniform vec2 in_tc;\n"
|
||||
"out vec2 tc;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
@ -371,36 +465,35 @@ public:
|
||||
"#version 330\n"
|
||||
"\n"
|
||||
"in vec2 tc;\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform sampler2D tex0;\n"
|
||||
"layout (location = 0) out vec4 res;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" res = texture(tex, tc);\n"
|
||||
" res = texture(tex0, tc);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
void SetTexture(void* pixels, int width, int hight)
|
||||
void SetTexture(void* pixels, int width, int height)
|
||||
{
|
||||
glUniform2i(1, width, hight);
|
||||
if(!m_tex_id)
|
||||
{
|
||||
glGenTextures(1, &m_tex_id);
|
||||
}
|
||||
m_pixels = pixels;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_tex_id);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, hight, 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels);
|
||||
m_program.SetTex(0);
|
||||
m_update_texture = true;
|
||||
}
|
||||
|
||||
void SetPosition(float x, float y, float z = 0.0f)
|
||||
{
|
||||
glUniform4f(0, x, y, z, 1.0f);
|
||||
m_pos_x = x;
|
||||
m_pos_y = y;
|
||||
m_pos_z = z;
|
||||
m_update_pos = true;
|
||||
}
|
||||
|
||||
void InitializeLocations()
|
||||
{
|
||||
//ConLog.Warning("tex0 location = 0x%x", m_program.GetLocation("tex0"));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -89,7 +89,6 @@ void GLProgram::Use()
|
||||
void GLProgram::SetTex(u32 index)
|
||||
{
|
||||
int loc = GetLocation(wxString::Format("tex%u", index));
|
||||
checkForGlError(wxString::Format("GetLocation(tex%u)", index));
|
||||
glProgramUniform1i(id, loc, index);
|
||||
checkForGlError(wxString::Format("SetTex(%u - %d - %d)", id, index, loc));
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
|
||||
//DynamicMemoryBlockBase
|
||||
template<typename PT>
|
||||
DynamicMemoryBlockBase<PT>::DynamicMemoryBlockBase() : m_max_size(0)
|
||||
DynamicMemoryBlockBase<PT>::DynamicMemoryBlockBase()
|
||||
: PT()
|
||||
, m_max_size(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Memory.h"
|
||||
#include "MemoryBlock.h"
|
||||
#include <atomic>
|
||||
|
||||
MemoryBase Memory;
|
||||
|
||||
@ -27,14 +28,14 @@ void MemoryBlock::InitMemory()
|
||||
{
|
||||
if(!range_size) return;
|
||||
|
||||
safe_delete(mem);
|
||||
if(mem) safe_free(mem);
|
||||
mem = (u8*)malloc(range_size);
|
||||
memset(mem, 0, range_size);
|
||||
}
|
||||
|
||||
void MemoryBlock::Delete()
|
||||
{
|
||||
safe_delete(mem);
|
||||
if(mem) safe_free(mem);
|
||||
Init();
|
||||
}
|
||||
|
||||
@ -98,24 +99,28 @@ __forceinline const u8 MemoryBlock::FastRead8(const u64 addr) const
|
||||
|
||||
__forceinline const u16 MemoryBlock::FastRead16(const u64 addr) const
|
||||
{
|
||||
return ((u16)FastRead8(addr) << 8) | (u16)FastRead8(addr + 1);
|
||||
volatile const u16 data = *(u16*)GetMem(addr);
|
||||
return re(data);
|
||||
}
|
||||
|
||||
__forceinline const u32 MemoryBlock::FastRead32(const u64 addr) const
|
||||
{
|
||||
return ((u32)FastRead16(addr) << 16) | (u32)FastRead16(addr + 2);
|
||||
volatile const u32 data = *(u32*)GetMem(addr);
|
||||
return re(data);
|
||||
}
|
||||
|
||||
__forceinline const u64 MemoryBlock::FastRead64(const u64 addr) const
|
||||
{
|
||||
return ((u64)FastRead32(addr) << 32) | (u64)FastRead32(addr + 4);
|
||||
volatile const u64 data = *(u64*)GetMem(addr);
|
||||
return re(data);
|
||||
}
|
||||
|
||||
__forceinline const u128 MemoryBlock::FastRead128(const u64 addr)
|
||||
{
|
||||
volatile const u128 data = *(u128*)GetMem(addr);
|
||||
u128 ret;
|
||||
ret.lo = FastRead64(addr);
|
||||
ret.hi = FastRead64(addr + 8);
|
||||
ret.lo = re(data.hi);
|
||||
ret.hi = re(data.lo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -127,6 +132,7 @@ bool MemoryBlock::Read8(const u64 addr, u8* value)
|
||||
return false;
|
||||
}
|
||||
|
||||
//*value = std::atomic_load((volatile std::atomic<u8>*)GetMem(FixAddr(addr)));
|
||||
*value = FastRead8(FixAddr(addr));
|
||||
return true;
|
||||
}
|
||||
@ -139,6 +145,7 @@ bool MemoryBlock::Read16(const u64 addr, u16* value)
|
||||
return false;
|
||||
}
|
||||
|
||||
//se_t<u16>::func(*value, std::atomic_load((volatile std::atomic<u16>*)GetMem(FixAddr(addr))));
|
||||
*value = FastRead16(FixAddr(addr));
|
||||
return true;
|
||||
}
|
||||
@ -151,6 +158,7 @@ bool MemoryBlock::Read32(const u64 addr, u32* value)
|
||||
return false;
|
||||
}
|
||||
|
||||
//se_t<u32>::func(*value, std::atomic_load((volatile std::atomic<u32>*)GetMem(FixAddr(addr))));
|
||||
*value = FastRead32(FixAddr(addr));
|
||||
return true;
|
||||
}
|
||||
@ -163,6 +171,7 @@ bool MemoryBlock::Read64(const u64 addr, u64* value)
|
||||
return false;
|
||||
}
|
||||
|
||||
//se_t<u64>::func(*value, std::atomic_load((volatile std::atomic<u64>*)GetMem(FixAddr(addr))));
|
||||
*value = FastRead64(FixAddr(addr));
|
||||
return true;
|
||||
}
|
||||
@ -175,6 +184,9 @@ bool MemoryBlock::Read128(const u64 addr, u128* value)
|
||||
return false;
|
||||
}
|
||||
|
||||
//u64 f_addr = FixAddr(addr);
|
||||
//se_t<u64>::func(value->lo, std::atomic_load((volatile std::atomic<u64>*)GetMem(f_addr)));
|
||||
//se_t<u64>::func(value->hi, std::atomic_load((volatile std::atomic<u64>*)GetMem(f_addr + 8)));
|
||||
*value = FastRead128(FixAddr(addr));
|
||||
return true;
|
||||
}
|
||||
@ -186,32 +198,32 @@ __forceinline void MemoryBlock::FastWrite8(const u64 addr, const u8 value)
|
||||
|
||||
__forceinline void MemoryBlock::FastWrite16(const u64 addr, const u16 value)
|
||||
{
|
||||
FastWrite8(addr, (u8)(value >> 8));
|
||||
FastWrite8(addr+1, (u8)value);
|
||||
*(u16*)GetMem(addr) = re(value);
|
||||
}
|
||||
|
||||
__forceinline void MemoryBlock::FastWrite32(const u64 addr, const u32 value)
|
||||
{
|
||||
FastWrite16(addr, (u16)(value >> 16));
|
||||
FastWrite16(addr+2, (u16)value);
|
||||
*(u32*)GetMem(addr) = re(value);
|
||||
}
|
||||
|
||||
__forceinline void MemoryBlock::FastWrite64(const u64 addr, const u64 value)
|
||||
{
|
||||
FastWrite32(addr, (u32)(value >> 32));
|
||||
FastWrite32(addr+4, (u32)value);
|
||||
*(u64*)GetMem(addr) = re(value);
|
||||
}
|
||||
|
||||
__forceinline void MemoryBlock::FastWrite128(const u64 addr, const u128 value)
|
||||
{
|
||||
FastWrite64(addr, value.lo);
|
||||
FastWrite64(addr+8, value.hi);
|
||||
u128 res;
|
||||
res.lo = re(value.hi);
|
||||
res.hi = re(value.lo);
|
||||
*(u128*)GetMem(addr) = res;
|
||||
}
|
||||
|
||||
bool MemoryBlock::Write8(const u64 addr, const u8 value)
|
||||
{
|
||||
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||
|
||||
//std::atomic_store((std::atomic<u8>*)GetMem(FixAddr(addr)), value);
|
||||
FastWrite8(FixAddr(addr), value);
|
||||
return true;
|
||||
}
|
||||
@ -220,6 +232,9 @@ bool MemoryBlock::Write16(const u64 addr, const u16 value)
|
||||
{
|
||||
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||
|
||||
//u16 re_value;
|
||||
//se_t<u16>::func(re_value, value);
|
||||
//std::atomic_store((std::atomic<u16>*)GetMem(FixAddr(addr)), re_value);
|
||||
FastWrite16(FixAddr(addr), value);
|
||||
return true;
|
||||
}
|
||||
@ -228,6 +243,9 @@ bool MemoryBlock::Write32(const u64 addr, const u32 value)
|
||||
{
|
||||
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||
|
||||
//u32 re_value;
|
||||
//se_t<u32>::func(re_value, value);
|
||||
//std::atomic_store((std::atomic<u32>*)GetMem(FixAddr(addr)), re_value);
|
||||
FastWrite32(FixAddr(addr), value);
|
||||
return true;
|
||||
}
|
||||
@ -236,6 +254,9 @@ bool MemoryBlock::Write64(const u64 addr, const u64 value)
|
||||
{
|
||||
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||
|
||||
//u64 re_value;
|
||||
//se_t<u64>::func(re_value, value);
|
||||
//std::atomic_store((std::atomic<u64>*)GetMem(FixAddr(addr)), re_value);
|
||||
FastWrite64(FixAddr(addr), value);
|
||||
return true;
|
||||
}
|
||||
@ -244,6 +265,12 @@ bool MemoryBlock::Write128(const u64 addr, const u128 value)
|
||||
{
|
||||
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
|
||||
|
||||
//u64 f_addr = FixAddr(addr);
|
||||
//u64 re_value;
|
||||
//se_t<u64>::func(re_value, value.lo);
|
||||
//std::atomic_store((std::atomic<u64>*)GetMem(f_addr), re_value);
|
||||
//se_t<u64>::func(re_value, value.hi);
|
||||
//std::atomic_store((std::atomic<u64>*)GetMem(f_addr + 8), re_value);
|
||||
FastWrite128(FixAddr(addr), value);
|
||||
return true;
|
||||
}
|
||||
@ -509,3 +536,233 @@ template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; }
|
||||
template<> __forceinline u64 MemoryBase::ReverseData<2>(u64 val) { return Reverse16(val); }
|
||||
template<> __forceinline u64 MemoryBase::ReverseData<4>(u64 val) { return Reverse32(val); }
|
||||
template<> __forceinline u64 MemoryBase::ReverseData<8>(u64 val) { return Reverse64(val); }
|
||||
|
||||
VirtualMemoryBlock::VirtualMemoryBlock() : MemoryBlock()
|
||||
{
|
||||
}
|
||||
|
||||
MemoryBlock* VirtualMemoryBlock::SetRange(const u64 start, const u32 size)
|
||||
{
|
||||
range_start = start;
|
||||
range_size = size;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::IsInMyRange(const u64 addr)
|
||||
{
|
||||
return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize() - GetResevedAmount();
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::IsInMyRange(const u64 addr, const u32 size)
|
||||
{
|
||||
return IsInMyRange(addr) && IsInMyRange(addr + size - 1);
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::IsMyAddress(const u64 addr)
|
||||
{
|
||||
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||
{
|
||||
if(addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr)
|
||||
{
|
||||
if(addr)
|
||||
{
|
||||
if(!IsInMyRange(addr, size) && (IsMyAddress(addr) || IsMyAddress(addr + size - 1)))
|
||||
return 0;
|
||||
|
||||
m_mapped_memory.Move(new VirtualMemInfo(addr, realaddr, size));
|
||||
return addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(u64 addr = GetStartAddr(); addr <= GetEndAddr() - GetResevedAmount() - size;)
|
||||
{
|
||||
bool is_good_addr = true;
|
||||
|
||||
// check if address is already mapped
|
||||
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||
{
|
||||
if((addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) ||
|
||||
(m_mapped_memory[i].addr >= addr && m_mapped_memory[i].addr < addr + size))
|
||||
{
|
||||
is_good_addr = false;
|
||||
addr = m_mapped_memory[i].addr + m_mapped_memory[i].size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!is_good_addr) continue;
|
||||
|
||||
m_mapped_memory.Move(new VirtualMemInfo(addr, realaddr, size));
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 VirtualMemoryBlock::UnmapRealAddress(u64 realaddr)
|
||||
{
|
||||
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||
{
|
||||
if(m_mapped_memory[i].realAddress == realaddr && IsInMyRange(m_mapped_memory[i].addr, m_mapped_memory[i].size))
|
||||
{
|
||||
u32 size = m_mapped_memory[i].size;
|
||||
m_mapped_memory.RemoveAt(i);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 VirtualMemoryBlock::UnmapAddress(u64 addr)
|
||||
{
|
||||
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||
{
|
||||
if(m_mapped_memory[i].addr == addr && IsInMyRange(m_mapped_memory[i].addr, m_mapped_memory[i].size))
|
||||
{
|
||||
u32 size = m_mapped_memory[i].size;
|
||||
m_mapped_memory.RemoveAt(i);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Read8(const u64 addr, u8* value)
|
||||
{
|
||||
u64 realAddr;
|
||||
*value = Memory.Read8(realAddr = getRealAddr(addr));
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Read16(const u64 addr, u16* value)
|
||||
{
|
||||
u64 realAddr;
|
||||
*value = Memory.Read16(realAddr = getRealAddr(addr));
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Read32(const u64 addr, u32* value)
|
||||
{
|
||||
u64 realAddr;
|
||||
*value = Memory.Read32(realAddr = getRealAddr(addr));
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Read64(const u64 addr, u64* value)
|
||||
{
|
||||
u64 realAddr;
|
||||
*value = Memory.Read64(realAddr = getRealAddr(addr));
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Read128(const u64 addr, u128* value)
|
||||
{
|
||||
u64 realAddr;
|
||||
*value = Memory.Read128(realAddr = getRealAddr(addr));
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Write8(const u64 addr, const u8 value)
|
||||
{
|
||||
u64 realAddr;
|
||||
Memory.Write8(realAddr = getRealAddr(addr), value);
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Write16(const u64 addr, const u16 value)
|
||||
{
|
||||
u64 realAddr;
|
||||
Memory.Write16(realAddr = getRealAddr(addr), value);
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Write32(const u64 addr, const u32 value)
|
||||
{
|
||||
u64 realAddr;
|
||||
Memory.Write32(realAddr = getRealAddr(addr), value);
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Write64(const u64 addr, const u64 value)
|
||||
{
|
||||
u64 realAddr;
|
||||
Memory.Write64(realAddr = getRealAddr(addr), value);
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Write128(const u64 addr, const u128 value)
|
||||
{
|
||||
u64 realAddr;
|
||||
Memory.Write128(realAddr = getRealAddr(addr), value);
|
||||
return realAddr != 0;
|
||||
}
|
||||
|
||||
u64 VirtualMemoryBlock::getRealAddr(u64 addr)
|
||||
{
|
||||
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||
{
|
||||
if(addr >= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size)
|
||||
{
|
||||
return m_mapped_memory[i].realAddress + (addr - m_mapped_memory[i].addr);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 VirtualMemoryBlock::getMappedAddress(u64 realAddress)
|
||||
{
|
||||
for(u32 i=0; i<m_mapped_memory.GetCount(); ++i)
|
||||
{
|
||||
if(realAddress >= m_mapped_memory[i].realAddress && realAddress < m_mapped_memory[i].realAddress + m_mapped_memory[i].size)
|
||||
{
|
||||
return m_mapped_memory[i].addr + (realAddress - m_mapped_memory[i].realAddress);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VirtualMemoryBlock::Delete()
|
||||
{
|
||||
m_mapped_memory.Clear();
|
||||
|
||||
MemoryBlock::Delete();
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Reserve(u32 size)
|
||||
{
|
||||
if(size + GetResevedAmount() > GetEndAddr() - GetStartAddr())
|
||||
return false;
|
||||
|
||||
m_reserve_size += size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VirtualMemoryBlock::Unreserve(u32 size)
|
||||
{
|
||||
if(size > GetResevedAmount())
|
||||
return false;
|
||||
|
||||
m_reserve_size -= size;
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 VirtualMemoryBlock::GetResevedAmount()
|
||||
{
|
||||
return m_reserve_size;
|
||||
}
|
@ -13,7 +13,7 @@ class MemoryBase
|
||||
NullMemoryBlock NullMem;
|
||||
|
||||
public:
|
||||
ArrayF<MemoryBlock> MemoryBlocks;
|
||||
std::vector<MemoryBlock*> MemoryBlocks;
|
||||
MemoryBlock* UserMemory;
|
||||
|
||||
DynamicMemoryBlock MainMem;
|
||||
@ -24,6 +24,7 @@ public:
|
||||
DynamicMemoryBlock StackMem;
|
||||
MemoryBlock SpuRawMem;
|
||||
MemoryBlock SpuThrMem;
|
||||
VirtualMemoryBlock RSXIOMem;
|
||||
|
||||
struct
|
||||
{
|
||||
@ -95,15 +96,15 @@ public:
|
||||
|
||||
MemoryBlock& GetMemByNum(const u8 num)
|
||||
{
|
||||
if(num >= MemoryBlocks.GetCount()) return NullMem;
|
||||
return MemoryBlocks.Get(num);
|
||||
if(num >= MemoryBlocks.size()) return NullMem;
|
||||
return *MemoryBlocks[num];
|
||||
}
|
||||
|
||||
MemoryBlock& GetMemByAddr(const u64 addr)
|
||||
{
|
||||
for(uint i=0; i<MemoryBlocks.GetCount(); ++i)
|
||||
for(uint i=0; i<MemoryBlocks.size(); ++i)
|
||||
{
|
||||
if(MemoryBlocks.Get(i).IsMyAddress(addr)) return MemoryBlocks[i];
|
||||
if(MemoryBlocks[i]->IsMyAddress(addr)) return *MemoryBlocks[i];
|
||||
}
|
||||
|
||||
return NullMem;
|
||||
@ -122,9 +123,9 @@ public:
|
||||
u64 RealToVirtualAddr(const void* addr)
|
||||
{
|
||||
const u64 raddr = (u64)addr;
|
||||
for(u32 i=0; i<MemoryBlocks.GetCount(); ++i)
|
||||
for(u32 i=0; i<MemoryBlocks.size(); ++i)
|
||||
{
|
||||
MemoryBlock& b = MemoryBlocks[i];
|
||||
MemoryBlock& b = *MemoryBlocks[i];
|
||||
const u64 baddr = (u64)b.GetMem();
|
||||
|
||||
if(raddr >= baddr && raddr < baddr + b.GetSize())
|
||||
@ -140,7 +141,7 @@ public:
|
||||
{
|
||||
//if(SpuRawMem.GetSize()) return false;
|
||||
|
||||
MemoryBlocks.Add(SpuRawMem.SetRange(0xe0000000, 0x100000 * max_spu_raw));
|
||||
MemoryBlocks.push_back(SpuRawMem.SetRange(0xe0000000, 0x100000 * max_spu_raw));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -155,27 +156,27 @@ public:
|
||||
switch(type)
|
||||
{
|
||||
case Memory_PS3:
|
||||
MemoryBlocks.Add(MainMem.SetRange(0x00010000, 0x2FFF0000));
|
||||
MemoryBlocks.Add(UserMemory = PRXMem.SetRange(0x30000000, 0x10000000));
|
||||
MemoryBlocks.Add(RSXCMDMem.SetRange(0x40000000, 0x10000000));
|
||||
MemoryBlocks.Add(MmaperMem.SetRange(0xB0000000, 0x10000000));
|
||||
MemoryBlocks.Add(RSXFBMem.SetRange(0xC0000000, 0x10000000));
|
||||
MemoryBlocks.Add(StackMem.SetRange(0xD0000000, 0x10000000));
|
||||
//MemoryBlocks.Add(SpuRawMem.SetRange(0xE0000000, 0x10000000));
|
||||
//MemoryBlocks.Add(SpuThrMem.SetRange(0xF0000000, 0x10000000));
|
||||
MemoryBlocks.push_back(MainMem.SetRange(0x00010000, 0x2FFF0000));
|
||||
MemoryBlocks.push_back(UserMemory = PRXMem.SetRange(0x30000000, 0x10000000));
|
||||
MemoryBlocks.push_back(RSXCMDMem.SetRange(0x40000000, 0x10000000));
|
||||
MemoryBlocks.push_back(MmaperMem.SetRange(0xB0000000, 0x10000000));
|
||||
MemoryBlocks.push_back(RSXFBMem.SetRange(0xC0000000, 0x10000000));
|
||||
MemoryBlocks.push_back(StackMem.SetRange(0xD0000000, 0x10000000));
|
||||
//MemoryBlocks.push_back(SpuRawMem.SetRange(0xE0000000, 0x10000000));
|
||||
//MemoryBlocks.push_back(SpuThrMem.SetRange(0xF0000000, 0x10000000));
|
||||
break;
|
||||
|
||||
case Memory_PSV:
|
||||
MemoryBlocks.Add(PSVMemory.RAM.SetRange(0x81000000, 0x10000000));
|
||||
MemoryBlocks.Add(UserMemory = PSVMemory.Userspace.SetRange(0x91000000, 0x10000000));
|
||||
MemoryBlocks.push_back(PSVMemory.RAM.SetRange(0x81000000, 0x10000000));
|
||||
MemoryBlocks.push_back(UserMemory = PSVMemory.Userspace.SetRange(0x91000000, 0x10000000));
|
||||
break;
|
||||
|
||||
case Memory_PSP:
|
||||
MemoryBlocks.Add(PSPMemory.Scratchpad.SetRange(0x00010000, 0x00004000));
|
||||
MemoryBlocks.Add(PSPMemory.VRAM.SetRange(0x04000000, 0x00200000));
|
||||
MemoryBlocks.Add(PSPMemory.RAM.SetRange(0x08000000, 0x02000000));
|
||||
MemoryBlocks.Add(PSPMemory.Kernel.SetRange(0x88000000, 0x00800000));
|
||||
MemoryBlocks.Add(UserMemory = PSPMemory.Userspace.SetRange(0x08800000, 0x01800000));
|
||||
MemoryBlocks.push_back(PSPMemory.Scratchpad.SetRange(0x00010000, 0x00004000));
|
||||
MemoryBlocks.push_back(PSPMemory.VRAM.SetRange(0x04000000, 0x00200000));
|
||||
MemoryBlocks.push_back(PSPMemory.RAM.SetRange(0x08000000, 0x02000000));
|
||||
MemoryBlocks.push_back(PSPMemory.Kernel.SetRange(0x88000000, 0x00800000));
|
||||
MemoryBlocks.push_back(UserMemory = PSPMemory.Userspace.SetRange(0x08800000, 0x01800000));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -184,9 +185,9 @@ public:
|
||||
|
||||
bool IsGoodAddr(const u64 addr)
|
||||
{
|
||||
for(uint i=0; i<MemoryBlocks.GetCount(); ++i)
|
||||
for(uint i=0; i<MemoryBlocks.size(); ++i)
|
||||
{
|
||||
if(MemoryBlocks[i].IsMyAddress(addr)) return true;
|
||||
if(MemoryBlocks[i]->IsMyAddress(addr)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -194,10 +195,10 @@ public:
|
||||
|
||||
bool IsGoodAddr(const u64 addr, const u32 size)
|
||||
{
|
||||
for(uint i=0; i<MemoryBlocks.GetCount(); ++i)
|
||||
for(uint i=0; i<MemoryBlocks.size(); ++i)
|
||||
{
|
||||
if( MemoryBlocks[i].IsMyAddress(addr) &&
|
||||
MemoryBlocks[i].IsMyAddress(addr + size - 1) ) return true;
|
||||
if( MemoryBlocks[i]->IsMyAddress(addr) &&
|
||||
MemoryBlocks[i]->IsMyAddress(addr + size - 1) ) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -210,12 +211,12 @@ public:
|
||||
|
||||
ConLog.Write("Closing memory...");
|
||||
|
||||
for(uint i=0; i<MemoryBlocks.GetCount(); ++i)
|
||||
for(uint i=0; i<MemoryBlocks.size(); ++i)
|
||||
{
|
||||
MemoryBlocks[i].Delete();
|
||||
MemoryBlocks[i]->Delete();
|
||||
}
|
||||
|
||||
MemoryBlocks.ClearF();
|
||||
MemoryBlocks.clear();
|
||||
}
|
||||
|
||||
void Write8(const u64 addr, const u8 data);
|
||||
@ -246,9 +247,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
u32 offs = mem.FixAddr(addr);
|
||||
|
||||
for(u32 i=0; i<size; ++i) dst[size - 1 - i] = mem.FastRead8(offs + i);
|
||||
for(u32 i=0; i<size; ++i) mem.Read8(addr + i, dst + size - 1 - i);
|
||||
}
|
||||
|
||||
void WriteLeft(const u64 addr, const u32 size, const u8* src)
|
||||
@ -261,9 +260,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
u32 offs = mem.FixAddr(addr);
|
||||
|
||||
for(u32 i=0; i<size; ++i) mem.FastWrite8(offs + i, src[size - 1 - i]);
|
||||
for(u32 i=0; i<size; ++i) mem.Write8(addr + i, src[size - 1 - i]);
|
||||
}
|
||||
|
||||
void ReadRight(u8* dst, const u64 addr, const u32 size)
|
||||
@ -276,9 +273,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
u32 offs = mem.FixAddr(addr);
|
||||
|
||||
for(u32 i=0; i<size; ++i) dst[i] = mem.FastRead8(offs + (size - 1 - i));
|
||||
for(u32 i=0; i<size; ++i) mem.Read8(addr + (size - 1 - i), dst + i);
|
||||
}
|
||||
|
||||
void WriteRight(const u64 addr, const u32 size, const u8* src)
|
||||
@ -291,9 +286,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
u32 offs = mem.FixAddr(addr);
|
||||
|
||||
for(u32 i=0; i<size; ++i) mem.FastWrite8(offs + (size - 1 - i), src[i]);
|
||||
for(u32 i=0; i<size; ++i) mem.Write8(addr + (size - 1 - i), src[i]);
|
||||
}
|
||||
|
||||
template<typename T> void WriteData(const u64 addr, const T* data)
|
||||
@ -312,12 +305,12 @@ public:
|
||||
|
||||
if(len) memcpy(wxStringBuffer(ret, len), GetMemFromAddr(addr), len);
|
||||
|
||||
return ret;
|
||||
return wxString(ret, wxConvUTF8);
|
||||
}
|
||||
|
||||
wxString ReadString(const u64 addr)
|
||||
{
|
||||
return wxString((const char*)GetMemFromAddr(addr));
|
||||
return wxString((const char*)GetMemFromAddr(addr), wxConvUTF8);
|
||||
}
|
||||
|
||||
void WriteString(const u64 addr, const wxString& str)
|
||||
@ -373,20 +366,21 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
MemoryBlocks.Add((new MemoryMirror())->SetRange(GetMemFromAddr(src_addr), dst_addr, size));
|
||||
MemoryBlocks.push_back((new MemoryMirror())->SetRange(GetMemFromAddr(src_addr), dst_addr, size));
|
||||
ConLog.Warning("memory mapped 0x%llx to 0x%llx size=0x%x", src_addr, dst_addr, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Unmap(const u64 addr)
|
||||
{
|
||||
for(uint i=0; i<MemoryBlocks.GetCount(); ++i)
|
||||
for(uint i=0; i<MemoryBlocks.size(); ++i)
|
||||
{
|
||||
if(MemoryBlocks[i].IsMirror())
|
||||
if(MemoryBlocks[i]->IsMirror())
|
||||
{
|
||||
if(MemoryBlocks[i].GetStartAddr() == addr)
|
||||
if(MemoryBlocks[i]->GetStartAddr() == addr)
|
||||
{
|
||||
MemoryBlocks.RemoveAt(i);
|
||||
delete MemoryBlocks[i];
|
||||
MemoryBlocks.erase(MemoryBlocks.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -425,9 +419,9 @@ public:
|
||||
return Memory.IsGoodAddr(m_addr, sizeof(T));
|
||||
}
|
||||
|
||||
__forceinline operator u32() const
|
||||
__forceinline operator bool() const
|
||||
{
|
||||
return m_addr;
|
||||
return m_addr != 0;
|
||||
}
|
||||
|
||||
__forceinline bool operator != (nullptr_t) const
|
||||
@ -685,6 +679,33 @@ public:
|
||||
void SetAddr(const u64 addr) { m_addr = addr; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _func_arg
|
||||
{
|
||||
__forceinline static u64 get_value(const T& arg)
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _func_arg<mem_base_t<T>>
|
||||
{
|
||||
__forceinline static u64 get_value(const mem_base_t<T>& arg)
|
||||
{
|
||||
return arg.GetAddr();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _func_arg<be_t<T>>
|
||||
{
|
||||
__forceinline static u64 get_value(const be_t<T>& arg)
|
||||
{
|
||||
return arg.ToLE();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> class mem_func_ptr_t;
|
||||
|
||||
template<typename RT>
|
||||
@ -716,7 +737,7 @@ class mem_func_ptr_t<RT (*)(T1)> : public mem_base_t<u64>
|
||||
{
|
||||
Callback cb;
|
||||
cb.SetAddr(m_addr);
|
||||
cb.Handle(a1);
|
||||
cb.Handle(_func_arg<T1>::get_value(a1));
|
||||
cb.Branch(!is_async);
|
||||
}
|
||||
|
||||
@ -739,7 +760,7 @@ class mem_func_ptr_t<RT (*)(T1, T2)> : public mem_base_t<u64>
|
||||
{
|
||||
Callback cb;
|
||||
cb.SetAddr(m_addr);
|
||||
cb.Handle(a1, a2);
|
||||
cb.Handle(_func_arg<T1>::get_value(a1), _func_arg<T2>::get_value(a2));
|
||||
cb.Branch(!is_async);
|
||||
}
|
||||
|
||||
@ -762,7 +783,7 @@ class mem_func_ptr_t<RT (*)(T1, T2, T3)> : public mem_base_t<u64>
|
||||
{
|
||||
Callback cb;
|
||||
cb.SetAddr(m_addr);
|
||||
cb.Handle(a1, a2, a3);
|
||||
cb.Handle(_func_arg<T1>::get_value(a1), _func_arg<T2>::get_value(a2), _func_arg<T3>::get_value(a3));
|
||||
cb.Branch(!is_async);
|
||||
}
|
||||
|
||||
@ -785,7 +806,7 @@ class mem_func_ptr_t<RT (*)(T1, T2, T3, T4)> : public mem_base_t<u64>
|
||||
{
|
||||
Callback cb;
|
||||
cb.SetAddr(m_addr);
|
||||
cb.Handle(a1, a2, a3, a4);
|
||||
cb.Handle(_func_arg<T1>::get_value(a1), _func_arg<T2>::get_value(a2), _func_arg<T3>::get_value(a3), _func_arg<T4>::get_value(a4));
|
||||
cb.Branch(!is_async);
|
||||
}
|
||||
|
||||
@ -801,7 +822,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class MemoryAllocator
|
||||
{
|
||||
|
@ -40,6 +40,23 @@ struct MemBlockInfo : public MemInfo
|
||||
}
|
||||
};
|
||||
|
||||
struct VirtualMemInfo : public MemInfo
|
||||
{
|
||||
u64 realAddress;
|
||||
|
||||
VirtualMemInfo(u64 _addr, u64 _realaddr, u32 _size)
|
||||
: MemInfo(_addr, _size)
|
||||
, realAddress(_realaddr)
|
||||
{
|
||||
}
|
||||
|
||||
VirtualMemInfo()
|
||||
: MemInfo(0, 0)
|
||||
, realAddress(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class MemoryBlock
|
||||
{
|
||||
protected:
|
||||
@ -206,6 +223,58 @@ private:
|
||||
void AppendLockedMem(u64 addr, u32 size);
|
||||
};
|
||||
|
||||
class VirtualMemoryBlock : public MemoryBlock
|
||||
{
|
||||
Array<VirtualMemInfo> m_mapped_memory;
|
||||
u32 m_reserve_size;
|
||||
|
||||
public:
|
||||
VirtualMemoryBlock();
|
||||
|
||||
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
|
||||
virtual bool IsInMyRange(const u64 addr);
|
||||
virtual bool IsInMyRange(const u64 addr, const u32 size);
|
||||
virtual bool IsMyAddress(const u64 addr);
|
||||
virtual void Delete();
|
||||
|
||||
// maps real address to virtual address space, returns the mapped address or 0 on failure (if no address is specified the
|
||||
// first mappable space is used)
|
||||
virtual u64 Map(u64 realaddr, u32 size, u64 addr = 0);
|
||||
|
||||
// Unmap real address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
|
||||
virtual u32 UnmapRealAddress(u64 realaddr);
|
||||
|
||||
// Unmap address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area
|
||||
virtual u32 UnmapAddress(u64 addr);
|
||||
|
||||
// Reserve a certain amount so no one can use it, returns true on succces, false on failure
|
||||
virtual bool Reserve(u32 size);
|
||||
|
||||
// Unreserve a certain amount of bytes, returns true on succcess, false if size is bigger than the reserved amount
|
||||
virtual bool Unreserve(u32 size);
|
||||
|
||||
// Return the total amount of reserved memory
|
||||
virtual u32 GetResevedAmount();
|
||||
|
||||
virtual bool Read8(const u64 addr, u8* value);
|
||||
virtual bool Read16(const u64 addr, u16* value);
|
||||
virtual bool Read32(const u64 addr, u32* value);
|
||||
virtual bool Read64(const u64 addr, u64* value);
|
||||
virtual bool Read128(const u64 addr, u128* value);
|
||||
|
||||
virtual bool Write8(const u64 addr, const u8 value);
|
||||
virtual bool Write16(const u64 addr, const u16 value);
|
||||
virtual bool Write32(const u64 addr, const u32 value);
|
||||
virtual bool Write64(const u64 addr, const u64 value);
|
||||
virtual bool Write128(const u64 addr, const u128 value);
|
||||
|
||||
// return the real address given a mapped address, if not mapped return 0
|
||||
u64 getRealAddr(u64 addr);
|
||||
|
||||
// return the mapped address given a real address, if not mapped return 0
|
||||
u64 getMappedAddress(u64 realAddress);
|
||||
};
|
||||
|
||||
#include "DynamicMemoryBlockBase.inl"
|
||||
|
||||
typedef DynamicMemoryBlockBase<MemoryBlock> DynamicMemoryBlock;
|
||||
|
@ -442,28 +442,12 @@ void Module::Error(wxString fmt, ...)
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
bool Module::CheckId(u32 id) const
|
||||
bool Module::CheckID(u32 id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetIDData(id).m_name.Cmp(GetName());
|
||||
return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetID(id).m_name.Cmp(GetName());
|
||||
}
|
||||
|
||||
bool Module::CheckId(u32 id, ID& _id) const
|
||||
bool Module::CheckID(u32 id, ID*& _id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && !(_id = Emu.GetIdManager().GetIDData(id)).m_name.Cmp(GetName());
|
||||
}
|
||||
|
||||
template<typename T> bool Module::CheckId(u32 id, T*& data)
|
||||
{
|
||||
ID id_data;
|
||||
|
||||
if(!CheckId(id, id_data)) return false;
|
||||
|
||||
data = (T*)id_data.m_data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 Module::GetNewId(void* data, u8 flags)
|
||||
{
|
||||
return Emu.GetIdManager().GetNewID(GetName(), data, flags);
|
||||
return Emu.GetIdManager().CheckID(id) && !(_id = &Emu.GetIdManager().GetID(id))->m_name.Cmp(GetName());
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#include "Modules/cellResc.h"
|
||||
#include "Modules/cellPngDec.h"
|
||||
#include "Modules/cellJpgDec.h"
|
||||
#include "Modules/cellGifDec.h"
|
||||
|
||||
#define declCPU PPUThread& CPU = GetCurrentPPUThread
|
||||
|
||||
@ -59,13 +62,24 @@ public:
|
||||
void Error(const u32 id, wxString fmt, ...);
|
||||
void Error(wxString fmt, ...);
|
||||
|
||||
bool CheckId(u32 id) const;
|
||||
bool CheckID(u32 id) const;
|
||||
template<typename T> bool CheckId(u32 id, T*& data)
|
||||
{
|
||||
ID* id_data;
|
||||
|
||||
bool CheckId(u32 id, ID& _id) const;
|
||||
if(!CheckID(id, id_data)) return false;
|
||||
|
||||
template<typename T> bool CheckId(u32 id, T*& data);
|
||||
data = id_data->m_data->get<T>();
|
||||
|
||||
u32 GetNewId(void* data = nullptr, u8 flags = 0);
|
||||
return true;
|
||||
}
|
||||
bool CheckID(u32 id, ID*& _id) const;
|
||||
|
||||
template<typename T>
|
||||
u32 GetNewId(T* data, u8 flags = 0)
|
||||
{
|
||||
return Emu.GetIdManager().GetNewID<T>(GetName(), data, flags);
|
||||
}
|
||||
|
||||
template<typename T> __forceinline void AddFunc(u32 id, T func);
|
||||
};
|
||||
|
@ -6,54 +6,60 @@
|
||||
void cellGcmSys_init();
|
||||
Module cellGcmSys(0x0010, cellGcmSys_init);
|
||||
|
||||
u32 local_size = 0;
|
||||
u32 local_addr = NULL;
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_GCM_ERROR_FAILURE = 0x802100ff,
|
||||
CELL_GCM_ERROR_NO_IO_PAGE_TABLE = 0x80210001,
|
||||
CELL_GCM_ERROR_INVALID_ENUM = 0x80210002,
|
||||
CELL_GCM_ERROR_INVALID_VALUE = 0x80210003,
|
||||
CELL_GCM_ERROR_INVALID_ALIGNMENT = 0x80210004,
|
||||
CELL_GCM_ERROR_ADDRESS_OVERWRAP = 0x80210005
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------
|
||||
Memory Mapping
|
||||
------------------------------------------------------------*/
|
||||
|
||||
struct gcm_offset
|
||||
{
|
||||
u64 io;
|
||||
u64 ea;
|
||||
};
|
||||
|
||||
void InitOffsetTable();
|
||||
int32_t cellGcmAddressToOffset(u64 address, mem32_t offset);
|
||||
uint32_t cellGcmGetMaxIoMapSize();
|
||||
void cellGcmGetOffsetTable(mem_ptr_t<gcm_offset> table);
|
||||
int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address);
|
||||
int32_t cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size);
|
||||
int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset);
|
||||
int32_t cellGcmReserveIoMapSize(const u32 size);
|
||||
int32_t cellGcmUnmapEaIoAddress(u64 ea);
|
||||
int32_t cellGcmUnmapIoAddress(u64 io);
|
||||
int32_t cellGcmUnreserveIoMapSize(u32 size);
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
CellGcmConfig current_config;
|
||||
CellGcmContextData current_context;
|
||||
gcmInfo gcm_info;
|
||||
struct gcm_offset
|
||||
{
|
||||
u16 ea;
|
||||
u16 offset;
|
||||
};
|
||||
|
||||
u32 map_offset_addr = 0;
|
||||
u32 map_offset_pos = 0;
|
||||
|
||||
int cellGcmMapMainMemory(u32 address, u32 size, mem32_t offset)
|
||||
{
|
||||
cellGcmSys.Warning("cellGcmMapMainMemory(address=0x%x,size=0x%x,offset_addr=0x%x)", address, size, offset.GetAddr());
|
||||
if(!offset.IsGood()) return CELL_EFAULT;
|
||||
|
||||
Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress;
|
||||
|
||||
offset = address - Emu.GetGSManager().GetRender().m_main_mem_addr;
|
||||
Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(address, size));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size)
|
||||
{
|
||||
cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
|
||||
//Memory.Map(io, ea, size);
|
||||
//Emu.GetGSManager().GetRender().m_ioAddress = io;
|
||||
Emu.GetGSManager().GetRender().m_report_main_addr = ea;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
|
||||
{
|
||||
cellGcmSys.Warning("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress);
|
||||
|
||||
const u32 local_size = 0xf900000; //TODO
|
||||
const u32 local_addr = Memory.RSXFBMem.GetStartAddr();
|
||||
if(!local_size && !local_addr)
|
||||
{
|
||||
local_size = 0xf900000; //TODO
|
||||
local_addr = Memory.RSXFBMem.GetStartAddr();
|
||||
Memory.RSXFBMem.Alloc(local_size);
|
||||
}
|
||||
|
||||
cellGcmSys.Warning("*** local memory(addr=0x%x, size=0x%x)", local_addr, local_size);
|
||||
|
||||
@ -66,8 +72,10 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
|
||||
current_config.memoryFrequency = re32(650000000);
|
||||
current_config.coreFrequency = re32(500000000);
|
||||
|
||||
Memory.RSXFBMem.Alloc(local_size);
|
||||
InitOffsetTable();
|
||||
Memory.RSXCMDMem.Alloc(cmdSize);
|
||||
Memory.MemoryBlocks.push_back(Memory.RSXIOMem.SetRange(0x50000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase
|
||||
cellGcmMapEaIoAddress(ioAddress, 0, ioSize);
|
||||
|
||||
u32 ctx_begin = ioAddress/* + 0x1000*/;
|
||||
u32 ctx_size = 0x6ffc;
|
||||
@ -112,57 +120,6 @@ int cellGcmGetConfiguration(mem_ptr_t<CellGcmConfig> config)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGcmAddressToOffset(u32 address, mem32_t offset)
|
||||
{
|
||||
cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr());
|
||||
if(!offset.IsGood()) return CELL_EFAULT;
|
||||
|
||||
if(!map_offset_addr)
|
||||
{
|
||||
map_offset_addr = Memory.Alloc(4*50, 4);
|
||||
}
|
||||
|
||||
u32 sa;
|
||||
bool is_main_mem = false;
|
||||
const auto& main_mem_info = Emu.GetGSManager().GetRender().m_main_mem_info;
|
||||
for(u32 i=0; i<Emu.GetGSManager().GetRender().m_main_mem_info.GetCount(); ++i)
|
||||
{
|
||||
//main memory
|
||||
if(address >= main_mem_info[i].addr && address < main_mem_info[i].addr + main_mem_info[i].size)
|
||||
{
|
||||
is_main_mem = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_main_mem)
|
||||
{
|
||||
//main
|
||||
sa = Emu.GetGSManager().GetRender().m_main_mem_addr;
|
||||
//ConLog.Warning("cellGcmAddressToOffset: main memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
|
||||
}
|
||||
else if(Memory.RSXFBMem.IsMyAddress(address))
|
||||
{
|
||||
//local
|
||||
sa = Emu.GetGSManager().GetRender().m_local_mem_addr;
|
||||
//ConLog.Warning("cellGcmAddressToOffset: local memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
|
||||
}
|
||||
else
|
||||
{
|
||||
//io
|
||||
sa = Emu.GetGSManager().GetRender().m_ioAddress;
|
||||
//ConLog.Warning("cellGcmAddressToOffset: io memory: offset = 0x%x - 0x%x = 0x%x", address, sa, address - sa);
|
||||
}
|
||||
|
||||
offset = address - sa;
|
||||
//ConLog.Warning("Address To Offset: 0x%x -> 0x%x", address, address - sa);
|
||||
//Memory.Write16(map_offset_addr + map_offset_pos + 0, ea);
|
||||
//Memory.Write16(map_offset_addr + map_offset_pos + 2, offset);
|
||||
//map_offset_pos += 4;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height)
|
||||
{
|
||||
cellGcmSys.Warning("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)",
|
||||
@ -611,16 +568,246 @@ int cellGcmSetSecondVFrequency (u32 freq)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------
|
||||
Memory Mapping
|
||||
------------------------------------------------------------*/
|
||||
|
||||
gcm_offset offsetTable = {0, 0};
|
||||
|
||||
void InitOffsetTable()
|
||||
{
|
||||
offsetTable.io = Memory.Alloc(3072*sizeof(u16), 1);
|
||||
for(int i=0; i<3072; i++)
|
||||
{
|
||||
Memory.Write16(offsetTable.io + sizeof(u16)*i, 0xFFFF);
|
||||
}
|
||||
|
||||
offsetTable.ea = Memory.Alloc(256*sizeof(u16), 1);//TODO: check flags
|
||||
for(int i=0; i<256; i++)
|
||||
{
|
||||
Memory.Write16(offsetTable.ea + sizeof(u16)*i, 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t cellGcmAddressToOffset(u64 address, mem32_t offset)
|
||||
{
|
||||
cellGcmSys.Warning("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.GetAddr());
|
||||
|
||||
if(address >= 0xD0000000/*not on main memory or local*/)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
u32 result;
|
||||
|
||||
// If address is in range of local memory
|
||||
if(Memory.RSXFBMem.IsInMyRange(address))
|
||||
{
|
||||
result = address - Memory.RSXFBMem.GetStartAddr();
|
||||
}
|
||||
// else check if the adress (main memory) is mapped in IO
|
||||
else
|
||||
{
|
||||
u16 upper12Bits = Memory.Read16(offsetTable.io + sizeof(u16)*(address >> 20));
|
||||
|
||||
if(upper12Bits != 0xFFFF)
|
||||
{
|
||||
result = (((u64)upper12Bits << 20) | (address & (0xFFFFF)));
|
||||
}
|
||||
// address is not mapped in IO
|
||||
else
|
||||
{
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
offset = result;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
uint32_t cellGcmGetMaxIoMapSize()
|
||||
{
|
||||
return Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetStartAddr() - Memory.RSXIOMem.GetResevedAmount();
|
||||
}
|
||||
|
||||
void cellGcmGetOffsetTable(mem_ptr_t<gcm_offset> table)
|
||||
{
|
||||
table->io = re(offsetTable.io);
|
||||
table->ea = re(offsetTable.ea);
|
||||
}
|
||||
|
||||
int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address)
|
||||
{
|
||||
u64 realAddr;
|
||||
|
||||
realAddr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ioOffset);
|
||||
|
||||
if(!realAddr)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
Memory.Write64(address, realAddr);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int32_t cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size)
|
||||
{
|
||||
cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
|
||||
|
||||
if((ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
//check if the mapping was successfull
|
||||
if(Memory.RSXIOMem.Map(ea, size, Memory.RSXIOMem.GetStartAddr() + io))
|
||||
{
|
||||
//fill the offset table
|
||||
for(u32 i=0; i<(size >> 20); i++)
|
||||
{
|
||||
Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i);
|
||||
Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int32_t cellGcmMapLocalMemory(u64 address, u64 size)
|
||||
{
|
||||
if(!local_size && !local_addr)
|
||||
{
|
||||
local_size = 0xf900000; //TODO
|
||||
local_addr = Memory.RSXFBMem.GetStartAddr();
|
||||
Memory.RSXFBMem.Alloc(local_size);
|
||||
Memory.Write32(address, local_addr);
|
||||
Memory.Write32(size, local_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("RSX local memory already mapped");
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int32_t cellGcmMapMainMemory(u64 ea, u32 size, mem32_t offset)
|
||||
{
|
||||
cellGcmSys.Warning("cellGcmMapMainMemory(ea=0x%x,size=0x%x,offset_addr=0x%x)", ea, size, offset.GetAddr());
|
||||
|
||||
u64 io;
|
||||
|
||||
if((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
//check if the mapping was successfull
|
||||
if(io = Memory.RSXIOMem.Map(ea, size, 0))
|
||||
{
|
||||
// convert to offset
|
||||
io = io - Memory.RSXIOMem.GetStartAddr();
|
||||
|
||||
//fill the offset table
|
||||
for(u32 i=0; i<(size >> 20); i++)
|
||||
{
|
||||
Memory.Write16(offsetTable.io + ((ea >> 20) + i)*sizeof(u16), (io >> 20) + i);
|
||||
Memory.Write16(offsetTable.ea + ((io >> 20) + i)*sizeof(u16), (ea >> 20) + i);
|
||||
}
|
||||
|
||||
offset = io;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_GCM_ERROR_NO_IO_PAGE_TABLE;
|
||||
}
|
||||
|
||||
Emu.GetGSManager().GetRender().m_main_mem_addr = Emu.GetGSManager().GetRender().m_ioAddress;
|
||||
Emu.GetGSManager().GetRender().m_main_mem_info.AddCpy(MemInfo(ea, size));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int32_t cellGcmReserveIoMapSize(const u32 size)
|
||||
{
|
||||
if(size & 0xFFFFF)
|
||||
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
|
||||
|
||||
if(size > cellGcmGetMaxIoMapSize())
|
||||
return CELL_GCM_ERROR_INVALID_VALUE;
|
||||
|
||||
Memory.RSXIOMem.Reserve(size);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int32_t cellGcmUnmapEaIoAddress(u64 ea)
|
||||
{
|
||||
u32 size;
|
||||
if(size = Memory.RSXIOMem.UnmapRealAddress(ea))
|
||||
{
|
||||
u64 io;
|
||||
ea = ea >> 20;
|
||||
io = Memory.Read16(offsetTable.io + (ea*sizeof(u16)));
|
||||
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
Memory.Write16(offsetTable.io + ((ea+i)*sizeof(u16)), 0xFFFF);
|
||||
Memory.Write16(offsetTable.ea + ((io+i)*sizeof(u16)), 0xFFFF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int32_t cellGcmUnmapIoAddress(u64 io)
|
||||
{
|
||||
u32 size;
|
||||
if(size = Memory.RSXIOMem.UnmapAddress(io))
|
||||
{
|
||||
u64 ea;
|
||||
io = io >> 20;
|
||||
ea = Memory.Read16(offsetTable.ea + (io*sizeof(u16)));
|
||||
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
Memory.Write16(offsetTable.io + ((ea+i)*sizeof(u16)), 0xFFFF);
|
||||
Memory.Write16(offsetTable.ea + ((io+i)*sizeof(u16)), 0xFFFF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int32_t cellGcmUnreserveIoMapSize(u32 size)
|
||||
{
|
||||
if(size & 0xFFFFF)
|
||||
return CELL_GCM_ERROR_INVALID_ALIGNMENT;
|
||||
|
||||
if(size > Memory.RSXIOMem.GetResevedAmount())
|
||||
return CELL_GCM_ERROR_INVALID_VALUE;
|
||||
|
||||
Memory.RSXIOMem.Unreserve(size);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void cellGcmSys_init()
|
||||
{
|
||||
current_config.ioAddress = NULL;
|
||||
current_config.localAddress = NULL;
|
||||
|
||||
cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize);
|
||||
cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler);
|
||||
cellGcmSys.AddFunc(0x15bae46b, cellGcmInit);
|
||||
cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand);
|
||||
cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset);
|
||||
cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15);
|
||||
cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode);
|
||||
cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress);
|
||||
cellGcmSys.AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize);
|
||||
cellGcmSys.AddFunc(0x72a577ce, cellGcmGetFlipStatus);
|
||||
cellGcmSys.AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize);
|
||||
@ -637,7 +824,6 @@ void cellGcmSys_init()
|
||||
cellGcmSys.AddFunc(0xd9b7653e, cellGcmUnbindTile);
|
||||
cellGcmSys.AddFunc(0xa75640e8, cellGcmUnbindZcull);
|
||||
cellGcmSys.AddFunc(0xa41ef7e8, cellGcmSetFlipHandler);
|
||||
cellGcmSys.AddFunc(0xa114ec67, cellGcmMapMainMemory);
|
||||
cellGcmSys.AddFunc(0xf80196c1, cellGcmGetLabelAddress);
|
||||
cellGcmSys.AddFunc(0x107bf3a1, cellGcmInitCursor);
|
||||
cellGcmSys.AddFunc(0x1a0de550, cellGcmSetCursorPosition);
|
||||
@ -661,4 +847,17 @@ void cellGcmSys_init()
|
||||
cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency);
|
||||
cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip);
|
||||
cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip);
|
||||
|
||||
//Memory Mapping
|
||||
cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset);
|
||||
cellGcmSys.AddFunc(0xfb81c03e, cellGcmGetMaxIoMapSize);
|
||||
cellGcmSys.AddFunc(0x2922aed0, cellGcmGetOffsetTable);
|
||||
cellGcmSys.AddFunc(0x2a6fba9c, cellGcmIoOffsetToAddress);
|
||||
cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress);
|
||||
cellGcmSys.AddFunc(0xdb769b32, cellGcmMapLocalMemory);
|
||||
cellGcmSys.AddFunc(0xa114ec67, cellGcmMapMainMemory);
|
||||
cellGcmSys.AddFunc(0xa7ede268, cellGcmReserveIoMapSize);
|
||||
cellGcmSys.AddFunc(0xefd00f54, cellGcmUnmapEaIoAddress);
|
||||
cellGcmSys.AddFunc(0xdb23e867, cellGcmUnmapIoAddress);
|
||||
cellGcmSys.AddFunc(0x3b9bd5bd, cellGcmUnreserveIoMapSize);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
#include "cellGifDec.h"
|
||||
|
||||
#include "stblib/stb_image.h"
|
||||
#include "stblib/stb_image.c" // (TODO: Should we put this elsewhere?)
|
||||
@ -8,118 +9,6 @@
|
||||
void cellGifDec_init();
|
||||
Module cellGifDec(0xf010, cellGifDec_init);
|
||||
|
||||
//Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_GIFDEC_ERROR_OPEN_FILE = 0x80611300,
|
||||
CELL_GIFDEC_ERROR_STREAM_FORMAT = 0x80611301,
|
||||
CELL_GIFDEC_ERROR_SEQ = 0x80611302,
|
||||
CELL_GIFDEC_ERROR_ARG = 0x80611303,
|
||||
CELL_GIFDEC_ERROR_FATAL = 0x80611304,
|
||||
CELL_GIFDEC_ERROR_SPU_UNSUPPORT = 0x80611305,
|
||||
CELL_GIFDEC_ERROR_SPU_ERROR = 0x80611306,
|
||||
CELL_GIFDEC_ERROR_CB_PARAM = 0x80611307,
|
||||
};
|
||||
|
||||
enum CellGifDecStreamSrcSel
|
||||
{
|
||||
CELL_GIFDEC_FILE = 0, //Input from a file
|
||||
CELL_GIFDEC_BUFFER = 1, //Input from a buffer
|
||||
};
|
||||
|
||||
enum CellGifDecColorSpace
|
||||
{
|
||||
CELL_GIFDEC_RGBA = 10,
|
||||
CELL_GIFDEC_ARGB = 20,
|
||||
};
|
||||
|
||||
enum CellGifDecRecordType
|
||||
{
|
||||
CELL_GIFDEC_RECORD_TYPE_IMAGE_DESC = 1, // Image data block
|
||||
CELL_GIFDEC_RECORD_TYPE_EXTENSION = 2, // Extension block
|
||||
CELL_GIFDEC_RECORD_TYPE_TERMINATE = 3, // Trailer block
|
||||
};
|
||||
|
||||
enum CellGifDecDecodeStatus
|
||||
{
|
||||
CELL_GIFDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||
CELL_GIFDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||
};
|
||||
|
||||
struct CellGifDecInfo
|
||||
{
|
||||
be_t<u32> SWidth;
|
||||
be_t<u32> SHeight;
|
||||
be_t<u32> SGlobalColorTableFlag;
|
||||
be_t<u32> SColorResolution;
|
||||
be_t<u32> SSortFlag;
|
||||
be_t<u32> SSizeOfGlobalColorTable;
|
||||
be_t<u32> SBackGroundColor;
|
||||
be_t<u32> SPixelAspectRatio;
|
||||
};
|
||||
|
||||
struct CellGifDecSrc
|
||||
{
|
||||
be_t<u32> srcSelect;
|
||||
be_t<u32> fileName;
|
||||
be_t<s64> fileOffset;
|
||||
be_t<u64> fileSize;
|
||||
be_t<u32> streamPtr;
|
||||
be_t<u32> streamSize;
|
||||
be_t<u32> spuThreadEnable;
|
||||
};
|
||||
|
||||
struct CellGifDecInParam
|
||||
{
|
||||
be_t<u32> commandPtr;
|
||||
be_t<u32> colorSpace; // CellGifDecColorSpace
|
||||
be_t<u8> outputColorAlpha1;
|
||||
be_t<u8> outputColorAlpha2;
|
||||
be_t<u8> reserved[2];
|
||||
};
|
||||
|
||||
struct CellGifDecOutParam
|
||||
{
|
||||
be_t<u64> outputWidthByte;
|
||||
be_t<u32> outputWidth;
|
||||
be_t<u32> outputHeight;
|
||||
be_t<u32> outputComponents;
|
||||
be_t<u32> outputBitDepth;
|
||||
be_t<u32> outputColorSpace; // CellGifDecColorSpace
|
||||
be_t<u32> useMemorySpace;
|
||||
};
|
||||
|
||||
struct CellGifDecExtension
|
||||
{
|
||||
be_t<u8> label;
|
||||
be_t<u32> data;
|
||||
};
|
||||
|
||||
struct CellGifDecDataOutInfo
|
||||
{
|
||||
be_t<u32> recordType;
|
||||
CellGifDecExtension outExtension;
|
||||
be_t<u32> status;
|
||||
};
|
||||
|
||||
struct CellGifDecOpnInfo
|
||||
{
|
||||
be_t<u32> initSpaceAllocated;
|
||||
};
|
||||
|
||||
struct CellGifDecDataCtrlParam
|
||||
{
|
||||
be_t<u64> outputBytesPerLine;
|
||||
};
|
||||
|
||||
struct CellGifDecSubHandle //Custom struct
|
||||
{
|
||||
u32 fd;
|
||||
u64 fileSize;
|
||||
CellGifDecInfo info;
|
||||
CellGifDecOutParam outParam;
|
||||
};
|
||||
|
||||
int cellGifDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellGifDec);
|
||||
@ -184,12 +73,10 @@ int cellGifDecOpen(u32 mainHandle, mem32_t subHandle, const mem_ptr_t<CellGifDec
|
||||
|
||||
int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellGifDecInfo> info)
|
||||
{
|
||||
ID sub_handle_id_data;
|
||||
if(!cellGifDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellGifDecSubHandle* subHandle_data;
|
||||
if(!cellGifDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
const u64& fileSize = subHandle_data->fileSize;
|
||||
CellGifDecInfo& current_info = subHandle_data->info;
|
||||
@ -224,12 +111,10 @@ int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellGifDecInfo
|
||||
|
||||
int cellGifDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t<CellGifDecInParam> inParam, mem_ptr_t<CellGifDecOutParam> outParam)
|
||||
{
|
||||
ID sub_handle_id_data;
|
||||
if(!cellGifDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellGifDecSubHandle* subHandle_data;
|
||||
if(!cellGifDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
CellGifDecInfo& current_info = subHandle_data->info;
|
||||
CellGifDecOutParam& current_outParam = subHandle_data->outParam;
|
||||
|
||||
@ -255,12 +140,10 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||
{
|
||||
dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_STOP;
|
||||
|
||||
ID sub_handle_id_data;
|
||||
if(!cellGifDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellGifDecSubHandle* subHandle_data;
|
||||
if(!cellGifDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
const u64& fileSize = subHandle_data->fileSize;
|
||||
const CellGifDecOutParam& current_outParam = subHandle_data->outParam;
|
||||
@ -306,12 +189,10 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||
|
||||
int cellGifDecClose(u32 mainHandle, u32 subHandle)
|
||||
{
|
||||
ID sub_handle_id_data;
|
||||
if(!cellGifDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellGifDecSubHandle* subHandle_data;
|
||||
if(!cellGifDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
cellFsClose(subHandle_data->fd);
|
||||
Emu.GetIdManager().RemoveID(subHandle);
|
||||
|
||||
|
114
rpcs3/Emu/SysCalls/Modules/cellGifDec.h
Normal file
114
rpcs3/Emu/SysCalls/Modules/cellGifDec.h
Normal file
@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
//Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_GIFDEC_ERROR_OPEN_FILE = 0x80611300,
|
||||
CELL_GIFDEC_ERROR_STREAM_FORMAT = 0x80611301,
|
||||
CELL_GIFDEC_ERROR_SEQ = 0x80611302,
|
||||
CELL_GIFDEC_ERROR_ARG = 0x80611303,
|
||||
CELL_GIFDEC_ERROR_FATAL = 0x80611304,
|
||||
CELL_GIFDEC_ERROR_SPU_UNSUPPORT = 0x80611305,
|
||||
CELL_GIFDEC_ERROR_SPU_ERROR = 0x80611306,
|
||||
CELL_GIFDEC_ERROR_CB_PARAM = 0x80611307,
|
||||
};
|
||||
|
||||
enum CellGifDecStreamSrcSel
|
||||
{
|
||||
CELL_GIFDEC_FILE = 0, //Input from a file
|
||||
CELL_GIFDEC_BUFFER = 1, //Input from a buffer
|
||||
};
|
||||
|
||||
enum CellGifDecColorSpace
|
||||
{
|
||||
CELL_GIFDEC_RGBA = 10,
|
||||
CELL_GIFDEC_ARGB = 20,
|
||||
};
|
||||
|
||||
enum CellGifDecRecordType
|
||||
{
|
||||
CELL_GIFDEC_RECORD_TYPE_IMAGE_DESC = 1, // Image data block
|
||||
CELL_GIFDEC_RECORD_TYPE_EXTENSION = 2, // Extension block
|
||||
CELL_GIFDEC_RECORD_TYPE_TERMINATE = 3, // Trailer block
|
||||
};
|
||||
|
||||
enum CellGifDecDecodeStatus
|
||||
{
|
||||
CELL_GIFDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||
CELL_GIFDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||
};
|
||||
|
||||
struct CellGifDecInfo
|
||||
{
|
||||
be_t<u32> SWidth;
|
||||
be_t<u32> SHeight;
|
||||
be_t<u32> SGlobalColorTableFlag;
|
||||
be_t<u32> SColorResolution;
|
||||
be_t<u32> SSortFlag;
|
||||
be_t<u32> SSizeOfGlobalColorTable;
|
||||
be_t<u32> SBackGroundColor;
|
||||
be_t<u32> SPixelAspectRatio;
|
||||
};
|
||||
|
||||
struct CellGifDecSrc
|
||||
{
|
||||
be_t<u32> srcSelect;
|
||||
be_t<u32> fileName;
|
||||
be_t<s64> fileOffset;
|
||||
be_t<u64> fileSize;
|
||||
be_t<u32> streamPtr;
|
||||
be_t<u32> streamSize;
|
||||
be_t<u32> spuThreadEnable;
|
||||
};
|
||||
|
||||
struct CellGifDecInParam
|
||||
{
|
||||
be_t<u32> commandPtr;
|
||||
be_t<u32> colorSpace; // CellGifDecColorSpace
|
||||
be_t<u8> outputColorAlpha1;
|
||||
be_t<u8> outputColorAlpha2;
|
||||
be_t<u8> reserved[2];
|
||||
};
|
||||
|
||||
struct CellGifDecOutParam
|
||||
{
|
||||
be_t<u64> outputWidthByte;
|
||||
be_t<u32> outputWidth;
|
||||
be_t<u32> outputHeight;
|
||||
be_t<u32> outputComponents;
|
||||
be_t<u32> outputBitDepth;
|
||||
be_t<u32> outputColorSpace; // CellGifDecColorSpace
|
||||
be_t<u32> useMemorySpace;
|
||||
};
|
||||
|
||||
struct CellGifDecExtension
|
||||
{
|
||||
be_t<u8> label;
|
||||
be_t<u32> data;
|
||||
};
|
||||
|
||||
struct CellGifDecDataOutInfo
|
||||
{
|
||||
be_t<u32> recordType;
|
||||
CellGifDecExtension outExtension;
|
||||
be_t<u32> status;
|
||||
};
|
||||
|
||||
struct CellGifDecOpnInfo
|
||||
{
|
||||
be_t<u32> initSpaceAllocated;
|
||||
};
|
||||
|
||||
struct CellGifDecDataCtrlParam
|
||||
{
|
||||
be_t<u64> outputBytesPerLine;
|
||||
};
|
||||
|
||||
struct CellGifDecSubHandle //Custom struct
|
||||
{
|
||||
u32 fd;
|
||||
u64 fileSize;
|
||||
CellGifDecInfo info;
|
||||
CellGifDecOutParam outParam;
|
||||
};
|
@ -1,113 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
#include "cellJpgDec.h"
|
||||
#include "stblib/stb_image.h"
|
||||
|
||||
void cellJpgDec_init();
|
||||
Module cellJpgDec(0x000f, cellJpgDec_init);
|
||||
|
||||
//Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_JPGDEC_ERROR_HEADER = 0x80611101,
|
||||
CELL_JPGDEC_ERROR_STREAM_FORMAT = 0x80611102,
|
||||
CELL_JPGDEC_ERROR_ARG = 0x80611103,
|
||||
CELL_JPGDEC_ERROR_SEQ = 0x80611104,
|
||||
CELL_JPGDEC_ERROR_BUSY = 0x80611105,
|
||||
CELL_JPGDEC_ERROR_FATAL = 0x80611106,
|
||||
CELL_JPGDEC_ERROR_OPEN_FILE = 0x80611107,
|
||||
CELL_JPGDEC_ERROR_SPU_UNSUPPORT = 0x80611108,
|
||||
CELL_JPGDEC_ERROR_CB_PARAM = 0x80611109,
|
||||
};
|
||||
|
||||
enum CellJpgDecColorSpace
|
||||
{
|
||||
CELL_JPG_UNKNOWN = 0,
|
||||
CELL_JPG_GRAYSCALE = 1,
|
||||
CELL_JPG_RGB = 2,
|
||||
CELL_JPG_YCbCr = 3,
|
||||
CELL_JPG_RGBA = 10,
|
||||
CELL_JPG_UPSAMPLE_ONLY = 11,
|
||||
CELL_JPG_ARGB = 20,
|
||||
CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA = 40,
|
||||
CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41,
|
||||
};
|
||||
|
||||
enum CellJpgDecDecodeStatus
|
||||
{
|
||||
CELL_JPGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||
CELL_JPGDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||
};
|
||||
|
||||
struct CellJpgDecInfo
|
||||
{
|
||||
be_t<u32> imageWidth;
|
||||
be_t<u32> imageHeight;
|
||||
be_t<u32> numComponents;
|
||||
be_t<u32> colorSpace; // CellJpgDecColorSpace
|
||||
};
|
||||
|
||||
struct CellJpgDecSrc
|
||||
{
|
||||
be_t<u32> srcSelect; // CellJpgDecStreamSrcSel
|
||||
be_t<u32> fileName; // const char*
|
||||
be_t<u64> fileOffset; // int64_t
|
||||
be_t<u32> fileSize;
|
||||
be_t<u32> streamPtr;
|
||||
be_t<u32> streamSize;
|
||||
be_t<u32> spuThreadEnable; // CellJpgDecSpuThreadEna
|
||||
};
|
||||
|
||||
struct CellJpgDecInParam
|
||||
{
|
||||
be_t<u32> commandPtr;
|
||||
be_t<u32> downScale;
|
||||
be_t<u32> method; // CellJpgDecMethod
|
||||
be_t<u32> outputMode; // CellJpgDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellJpgDecColorSpace
|
||||
be_t<u8> outputColorAlpha;
|
||||
be_t<u8> reserved[3];
|
||||
};
|
||||
|
||||
struct CellJpgDecOutParam
|
||||
{
|
||||
be_t<u64> outputWidthByte;
|
||||
be_t<u32> outputWidth;
|
||||
be_t<u32> outputHeight;
|
||||
be_t<u32> outputComponents;
|
||||
be_t<u32> outputMode; // CellJpgDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellJpgDecColorSpace
|
||||
be_t<u32> downScale;
|
||||
be_t<u32> useMemorySpace;
|
||||
};
|
||||
|
||||
struct CellJpgDecOpnInfo
|
||||
{
|
||||
be_t<u32> initSpaceAllocated;
|
||||
};
|
||||
|
||||
struct CellJpgDecDataCtrlParam
|
||||
{
|
||||
be_t<u64> outputBytesPerLine;
|
||||
};
|
||||
|
||||
struct CellJpgDecDataOutInfo
|
||||
{
|
||||
be_t<float> mean;
|
||||
be_t<u32> outputLines;
|
||||
be_t<u32> status;
|
||||
};
|
||||
|
||||
|
||||
struct CellJpgDecSubHandle //Custom struct
|
||||
{
|
||||
u32 fd;
|
||||
u64 fileSize;
|
||||
CellJpgDecInfo info;
|
||||
CellJpgDecOutParam outParam;
|
||||
};
|
||||
|
||||
int cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellJpgDec);
|
||||
@ -153,12 +52,10 @@ int cellJpgDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t<CellJpgDecSrc> s
|
||||
|
||||
int cellJpgDecClose(u32 mainHandle, u32 subHandle)
|
||||
{
|
||||
ID sub_handle_id_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellJpgDecSubHandle* subHandle_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
cellFsClose(subHandle_data->fd);
|
||||
Emu.GetIdManager().RemoveID(subHandle);
|
||||
|
||||
@ -168,12 +65,10 @@ int cellJpgDecClose(u32 mainHandle, u32 subHandle)
|
||||
int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellJpgDecInfo> info)
|
||||
{
|
||||
cellJpgDec.Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr());
|
||||
ID sub_handle_id_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellJpgDecSubHandle* subHandle_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
const u64& fileSize = subHandle_data->fileSize;
|
||||
CellJpgDecInfo& current_info = subHandle_data->info;
|
||||
@ -227,12 +122,10 @@ int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellJpgDecInfo
|
||||
int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_ptr_t<CellJpgDecDataCtrlParam> dataCtrlParam, mem_ptr_t<CellJpgDecDataOutInfo> dataOutInfo)
|
||||
{
|
||||
dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_STOP;
|
||||
ID sub_handle_id_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellJpgDecSubHandle* subHandle_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
const u64& fileSize = subHandle_data->fileSize;
|
||||
const CellJpgDecOutParam& current_outParam = subHandle_data->outParam;
|
||||
@ -292,12 +185,10 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||
|
||||
int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t<CellJpgDecInParam> inParam, mem_ptr_t<CellJpgDecOutParam> outParam)
|
||||
{
|
||||
ID sub_handle_id_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellJpgDecSubHandle* subHandle_data;
|
||||
if(!cellJpgDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
CellJpgDecInfo& current_info = subHandle_data->info;
|
||||
CellJpgDecOutParam& current_outParam = subHandle_data->outParam;
|
||||
|
||||
|
101
rpcs3/Emu/SysCalls/Modules/cellJpgDec.h
Normal file
101
rpcs3/Emu/SysCalls/Modules/cellJpgDec.h
Normal file
@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
|
||||
//Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_JPGDEC_ERROR_HEADER = 0x80611101,
|
||||
CELL_JPGDEC_ERROR_STREAM_FORMAT = 0x80611102,
|
||||
CELL_JPGDEC_ERROR_ARG = 0x80611103,
|
||||
CELL_JPGDEC_ERROR_SEQ = 0x80611104,
|
||||
CELL_JPGDEC_ERROR_BUSY = 0x80611105,
|
||||
CELL_JPGDEC_ERROR_FATAL = 0x80611106,
|
||||
CELL_JPGDEC_ERROR_OPEN_FILE = 0x80611107,
|
||||
CELL_JPGDEC_ERROR_SPU_UNSUPPORT = 0x80611108,
|
||||
CELL_JPGDEC_ERROR_CB_PARAM = 0x80611109,
|
||||
};
|
||||
|
||||
enum CellJpgDecColorSpace
|
||||
{
|
||||
CELL_JPG_UNKNOWN = 0,
|
||||
CELL_JPG_GRAYSCALE = 1,
|
||||
CELL_JPG_RGB = 2,
|
||||
CELL_JPG_YCbCr = 3,
|
||||
CELL_JPG_RGBA = 10,
|
||||
CELL_JPG_UPSAMPLE_ONLY = 11,
|
||||
CELL_JPG_ARGB = 20,
|
||||
CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA = 40,
|
||||
CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41,
|
||||
};
|
||||
|
||||
enum CellJpgDecDecodeStatus
|
||||
{
|
||||
CELL_JPGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||
CELL_JPGDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||
};
|
||||
|
||||
struct CellJpgDecInfo
|
||||
{
|
||||
be_t<u32> imageWidth;
|
||||
be_t<u32> imageHeight;
|
||||
be_t<u32> numComponents;
|
||||
be_t<u32> colorSpace; // CellJpgDecColorSpace
|
||||
};
|
||||
|
||||
struct CellJpgDecSrc
|
||||
{
|
||||
be_t<u32> srcSelect; // CellJpgDecStreamSrcSel
|
||||
be_t<u32> fileName; // const char*
|
||||
be_t<u64> fileOffset; // int64_t
|
||||
be_t<u32> fileSize;
|
||||
be_t<u32> streamPtr;
|
||||
be_t<u32> streamSize;
|
||||
be_t<u32> spuThreadEnable; // CellJpgDecSpuThreadEna
|
||||
};
|
||||
|
||||
struct CellJpgDecInParam
|
||||
{
|
||||
be_t<u32> commandPtr;
|
||||
be_t<u32> downScale;
|
||||
be_t<u32> method; // CellJpgDecMethod
|
||||
be_t<u32> outputMode; // CellJpgDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellJpgDecColorSpace
|
||||
be_t<u8> outputColorAlpha;
|
||||
be_t<u8> reserved[3];
|
||||
};
|
||||
|
||||
struct CellJpgDecOutParam
|
||||
{
|
||||
be_t<u64> outputWidthByte;
|
||||
be_t<u32> outputWidth;
|
||||
be_t<u32> outputHeight;
|
||||
be_t<u32> outputComponents;
|
||||
be_t<u32> outputMode; // CellJpgDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellJpgDecColorSpace
|
||||
be_t<u32> downScale;
|
||||
be_t<u32> useMemorySpace;
|
||||
};
|
||||
|
||||
struct CellJpgDecOpnInfo
|
||||
{
|
||||
be_t<u32> initSpaceAllocated;
|
||||
};
|
||||
|
||||
struct CellJpgDecDataCtrlParam
|
||||
{
|
||||
be_t<u64> outputBytesPerLine;
|
||||
};
|
||||
|
||||
struct CellJpgDecDataOutInfo
|
||||
{
|
||||
be_t<float> mean;
|
||||
be_t<u32> outputLines;
|
||||
be_t<u32> status;
|
||||
};
|
||||
|
||||
struct CellJpgDecSubHandle //Custom struct
|
||||
{
|
||||
u32 fd;
|
||||
u64 fileSize;
|
||||
CellJpgDecInfo info;
|
||||
CellJpgDecOutParam outParam;
|
||||
};
|
@ -1,116 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
#include "cellPngDec.h"
|
||||
#include "stblib/stb_image.h"
|
||||
|
||||
void cellPngDec_init();
|
||||
Module cellPngDec(0x0018, cellPngDec_init);
|
||||
|
||||
//Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_PNGDEC_ERROR_HEADER = 0x80611201,
|
||||
CELL_PNGDEC_ERROR_STREAM_FORMAT = 0x80611202,
|
||||
CELL_PNGDEC_ERROR_ARG = 0x80611203,
|
||||
CELL_PNGDEC_ERROR_SEQ = 0x80611204,
|
||||
CELL_PNGDEC_ERROR_BUSY = 0x80611205,
|
||||
CELL_PNGDEC_ERROR_FATAL = 0x80611206,
|
||||
CELL_PNGDEC_ERROR_OPEN_FILE = 0x80611207,
|
||||
CELL_PNGDEC_ERROR_SPU_UNSUPPORT = 0x80611208,
|
||||
CELL_PNGDEC_ERROR_SPU_ERROR = 0x80611209,
|
||||
CELL_PNGDEC_ERROR_CB_PARAM = 0x8061120a,
|
||||
};
|
||||
|
||||
enum CellPngDecColorSpace
|
||||
{
|
||||
CELL_PNGDEC_GRAYSCALE = 1,
|
||||
CELL_PNGDEC_RGB = 2,
|
||||
CELL_PNGDEC_PALETTE = 4,
|
||||
CELL_PNGDEC_GRAYSCALE_ALPHA = 9,
|
||||
CELL_PNGDEC_RGBA = 10,
|
||||
CELL_PNGDEC_ARGB = 20,
|
||||
};
|
||||
|
||||
enum CellPngDecDecodeStatus
|
||||
{
|
||||
CELL_PNGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||
CELL_PNGDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||
};
|
||||
|
||||
enum CellPngDecStreamSrcSel
|
||||
{
|
||||
CELL_PNGDEC_FILE = 0,
|
||||
CELL_PNGDEC_BUFFER = 1
|
||||
};
|
||||
|
||||
struct CellPngDecDataOutInfo
|
||||
{
|
||||
be_t<u32> chunkInformation;
|
||||
be_t<u32> numText;
|
||||
be_t<u32> numUnknownChunk;
|
||||
be_t<u32> status;
|
||||
};
|
||||
|
||||
struct CellPngDecDataCtrlParam
|
||||
{
|
||||
be_t<u64> outputBytesPerLine;
|
||||
};
|
||||
|
||||
struct CellPngDecInfo
|
||||
{
|
||||
be_t<u32> imageWidth;
|
||||
be_t<u32> imageHeight;
|
||||
be_t<u32> numComponents;
|
||||
be_t<u32> colorSpace; // CellPngDecColorSpace
|
||||
be_t<u32> bitDepth;
|
||||
be_t<u32> interlaceMethod; // CellPngDecInterlaceMode
|
||||
be_t<u32> chunkInformation;
|
||||
};
|
||||
|
||||
struct CellPngDecSrc
|
||||
{
|
||||
be_t<u32> srcSelect; // CellPngDecStreamSrcSel
|
||||
be_t<u32> fileName; // const char*
|
||||
be_t<u64> fileOffset; // int64_t
|
||||
be_t<u32> fileSize;
|
||||
be_t<u32> streamPtr;
|
||||
be_t<u32> streamSize;
|
||||
be_t<u32> spuThreadEnable; // CellPngDecSpuThreadEna
|
||||
};
|
||||
|
||||
struct CellPngDecInParam
|
||||
{
|
||||
be_t<u32> commandPtr;
|
||||
be_t<u32> outputMode; // CellPngDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellPngDecColorSpace
|
||||
be_t<u32> outputBitDepth;
|
||||
be_t<u32> outputPackFlag; // CellPngDecPackFlag
|
||||
be_t<u32> outputAlphaSelect; // CellPngDecAlphaSelect
|
||||
be_t<u32> outputColorAlpha;
|
||||
};
|
||||
|
||||
struct CellPngDecOutParam
|
||||
{
|
||||
be_t<u64> outputWidthByte;
|
||||
be_t<u32> outputWidth;
|
||||
be_t<u32> outputHeight;
|
||||
be_t<u32> outputComponents;
|
||||
be_t<u32> outputBitDepth;
|
||||
be_t<u32> outputMode; // CellPngDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellPngDecColorSpace
|
||||
be_t<u32> useMemorySpace;
|
||||
};
|
||||
|
||||
struct CellPngDecSubHandle //Custom struct
|
||||
{
|
||||
u32 fd;
|
||||
u64 fileSize;
|
||||
CellPngDecInfo info;
|
||||
CellPngDecOutParam outParam;
|
||||
CellPngDecSrc src;
|
||||
};
|
||||
|
||||
int cellPngDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||
@ -164,12 +60,10 @@ int cellPngDecClose(u32 mainHandle, u32 subHandle)
|
||||
{
|
||||
cellPngDec.Warning("cellPngDecClose(mainHandle=0x%x,subHandle=0x%x)", mainHandle, subHandle);
|
||||
|
||||
ID sub_handle_id_data;
|
||||
if(!cellPngDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellPngDecSubHandle* subHandle_data;
|
||||
if(!cellPngDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
cellFsClose(subHandle_data->fd);
|
||||
Emu.GetIdManager().RemoveID(subHandle);
|
||||
|
||||
@ -179,12 +73,10 @@ int cellPngDecClose(u32 mainHandle, u32 subHandle)
|
||||
int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellPngDecInfo> info)
|
||||
{
|
||||
cellPngDec.Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr());
|
||||
ID sub_handle_id_data;
|
||||
if(!cellPngDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellPngDecSubHandle* subHandle_data;
|
||||
if(!cellPngDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
const u64& fileSize = subHandle_data->fileSize;
|
||||
CellPngDecInfo& current_info = subHandle_data->info;
|
||||
@ -238,12 +130,10 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_ptr_t<CellPngDecInfo
|
||||
int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_ptr_t<CellPngDecDataCtrlParam> dataCtrlParam, mem_ptr_t<CellPngDecDataOutInfo> dataOutInfo)
|
||||
{
|
||||
dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP;
|
||||
ID sub_handle_id_data;
|
||||
if(!cellPngDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellPngDecSubHandle* subHandle_data;
|
||||
if(!cellPngDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
const u32& fd = subHandle_data->fd;
|
||||
const u64& fileSize = subHandle_data->fileSize;
|
||||
const CellPngDecOutParam& current_outParam = subHandle_data->outParam;
|
||||
@ -306,12 +196,10 @@ int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const m
|
||||
|
||||
int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, const mem_ptr_t<CellPngDecInParam> inParam, mem_ptr_t<CellPngDecOutParam> outParam)
|
||||
{
|
||||
ID sub_handle_id_data;
|
||||
if(!cellPngDec.CheckId(subHandle, sub_handle_id_data))
|
||||
CellPngDecSubHandle* subHandle_data;
|
||||
if(!cellPngDec.CheckId(subHandle, subHandle_data))
|
||||
return CELL_PNGDEC_ERROR_FATAL;
|
||||
|
||||
auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data;
|
||||
|
||||
CellPngDecInfo& current_info = subHandle_data->info;
|
||||
CellPngDecOutParam& current_outParam = subHandle_data->outParam;
|
||||
|
||||
|
105
rpcs3/Emu/SysCalls/Modules/cellPngDec.h
Normal file
105
rpcs3/Emu/SysCalls/Modules/cellPngDec.h
Normal file
@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
//Return Codes
|
||||
enum
|
||||
{
|
||||
CELL_PNGDEC_ERROR_HEADER = 0x80611201,
|
||||
CELL_PNGDEC_ERROR_STREAM_FORMAT = 0x80611202,
|
||||
CELL_PNGDEC_ERROR_ARG = 0x80611203,
|
||||
CELL_PNGDEC_ERROR_SEQ = 0x80611204,
|
||||
CELL_PNGDEC_ERROR_BUSY = 0x80611205,
|
||||
CELL_PNGDEC_ERROR_FATAL = 0x80611206,
|
||||
CELL_PNGDEC_ERROR_OPEN_FILE = 0x80611207,
|
||||
CELL_PNGDEC_ERROR_SPU_UNSUPPORT = 0x80611208,
|
||||
CELL_PNGDEC_ERROR_SPU_ERROR = 0x80611209,
|
||||
CELL_PNGDEC_ERROR_CB_PARAM = 0x8061120a,
|
||||
};
|
||||
|
||||
enum CellPngDecColorSpace
|
||||
{
|
||||
CELL_PNGDEC_GRAYSCALE = 1,
|
||||
CELL_PNGDEC_RGB = 2,
|
||||
CELL_PNGDEC_PALETTE = 4,
|
||||
CELL_PNGDEC_GRAYSCALE_ALPHA = 9,
|
||||
CELL_PNGDEC_RGBA = 10,
|
||||
CELL_PNGDEC_ARGB = 20,
|
||||
};
|
||||
|
||||
enum CellPngDecDecodeStatus
|
||||
{
|
||||
CELL_PNGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||
CELL_PNGDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||
};
|
||||
|
||||
enum CellPngDecStreamSrcSel
|
||||
{
|
||||
CELL_PNGDEC_FILE = 0,
|
||||
CELL_PNGDEC_BUFFER = 1,
|
||||
};
|
||||
|
||||
struct CellPngDecDataOutInfo
|
||||
{
|
||||
be_t<u32> chunkInformation;
|
||||
be_t<u32> numText;
|
||||
be_t<u32> numUnknownChunk;
|
||||
be_t<u32> status;
|
||||
};
|
||||
|
||||
struct CellPngDecDataCtrlParam
|
||||
{
|
||||
be_t<u64> outputBytesPerLine;
|
||||
};
|
||||
|
||||
struct CellPngDecInfo
|
||||
{
|
||||
be_t<u32> imageWidth;
|
||||
be_t<u32> imageHeight;
|
||||
be_t<u32> numComponents;
|
||||
be_t<u32> colorSpace; // CellPngDecColorSpace
|
||||
be_t<u32> bitDepth;
|
||||
be_t<u32> interlaceMethod; // CellPngDecInterlaceMode
|
||||
be_t<u32> chunkInformation;
|
||||
};
|
||||
|
||||
struct CellPngDecSrc
|
||||
{
|
||||
be_t<u32> srcSelect; // CellPngDecStreamSrcSel
|
||||
be_t<u32> fileName; // const char*
|
||||
be_t<u64> fileOffset; // int64_t
|
||||
be_t<u32> fileSize;
|
||||
be_t<u32> streamPtr;
|
||||
be_t<u32> streamSize;
|
||||
be_t<u32> spuThreadEnable; // CellPngDecSpuThreadEna
|
||||
};
|
||||
|
||||
struct CellPngDecInParam
|
||||
{
|
||||
be_t<u32> commandPtr;
|
||||
be_t<u32> outputMode; // CellPngDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellPngDecColorSpace
|
||||
be_t<u32> outputBitDepth;
|
||||
be_t<u32> outputPackFlag; // CellPngDecPackFlag
|
||||
be_t<u32> outputAlphaSelect; // CellPngDecAlphaSelect
|
||||
be_t<u32> outputColorAlpha;
|
||||
};
|
||||
|
||||
struct CellPngDecOutParam
|
||||
{
|
||||
be_t<u64> outputWidthByte;
|
||||
be_t<u32> outputWidth;
|
||||
be_t<u32> outputHeight;
|
||||
be_t<u32> outputComponents;
|
||||
be_t<u32> outputBitDepth;
|
||||
be_t<u32> outputMode; // CellPngDecOutputMode
|
||||
be_t<u32> outputColorSpace; // CellPngDecColorSpace
|
||||
be_t<u32> useMemorySpace;
|
||||
};
|
||||
|
||||
struct CellPngDecSubHandle //Custom struct
|
||||
{
|
||||
u32 fd;
|
||||
u64 fileSize;
|
||||
CellPngDecInfo info;
|
||||
CellPngDecOutParam outParam;
|
||||
CellPngDecSrc src;
|
||||
};
|
@ -76,7 +76,7 @@ CCellRescInternal* s_rescInternalInstance = new CCellRescInternal();
|
||||
// Extern Functions
|
||||
extern int cellGcmSetFlipMode(u32 mode);
|
||||
extern int cellGcmSetFlipHandler(u32 handler_addr);
|
||||
extern int cellGcmAddressToOffset(u32 address, mem32_t offset);
|
||||
extern int32_t cellGcmAddressToOffset(u64 address, mem32_t offset);
|
||||
extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height);
|
||||
extern int cellGcmSetPrepareFlip(mem_ptr_t<CellGcmContextData> ctx, u32 id);
|
||||
extern int cellGcmSetSecondVFrequency(u32 freq);
|
||||
|
@ -3,10 +3,9 @@
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
void sys_fs_init();
|
||||
void sys_fs_unload();
|
||||
Module sys_fs(0x000e, sys_fs_init, nullptr, sys_fs_unload);
|
||||
Module sys_fs(0x000e, sys_fs_init);
|
||||
|
||||
std::atomic<u32> g_FsAioReadID = 0;
|
||||
Array<vfsStream*> FDs;
|
||||
|
||||
bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp)
|
||||
{
|
||||
@ -138,10 +137,12 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*)(u32 xaio_addr, u32 error, int xid, u64 size)> func)
|
||||
void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*)(mem_ptr_t<CellFsAio> xaio, u32 error, int xid, u64 size)> func)
|
||||
{
|
||||
vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd];
|
||||
const wxString path = orig_file.GetPath().AfterFirst('/');
|
||||
vfsFileBase* orig_file;
|
||||
if(!sys_fs.CheckId(fd, orig_file)) return;
|
||||
|
||||
const wxString path = orig_file->GetPath().AfterFirst('/');
|
||||
|
||||
u64 nbytes = (u64)aio->size;
|
||||
const u32 buf_addr = (u32)aio->buf_addr;
|
||||
@ -176,22 +177,18 @@ void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*
|
||||
|
||||
//start callback thread
|
||||
//if(func)
|
||||
//func.async(aio.GetAddr(), error, xid, res);
|
||||
//func.async(aio, error, xid, res);
|
||||
|
||||
ConLog.Warning("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=%d, res=%d, xid=%d [%s])",
|
||||
fd, (u64)aio->offset, buf_addr, (u64)aio->size, res, xid, path.c_str());
|
||||
}
|
||||
|
||||
int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void (*)(u32 xaio_addr, u32 error, int xid, u64 size)> func)
|
||||
int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void (*)(mem_ptr_t<CellFsAio> xaio, u32 error, int xid, u64 size)> func)
|
||||
{
|
||||
sys_fs.Warning("cellFsAioRead(aio_addr=0x%x, id_addr=0x%x, func_addr=0x%x)", aio.GetAddr(), aio_id.GetAddr(), func.GetAddr());
|
||||
//ID id;
|
||||
u32 fd = (u32)aio->fd;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||
//vfsFileBase& orig_file = *(vfsFileBase*)id.m_data;
|
||||
vfsFileBase& orig_file = *(vfsFileBase*)FDs[fd];
|
||||
vfsFileBase* orig_file;
|
||||
u32 fd = aio->fd;
|
||||
if(!sys_fs.CheckId(fd, orig_file)) return CELL_ESRCH;
|
||||
|
||||
//get a unique id for the callback (may be used by cellFsAioCancel)
|
||||
const u32 xid = g_FsAioReadID++;
|
||||
@ -209,13 +206,13 @@ int cellFsAioRead(mem_ptr_t<CellFsAio> aio, mem32_t aio_id, mem_func_ptr_t<void
|
||||
|
||||
int cellFsAioInit(mem8_ptr_t mount_point)
|
||||
{
|
||||
sys_fs.Warning("cellFsAioInit(mount_point_addr=0x%x)", mount_point.GetAddr());
|
||||
sys_fs.Warning("cellFsAioInit(mount_point_addr=0x%x (%s))", mount_point.GetAddr(), (char*)mount_point.GetPtr());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellFsAioFinish(mem8_ptr_t mount_point)
|
||||
{
|
||||
sys_fs.Warning("cellFsAioFinish(mount_point_addr=0x%x)", mount_point.GetAddr());
|
||||
sys_fs.Warning("cellFsAioFinish(mount_point_addr=0x%x (%s))", mount_point.GetAddr(), (char*)mount_point.GetPtr());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -243,16 +240,3 @@ void sys_fs_init()
|
||||
sys_fs.AddFunc(0xdb869f20, cellFsAioInit);
|
||||
sys_fs.AddFunc(0x9f951810, cellFsAioFinish);
|
||||
}
|
||||
|
||||
void sys_fs_unload()
|
||||
{
|
||||
for (u32 i = 0; i < FDs.GetCount(); i++)
|
||||
{
|
||||
if (FDs[i])
|
||||
{
|
||||
FDs[i]->Close();
|
||||
delete FDs[i];
|
||||
}
|
||||
}
|
||||
FDs.Clear();
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
#include "lv2/SC_Rwlock.h"
|
||||
#include "lv2/SC_SPU_Thread.h"
|
||||
#include "lv2/SC_Lwmutex.h"
|
||||
#include "Emu/event.h"
|
||||
//#define SYSCALLS_DEBUG
|
||||
|
||||
#define declCPU PPUThread& CPU = GetCurrentPPUThread
|
||||
@ -87,28 +88,29 @@ public:
|
||||
|
||||
bool CheckId(u32 id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetIDData(id).m_name.Cmp(GetName());
|
||||
}
|
||||
|
||||
bool CheckId(u32 id, ID& _id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && !(_id = Emu.GetIdManager().GetIDData(id)).m_name.Cmp(GetName());
|
||||
return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetID(id).m_name.Cmp(GetName());
|
||||
}
|
||||
|
||||
template<typename T> bool CheckId(u32 id, T*& data)
|
||||
{
|
||||
ID id_data;
|
||||
ID* id_data;
|
||||
|
||||
if(!CheckId(id, id_data)) return false;
|
||||
|
||||
data = (T*)id_data.m_data;
|
||||
data = id_data->m_data->get<T>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 GetNewId(void* data = nullptr, u8 flags = 0)
|
||||
template<> bool CheckId(u32 id, ID*& _id)
|
||||
{
|
||||
return Emu.GetIdManager().GetNewID(GetName(), data, flags);
|
||||
return Emu.GetIdManager().CheckID(id) && !(_id = &Emu.GetIdManager().GetID(id))->m_name.Cmp(GetName());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
u32 GetNewId(T* data, u8 flags = 0)
|
||||
{
|
||||
return Emu.GetIdManager().GetNewID<T>(GetName(), data, flags);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -150,7 +150,8 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
|
||||
return false;
|
||||
}
|
||||
|
||||
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(equeue_id).m_data;
|
||||
EventQueue* equeue;
|
||||
Emu.GetIdManager().GetIDData(equeue_id, equeue);
|
||||
for(int i=0; i<equeue->pos; ++i)
|
||||
{
|
||||
if(!equeue->ports[i]->has_data && equeue->ports[i]->thread)
|
||||
@ -225,8 +226,10 @@ int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id)
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
EventPort* eport = (EventPort*)Emu.GetIdManager().GetIDData(event_port_id).m_data;
|
||||
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(event_queue_id).m_data;
|
||||
EventPort* eport;
|
||||
EventQueue* equeue;
|
||||
Emu.GetIdManager().GetIDData(event_port_id, eport);
|
||||
Emu.GetIdManager().GetIDData(event_queue_id, equeue);
|
||||
equeue->ports[equeue->pos++] = eport;
|
||||
eport->queue[eport->pos++] = equeue;
|
||||
|
||||
@ -243,7 +246,8 @@ int sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3)
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
EventPort* eport = (EventPort*)Emu.GetIdManager().GetIDData(event_port_id).m_data;
|
||||
EventPort* eport;
|
||||
Emu.GetIdManager().GetIDData(event_port_id, eport);
|
||||
|
||||
if(!eport->pos)
|
||||
{
|
||||
|
@ -3,11 +3,10 @@
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
|
||||
extern Module sys_fs;
|
||||
extern Array<vfsStream*> FDs;
|
||||
|
||||
int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
{
|
||||
const wxString& path = wxString(Memory.ReadString(path_addr), wxConvUTF8);
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sys_fs.Log("cellFsOpen(path: %s, flags: 0x%x, fd_addr: 0x%x, arg_addr: 0x%x, size: 0x%llx)",
|
||||
path.mb_str(), flags, fd.GetAddr(), arg.GetAddr(), size);
|
||||
|
||||
@ -18,29 +17,6 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
if(flags & CELL_O_CREAT)
|
||||
{
|
||||
_oflags &= ~CELL_O_CREAT;
|
||||
/*
|
||||
//create path
|
||||
for(uint p=1;p<ppath.Length();p++)
|
||||
{
|
||||
for(;p<ppath.Length(); p++) if(ppath[p] == '/') break;
|
||||
|
||||
if(p == ppath.Length()) break;
|
||||
const wxString& dir = ppath(0, p);
|
||||
if(!wxDirExists(dir))
|
||||
{
|
||||
ConLog.Write("create dir: %s", dir);
|
||||
wxMkdir(dir);
|
||||
}
|
||||
}
|
||||
//create file
|
||||
if(!wxFileExists(ppath))
|
||||
{
|
||||
wxFile f;
|
||||
f.Create(ppath);
|
||||
f.Close();
|
||||
}
|
||||
*/
|
||||
|
||||
Emu.GetVFS().Create(ppath);
|
||||
}
|
||||
|
||||
@ -95,8 +71,7 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
fd = FDs.AddCpy(stream);
|
||||
//fd = sys_fs.GetNewId(stream, flags);
|
||||
fd = sys_fs.GetNewId(stream, flags);
|
||||
ConLog.Warning("*** cellFsOpen(path: %s): fd=%d", path.mb_str(), fd.GetValue());
|
||||
|
||||
return CELL_OK;
|
||||
@ -106,12 +81,8 @@ int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
|
||||
{
|
||||
sys_fs.Log("cellFsRead(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nread_addr: 0x%x)",
|
||||
fd, buf_addr, nbytes, nread.GetAddr());
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||
vfsStream* file;
|
||||
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
|
||||
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
|
||||
{
|
||||
@ -119,7 +90,7 @@ int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
|
||||
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
|
||||
}
|
||||
|
||||
const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
||||
const u64 res = nbytes ? file->Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
||||
|
||||
if(nread.IsGood())
|
||||
nread = res;
|
||||
@ -131,12 +102,8 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
|
||||
{
|
||||
sys_fs.Log("cellFsWrite(fd: %d, buf_addr: 0x%x, nbytes: 0x%llx, nwrite_addr: 0x%x)",
|
||||
fd, buf_addr, nbytes, nwrite.GetAddr());
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||
vfsStream* file;
|
||||
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
|
||||
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
|
||||
{
|
||||
@ -144,7 +111,7 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
|
||||
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
|
||||
}
|
||||
|
||||
const u64 res = nbytes ? file.Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
||||
const u64 res = nbytes ? file->Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
||||
|
||||
if(nwrite.IsGood())
|
||||
nwrite = res;
|
||||
@ -155,16 +122,10 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
|
||||
int cellFsClose(u32 fd)
|
||||
{
|
||||
sys_fs.Warning("cellFsClose(fd: %d)", fd);
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||
file.Close();
|
||||
delete FDs[fd];
|
||||
//Emu.GetIdManager().RemoveID(fd);
|
||||
FDs[fd] = nullptr;
|
||||
|
||||
if(!Emu.GetIdManager().RemoveID(fd))
|
||||
return CELL_ESRCH;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -246,12 +207,9 @@ int cellFsStat(const u32 path_addr, mem_ptr_t<CellFsStat> sb)
|
||||
int cellFsFstat(u32 fd, mem_ptr_t<CellFsStat> sb)
|
||||
{
|
||||
sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr());
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||
|
||||
vfsStream* file;
|
||||
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
|
||||
sb->st_mode =
|
||||
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
|
||||
@ -264,7 +222,7 @@ int cellFsFstat(u32 fd, mem_ptr_t<CellFsStat> sb)
|
||||
sb->st_atime_ = 0; //TODO
|
||||
sb->st_mtime_ = 0; //TODO
|
||||
sb->st_ctime_ = 0; //TODO
|
||||
sb->st_size = file.GetSize();
|
||||
sb->st_size = file->GetSize();
|
||||
sb->st_blksize = 4096;
|
||||
|
||||
return CELL_OK;
|
||||
@ -330,35 +288,28 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
|
||||
sys_fs.Error(fd, "Unknown seek whence! (%d)", whence);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||
pos = file.Seek(offset, seek_mode);
|
||||
|
||||
vfsStream* file;
|
||||
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
pos = file->Seek(offset, seek_mode);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellFsFtruncate(u32 fd, u64 size)
|
||||
{
|
||||
sys_fs.Log("cellFsFtruncate(fd: %d, size: %lld)", fd, size);
|
||||
//ID id;
|
||||
//if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||
if (fd >= FDs.GetCount()) return CELL_ESRCH;
|
||||
if (FDs[fd] == nullptr) return CELL_ESRCH;
|
||||
//vfsStream& file = *(vfsStream*)id.m_data;
|
||||
vfsStream& file = *(vfsStream*)FDs[fd];
|
||||
u64 initialSize = file.GetSize();
|
||||
vfsStream* file;
|
||||
if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH;
|
||||
u64 initialSize = file->GetSize();
|
||||
|
||||
if (initialSize < size)
|
||||
{
|
||||
u64 last_pos = file.Tell();
|
||||
file.Seek(0, vfsSeekEnd);
|
||||
u64 last_pos = file->Tell();
|
||||
file->Seek(0, vfsSeekEnd);
|
||||
static const char nullbyte = 0;
|
||||
file.Seek(size-initialSize-1, vfsSeekCur);
|
||||
file.Write(&nullbyte, sizeof(char));
|
||||
file.Seek(last_pos, vfsSeekSet);
|
||||
file->Seek(size-initialSize-1, vfsSeekCur);
|
||||
file->Write(&nullbyte, sizeof(char));
|
||||
file->Seek(last_pos, vfsSeekSet);
|
||||
}
|
||||
|
||||
if (initialSize > size)
|
||||
|
@ -20,16 +20,15 @@ struct HeapInfo
|
||||
int sys_heap_create_heap(const u32 heap_addr, const u32 align, const u32 size)
|
||||
{
|
||||
sc_heap.Warning("sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size);
|
||||
return Emu.GetIdManager().GetNewID(sc_heap.GetName(), new HeapInfo(heap_addr, align, size));
|
||||
return sc_heap.GetNewId(new HeapInfo(heap_addr, align, size));
|
||||
}
|
||||
|
||||
int sys_heap_malloc(const u32 heap_id, const u32 size)
|
||||
{
|
||||
sc_heap.Warning("sys_heap_malloc(heap_id=0x%x, size=0x%x)", heap_id, size);
|
||||
if(!Emu.GetIdManager().CheckID(heap_id)) return CELL_ESRCH;
|
||||
const ID& id = Emu.GetIdManager().GetIDData(heap_id);
|
||||
if(!!id.m_name.Cmp(sc_heap.GetName())) return CELL_ESRCH;
|
||||
const HeapInfo& heap = *(HeapInfo*)id.m_data;
|
||||
|
||||
return Memory.Alloc(size, heap.align);
|
||||
HeapInfo* heap;
|
||||
if(!sc_heap.CheckId(heap_id, heap)) return CELL_ESRCH;
|
||||
|
||||
return Memory.Alloc(size, heap->align);
|
||||
}
|
@ -141,7 +141,7 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32
|
||||
|
||||
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
Memory.Write32(thread_id_addr, new_thread.GetId());
|
||||
Memory.Write64(thread_id_addr, new_thread.GetId());
|
||||
new_thread.SetEntry(entry);
|
||||
new_thread.SetArg(0, arg);
|
||||
new_thread.SetPrio(prio);
|
||||
@ -175,6 +175,6 @@ int sys_ppu_thread_get_id(const u32 id_addr)
|
||||
{
|
||||
sysPrxForUser.Log("sys_ppu_thread_get_id(id_addr=0x%x)", id_addr);
|
||||
|
||||
Memory.Write32(id_addr, GetCurrentPPUThread().GetId());
|
||||
Memory.Write64(id_addr, GetCurrentPPUThread().GetId());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -86,13 +86,12 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||
sc_spu.Warning("sys_spu_thread_initialize(thread_addr=0x%x, group=0x%x, spu_num=%d, img_addr=0x%x, attr_addr=0x%x, arg_addr=0x%x)",
|
||||
thread.GetAddr(), group, spu_num, img.GetAddr(), attr.GetAddr(), arg.GetAddr());
|
||||
|
||||
if(!Emu.GetIdManager().CheckID(group))
|
||||
SpuGroupInfo* group_info;
|
||||
if(!Emu.GetIdManager().GetIDData(group, group_info))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
SpuGroupInfo& group_info = *(SpuGroupInfo*)Emu.GetIdManager().GetIDData(group).m_data;
|
||||
|
||||
if(!thread.IsGood() || !img.IsGood() || !attr.IsGood() || !attr.IsGood())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
@ -108,7 +107,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if(group_info.threads[spu_num])
|
||||
if(group_info->threads[spu_num])
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
@ -136,7 +135,7 @@ int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t<
|
||||
|
||||
thread = new_thread.GetId();
|
||||
|
||||
group_info.threads[spu_num] = &new_thread;
|
||||
group_info->threads[spu_num] = &new_thread;
|
||||
|
||||
/*ConLog.Write("New SPU Thread:");
|
||||
ConLog.Write("SPU img offset = 0x%x", (u32)img->segs_addr);
|
||||
@ -186,15 +185,18 @@ int sys_spu_thread_group_start(u32 id)
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
ID& id_data = Emu.GetIdManager().GetIDData(id);
|
||||
SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data;
|
||||
SpuGroupInfo* group_info;
|
||||
if(!Emu.GetIdManager().GetIDData(id, group_info))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
//Emu.Pause();
|
||||
for(int i=0; i<g_spu_group_thr_count; i++)
|
||||
{
|
||||
if(group_info.threads[i])
|
||||
if(group_info->threads[i])
|
||||
{
|
||||
group_info.threads[i]->Exec();
|
||||
group_info->threads[i]->Exec();
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,20 +208,18 @@ int sys_spu_thread_group_suspend(u32 id)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_suspend(id=0x%x)", id);
|
||||
|
||||
if(!Emu.GetIdManager().CheckID(id))
|
||||
SpuGroupInfo* group_info;
|
||||
if(!Emu.GetIdManager().GetIDData(id, group_info))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
ID& id_data = Emu.GetIdManager().GetIDData(id);
|
||||
SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data;
|
||||
|
||||
//Emu.Pause();
|
||||
for(int i=0; i<g_spu_group_thr_count; i++)
|
||||
{
|
||||
if(group_info.threads[i])
|
||||
if(group_info->threads[i])
|
||||
{
|
||||
group_info.threads[i]->Pause();
|
||||
group_info->threads[i]->Pause();
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,15 +253,13 @@ int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_join(id=0x%x, cause_addr=0x%x, status_addr=0x%x)", id, cause.GetAddr(), status.GetAddr());
|
||||
|
||||
if(!Emu.GetIdManager().CheckID(id))
|
||||
SpuGroupInfo* group_info;
|
||||
if(!Emu.GetIdManager().GetIDData(id, group_info))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
ID& id_data = Emu.GetIdManager().GetIDData(id);
|
||||
SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data;
|
||||
|
||||
if (_InterlockedCompareExchange(&group_info.lock, 1, 0)) //get lock
|
||||
if (_InterlockedCompareExchange(&group_info->lock, 1, 0)) //get lock
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
@ -271,13 +269,13 @@ int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
||||
|
||||
for(int i=0; i<g_spu_group_thr_count; i++)
|
||||
{
|
||||
if(group_info.threads[i])
|
||||
if(group_info->threads[i])
|
||||
{
|
||||
while (!group_info.threads[i]->IsStopped()) Sleep(1);
|
||||
while (!group_info->threads[i]->IsStopped()) Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
_InterlockedExchange(&group_info.lock, 0); //release lock
|
||||
_InterlockedExchange(&group_info->lock, 0); //release lock
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -490,7 +488,7 @@ int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32
|
||||
id, eq, req, spup_addr);
|
||||
|
||||
EventQueue* equeue;
|
||||
if(!Emu.GetIdManager().CheckID(id) || !sys_event.CheckId(eq, equeue))
|
||||
if(!sys_event.CheckId(eq, equeue))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
@ -500,7 +498,11 @@ int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
SpuGroupInfo* group = (SpuGroupInfo*)Emu.GetIdManager().GetIDData(id).m_data;
|
||||
SpuGroupInfo* group;
|
||||
if(!Emu.GetIdManager().GetIDData(id, group))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
for(int i=0; i<g_spu_group_thr_count; ++i)
|
||||
{
|
||||
|
@ -842,47 +842,6 @@ void MainFrame::OnQuit(wxCloseEvent& event)
|
||||
TheApp->Exit();
|
||||
}
|
||||
|
||||
struct state_hdr
|
||||
{
|
||||
u32 magic;
|
||||
u16 version;
|
||||
u32 mem_count;
|
||||
u32 mem_offset;
|
||||
u32 mem_size;
|
||||
u32 hle_count;
|
||||
u32 hle_offset;
|
||||
};
|
||||
|
||||
static const u32 state_magic = *(u32*)"R3SS";
|
||||
static const u32 state_version = 0x1000;
|
||||
|
||||
void MakeSaveState(wxFile& f)
|
||||
{
|
||||
const ArrayF<MemoryBlock>& mb = Memory.MemoryBlocks;
|
||||
|
||||
state_hdr state;
|
||||
memset(&state, 0, sizeof(state_hdr));
|
||||
|
||||
state.magic = state_magic;
|
||||
state.version = state_version;
|
||||
state.mem_count = mb.GetCount();
|
||||
//state.hle_count = mb.GetCount();
|
||||
|
||||
state.mem_offset = sizeof(state_hdr) + 4;
|
||||
|
||||
f.Seek(state.mem_offset);
|
||||
for(u32 i=0; i<state.mem_count; ++i)
|
||||
{
|
||||
state.mem_size += mb[i].GetSize();
|
||||
f.Write(mb[i].GetMem(), mb[i].GetSize());
|
||||
}
|
||||
|
||||
state.hle_offset = state.mem_offset + state.mem_size + 4;
|
||||
|
||||
f.Seek(0);
|
||||
f.Write(&state, sizeof(state_hdr));
|
||||
}
|
||||
|
||||
void MainFrame::OnKeyDown(wxKeyEvent& event)
|
||||
{
|
||||
if(wxGetActiveWindow() /*== this*/ && event.ControlDown())
|
||||
|
@ -32,6 +32,7 @@ bool Rpcs3App::OnInit()
|
||||
m_MainFrame->Show();
|
||||
|
||||
m_MainFrame->DoSettings(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@
|
||||
<DataExecutionPrevention>false</DataExecutionPrevention>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>$(SolutionDir)\Utilities\git-version-gen.cmd</Command>
|
||||
<Command>"$(SolutionDir)\Utilities\git-version-gen.cmd"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
Loading…
Reference in New Issue
Block a user