- Implemented HDD manager.

- Implemented VFS manager.
- Implemented MFC.
- Fixed ELF Compiler.
- Improved HLE Func binder.
This commit is contained in:
DH 2013-08-03 12:40:03 +03:00
parent 559852a8fc
commit 81e874c9e2
52 changed files with 2684 additions and 468 deletions

View file

@ -2,6 +2,7 @@
template<typename T> class Array
{
protected:
u32 m_count;
T* m_array;
@ -120,7 +121,13 @@ public:
u32 count = m_count;
m_count = 0;
for(u32 i=0; i<count; ++i) m_array[i].~T();
safe_delete(m_array);
safe_free(m_array);
}
inline void ClearF()
{
m_count = 0;
safe_free(m_array);
}
inline T& Get(u32 num)
@ -129,15 +136,15 @@ public:
return m_array[num];
}
u32 GetCount() const { return m_count; }
virtual u32 GetCount() const { return m_count; }
void SetCount(const u32 count, bool memzero = true)
virtual void SetCount(const u32 count, bool memzero = true)
{
if(GetCount() >= count) return;
if(m_count >= count) return;
_InsertRoomEnd(count - GetCount());
_InsertRoomEnd(count - m_count);
if(memzero) memset(m_array + GetCount(), 0, count - GetCount());
if(memzero) memset(m_array + m_count - count, 0, sizeof(T) * (m_count - count));
}
void Reserve(const u32 count)
@ -162,6 +169,7 @@ public:
}
inline T* GetPtr() { return m_array; }
inline const T* GetPtr() const { return m_array; }
T& operator[](u32 num) const { return m_array[num]; }
@ -185,6 +193,96 @@ protected:
}
};
class ArrayString : public Array<char>
{
public:
ArrayString() : Array()
{
}
ArrayString(const wxString& value) : Array()
{
*this = value;
}
ArrayString(const char* value) : Array()
{
*this = value;
}
virtual u32 GetCount() const
{
return m_array ? strlen(m_array) : 0;
}
virtual void SetCount(const u32 count, bool memzero = true)
{
if(m_count && count < m_count - 1)
{
m_array[count] = '\0';
}
else
{
Array::SetCount(count + 1, memzero);
}
}
ArrayString& operator = (const char* right)
{
Clear();
if(right)
{
size_t len = strlen(right);
if(len)
{
SetCount(len);
memcpy(m_array, right, len * sizeof(char));
m_array[len] = '\0';
}
}
return *this;
}
ArrayString& operator = (const ArrayString& right)
{
Clear();
if(size_t len = right.GetCount())
{
SetCount(len);
memcpy(m_array, right.GetPtr(), len * sizeof(char));
m_array[len] = '\0';
}
return *this;
}
ArrayString& operator = (const wxString& right)
{
Clear();
if(size_t len = right.Len())
{
SetCount(len);
memcpy(m_array, right.c_str(), len * sizeof(char));
m_array[len] = '\0';
}
return *this;
}
ArrayString* Clone() const
{
ArrayString* new_array = new ArrayString();
(*new_array) = m_array;
return new_array;
}
};
template<typename T> struct Stack : public Array<T>
{
Stack() : Array<T>()

2
rpcs3/Emu/Cell/MFC.cpp Normal file
View file

@ -0,0 +1,2 @@
#include "stdafx.h"
#include "MFC.h"

252
rpcs3/Emu/Cell/MFC.h Normal file
View file

@ -0,0 +1,252 @@
#pragma once
#include <atomic>
enum
{
MFC_PUT_CMD = 0x20,
MFC_GET_CMD = 0x40,
MFC_MASK_CMD = 0xffff,
};
enum
{
MFC_SPU_TO_PPU_MAILBOX_STATUS_MASK = 0x000000FF,
MFC_SPU_TO_PPU_MAILBOX_STATUS_SHIFT = 0x0,
MFC_PPU_TO_SPU_MAILBOX_STATUS_MASK = 0x0000FF00,
MFC_PPU_TO_SPU_MAILBOX_STATUS_SHIFT = 0x8,
MFC_PPU_TO_SPU_MAILBOX_MAX = 0x4,
MFC_SPU_TO_PPU_INT_MAILBOX_STATUS_MASK = 0x00FF0000,
MFC_SPU_TO_PPU_INT_MAILBOX_STATUS_SHIFT = 0x10,
};
enum
{
MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL = 0x00,
MFC_PPU_DMA_CMD_SEQUENCE_ERROR = 0x01,
MFC_PPU_DMA_QUEUE_FULL = 0x02,
};
enum
{
MFC_PPU_MAX_QUEUE_SPACE = 0x08,
MFC_SPU_MAX_QUEUE_SPACE = 0x10,
};
struct DMAC_Queue
{
bool is_valid;
u64 ea;
u32 lsa;
u16 size;
u32 op;
u8 tag;
u8 rt;
u16 list_addr;
u16 list_size;
u32 dep_state;
u32 cmd;
u32 dep_type;
};
struct DMAC_Proxy
{
u64 ea;
u32 lsa;
u16 size;
u32 op;
u8 tag;
u8 rt;
u16 list_addr;
u16 list_size;
u32 dep_state;
u32 cmd;
u32 dep_type;
};
template<size_t _max_count>
class SPUReg
{
u64 m_addr;
u32 m_pos;
public:
static const size_t max_count = _max_count;
static const size_t size = max_count * 4;
SPUReg()
{
Init();
}
void Init()
{
m_pos = 0;
}
void SetAddr(u64 addr)
{
m_addr = addr;
}
u64 GetAddr() const
{
return m_addr;
}
__forceinline bool Pop(u32& res)
{
if(!m_pos) return false;
res = Memory.Read32(m_addr + m_pos--);
return true;
}
__forceinline bool Push(u32 value)
{
if(m_pos >= max_count) return false;
Memory.Write32(m_addr + m_pos++, value);
return true;
}
u32 GetCount() const
{
return m_pos;
}
u32 GetFreeCount() const
{
return max_count - m_pos;
}
void SetValue(u32 value)
{
Memory.Write32(m_addr, value);
}
u32 GetValue() const
{
return Memory.Read32(m_addr);
}
};
struct DMAC
{
DMAC_Queue queue[MFC_SPU_MAX_QUEUE_SPACE];
DMAC_Proxy proxy[MFC_PPU_MAX_QUEUE_SPACE];
u64 ls_offset;
std::atomic<u32> queue_pos;
std::atomic<u32> proxy_pos;
u32 Cmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size)
{
if(!Memory.IsGoodAddr(ls_offset + lsa, size) || !Memory.IsGoodAddr(ea, size))
{
return MFC_PPU_DMA_CMD_SEQUENCE_ERROR;
}
if(proxy_pos >= MFC_PPU_MAX_QUEUE_SPACE)
{
return MFC_PPU_DMA_QUEUE_FULL;
}
DMAC_Proxy& p = proxy[proxy_pos++];
p.cmd = cmd;
p.tag = tag;
p.lsa = lsa;
p.ea = ea;
p.size = size;
return MFC_PPU_DMA_CMD_ENQUEUE_SUCCESSFUL;
}
void DoCmd()
{
if(proxy_pos)
{
DMAC_Proxy p = proxy[0];
memcpy(proxy, proxy + 1, proxy_pos--);
switch(p.cmd)
{
case MFC_PUT_CMD:
memcpy(Memory + ls_offset + p.lsa, Memory + p.ea, p.size);
break;
case MFC_GET_CMD:
memcpy(Memory + p.ea, Memory + ls_offset + p.lsa, p.size);
break;
default:
ConLog.Error("Unknown DMA cmd.");
break;
}
}
}
};
struct MFC
{
SPUReg<1> MFC_LSA;
SPUReg<1> MFC_EAH;
SPUReg<1> MFC_EAL;
SPUReg<1> MFC_Size_Tag;
SPUReg<1> MFC_CMDStatus;
SPUReg<1> MFC_QStatus;
SPUReg<1> Prxy_QueryType;
SPUReg<1> Prxy_QueryMask;
SPUReg<1> Prxy_TagStatus;
SPUReg<1> SPU_Out_MBox;
SPUReg<4> SPU_In_MBox;
SPUReg<1> SPU_MBox_Status;
SPUReg<1> SPU_RunCntl;
SPUReg<1> SPU_Status;
SPUReg<1> SPU_NPC;
SPUReg<1> SPU_RdSigNotify1;
SPUReg<1> SPU_RdSigNotify2;
DMAC dmac;
void Handle()
{
u32 cmd = MFC_CMDStatus.GetValue();
if(cmd)
{
u16 op = cmd & MFC_MASK_CMD;
switch(op)
{
case MFC_PUT_CMD:
case MFC_GET_CMD:
{
u32 lsa = MFC_LSA.GetValue();
u64 ea = (u64)MFC_EAL.GetValue() | ((u64)MFC_EAH.GetValue() << 32);
u32 size_tag = MFC_Size_Tag.GetValue();
u16 tag = (u16)size_tag;
u16 size = size_tag >> 16;
ConLog.Warning("RawSPU DMA %s:", op == MFC_PUT_CMD ? "PUT" : "GET");
ConLog.Warning("*** lsa = 0x%x", lsa);
ConLog.Warning("*** ea = 0x%llx", ea);
ConLog.Warning("*** tag = 0x%x", tag);
ConLog.Warning("*** size = 0x%x", size);
ConLog.SkipLn();
MFC_CMDStatus.SetValue(dmac.Cmd(cmd, tag, lsa, ea, size));
}
break;
default:
ConLog.Error("Unknown MFC cmd.");
break;
}
}
if(Prxy_QueryType.GetValue() == 2)
{
Prxy_QueryType.SetValue(0);
u32 mask = Prxy_QueryMask.GetValue();
//
MFC_QStatus.SetValue(mask);
}
}
};

View file

@ -72,7 +72,7 @@ SectionInfo::SectionInfo(const wxString& _name) : name(_name)
shdr.sh_offset = section_offs;
shdr.sh_name = section_name_offs;
section_name_offs += name.Len() + 1;
section_name_offs += name.GetCount() + 1;
}
void SectionInfo::SetDataSize(u32 size, u32 align)
@ -107,11 +107,11 @@ SectionInfo::~SectionInfo()
for(u32 i=section_num + 1; i<sections_list.GetCount(); ++i)
{
sections_list[i].shdr.sh_offset -= code.GetCount();
sections_list[i].shdr.sh_name -= name.Len();
sections_list[i].shdr.sh_name -= name.GetCount();
}
section_offs -= code.GetCount();
section_name_offs -= name.Len();
section_name_offs -= name.GetCount();
}
CompilePPUProgram::CompilePPUProgram(
@ -302,7 +302,7 @@ int CompilePPUProgram::GetArg(wxString& result, bool func)
case 'r': result = result(0, pos) + '\r' + result(pos+2, result.Len()-(pos+2)); break;
case 't': result = result(0, pos) + '\t' + result(pos+2, result.Len()-(pos+2)); break;
}
pos++;
}
}
@ -354,7 +354,7 @@ bool CompilePPUProgram::CheckEnd(bool show_err)
void CompilePPUProgram::DetectArgInfo(Arg& arg)
{
const wxString str = arg.string;
const wxString str = arg.string.GetPtr();
if(str.Len() <= 0)
{
@ -372,7 +372,7 @@ void CompilePPUProgram::DetectArgInfo(Arg& arg)
{
for(u32 i=0; i<m_branches.GetCount(); ++i)
{
if(m_branches[i].m_name.Cmp(str) != 0) continue;
if(str.Cmp(m_branches[i].m_name.GetPtr()) != 0) continue;
arg.type = ARG_BRANCH;
arg.value = GetBranchValue(str);
@ -532,7 +532,7 @@ u32 CompilePPUProgram::GetBranchValue(const wxString& branch)
{
for(u32 i=0; i<m_branches.GetCount(); ++i)
{
if(m_branches[i].m_name.Cmp(branch) != 0) continue;
if(branch.Cmp(m_branches[i].m_name.GetPtr()) != 0) continue;
if(m_branches[i].m_pos >= 0) return m_text_addr + m_branches[i].m_pos * 4;
return m_branches[i].m_addr;
@ -664,7 +664,7 @@ CompilePPUProgram::Branch& CompilePPUProgram::GetBranch(const wxString& name)
{
for(u32 i=0; i<m_branches.GetCount(); ++i)
{
if(m_branches[i].m_name.Cmp(name) != 0) continue;
if(name.Cmp(m_branches[i].m_name.GetPtr()) != 0) continue;
return m_branches[i];
}
@ -684,7 +684,7 @@ void CompilePPUProgram::SetSp(const wxString& name, u32 addr, bool create)
for(u32 i=0; i<m_branches.GetCount(); ++i)
{
if(m_branches[i].m_name.Cmp(name) != 0) continue;
if(name.Cmp(m_branches[i].m_name.GetPtr()) != 0) continue;
m_branches[i].m_addr = addr;
}
}
@ -803,7 +803,7 @@ void CompilePPUProgram::LoadSp(const wxString& op, Elf64_Shdr& s_opd)
for(u32 i=0; i<m_sp_string.GetCount(); ++i)
{
if(m_sp_string[i].m_data.Cmp(src1) != 0) continue;
if(src1.Cmp(m_sp_string[i].m_data.GetPtr()) != 0) continue;
*dst_branch = Branch(dst, -1, m_sp_string[i].m_addr);
founded = true;
}
@ -827,7 +827,7 @@ void CompilePPUProgram::LoadSp(const wxString& op, Elf64_Shdr& s_opd)
{
if(m_sp_string[i].m_addr == a_src1.value)
{
*dst_branch = Branch(dst, -1, m_sp_string[i].m_data.Len());
*dst_branch = Branch(dst, -1, m_sp_string[i].m_data.GetCount());
break;
}
}
@ -1335,7 +1335,7 @@ void CompilePPUProgram::Compile()
for(u32 i=0; i<m_branches.GetCount(); ++i)
{
if(name.Cmp(m_branches[i].m_name) != 0) continue;
if(name.Cmp(m_branches[i].m_name.GetPtr()) != 0) continue;
WriteError(wxString::Format("'%s' already declared", name));
m_error = true;
break;
@ -1365,7 +1365,7 @@ void CompilePPUProgram::Compile()
bool has_entry = false;
for(u32 i=0; i<m_branches.GetCount(); ++i)
{
if(m_branches[i].m_name.Cmp("entry") != 0) continue;
if(wxString("entry").Cmp(m_branches[i].m_name.GetPtr()) != 0) continue;
has_entry = true;
break;
@ -1510,7 +1510,7 @@ void CompilePPUProgram::Compile()
u32 entry_point = s_text.sh_addr;
for(u32 i=0; i<m_branches.GetCount(); ++i)
{
if(m_branches[i].m_name.Cmp("entry") == 0)
if(wxString("entry").Cmp(m_branches[i].m_name.GetPtr()) == 0)
{
entry_point += m_branches[i].m_pos * 4;
break;
@ -1561,7 +1561,7 @@ void CompilePPUProgram::Compile()
for(u32 i=0; i<m_sp_string.GetCount(); ++i)
{
f.Seek(s_opd.sh_offset + (m_sp_string[i].m_addr - s_opd.sh_addr));
f.Write(&m_sp_string[i].m_data[0], m_sp_string[i].m_data.Len() + 1);
f.Write(&m_sp_string[i].m_data[0], m_sp_string[i].m_data.GetCount() + 1);
}
f.Seek(s_sceStub_text.sh_offset);
@ -1576,16 +1576,6 @@ void CompilePPUProgram::Compile()
Write32(f, LWZ(2, 12, 4));
Write32(f, MTSPR(0x009, 0));
Write32(f, BCCTR(20, 0, 0, 0));
/*
Write32(f, ToOpcode(ADDI) | ToRD(12)); //li r12,0
Write32(f, ToOpcode(ORIS) | ToRD(12) | ToRA(12) | ToIMM16(addr >> 16)); //oris r12,r12,addr>>16
Write32(f, ToOpcode(LWZ) | ToRD(12) | ToRA(12) | ToIMM16(addr)); //lwz r12,addr&0xffff(r12)
Write32(f, 0xf8410028); //std r2,40(r1)
Write32(f, ToOpcode(LWZ) | ToRD(0) | ToRA(12) | ToIMM16(0)); //lwz r0,0(r12)
Write32(f, ToOpcode(LWZ) | ToRD(2) | ToRA(12) | ToIMM16(4)); //lwz r2,4(r12)
Write32(f, 0x7c0903a6); //mtctr r0
Write32(f, 0x4e800420); //bctr
*/
}
f.Seek(s_lib_stub_top.sh_offset);

View file

@ -19,7 +19,7 @@ enum ArgType
struct Arg
{
wxString string;
ArrayString string;
u32 value;
ArgType type;
@ -34,7 +34,7 @@ struct Arg
struct SectionInfo
{
Elf64_Shdr shdr;
wxString name;
ArrayString name;
Array<u8> code;
u32 section_num;
@ -62,7 +62,7 @@ class CompilePPUProgram
{
struct Branch
{
wxString m_name;
ArrayString m_name;
s32 m_pos;
s32 m_id;
s32 m_addr;
@ -101,7 +101,7 @@ class CompilePPUProgram
struct SpData
{
wxString m_data;
ArrayString m_data;
u32 m_addr;
SpData(const wxString& data, u32 addr)

View file

@ -20,29 +20,32 @@ void RawSPUThread::InitRegs()
u32 num = Emu.GetCPU().GetThreadNumById(GetType(), GetId());
m_offset = RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * num + RAW_SPU_LS_OFFSET;
MFC_LSA.SetAddr(GetRawSPURegAddrByNum(num, MFC_LSA_offs));
MFC_EAH.SetAddr(GetRawSPURegAddrByNum(num, MFC_EAH_offs));
MFC_EAL.SetAddr(GetRawSPURegAddrByNum(num, MFC_EAL_offs));
MFC_Size_Tag.SetAddr(GetRawSPURegAddrByNum(num, MFC_Size_Tag_offs));
MFC_CMDStatus.SetAddr(GetRawSPURegAddrByNum(num, MFC_CMDStatus_offs));
MFC_QStatus.SetAddr(GetRawSPURegAddrByNum(num, MFC_QStatus_offs));
Prxy_QueryType.SetAddr(GetRawSPURegAddrByNum(num, Prxy_QueryType_offs));
Prxy_QueryMask.SetAddr(GetRawSPURegAddrByNum(num, Prxy_QueryMask_offs));
Prxy_TagStatus.SetAddr(GetRawSPURegAddrByNum(num, Prxy_TagStatus_offs));
SPU_Out_MBox.SetAddr(GetRawSPURegAddrByNum(num, SPU_Out_MBox_offs));
SPU_In_MBox.SetAddr(GetRawSPURegAddrByNum(num, SPU_In_MBox_offs));
SPU_MBox_Status.SetAddr(GetRawSPURegAddrByNum(num, SPU_MBox_Status_offs));
SPU_RunCntl.SetAddr(GetRawSPURegAddrByNum(num, SPU_RunCntl_offs));
SPU_Status.SetAddr(GetRawSPURegAddrByNum(num, SPU_Status_offs));
SPU_NPC.SetAddr(GetRawSPURegAddrByNum(num, SPU_NPC_offs));
SPU_RdSigNotify1.SetAddr(GetRawSPURegAddrByNum(num, SPU_RdSigNotify1_offs));
SPU_RdSigNotify2.SetAddr(GetRawSPURegAddrByNum(num, SPU_RdSigNotify2_offs));
mfc.dmac.ls_offset = m_offset;
mfc.dmac.proxy_pos = 0;
mfc.dmac.queue_pos = 0;
mfc.MFC_LSA.SetAddr(GetRawSPURegAddrByNum(num, MFC_LSA_offs));
mfc.MFC_EAH.SetAddr(GetRawSPURegAddrByNum(num, MFC_EAH_offs));
mfc.MFC_EAL.SetAddr(GetRawSPURegAddrByNum(num, MFC_EAL_offs));
mfc.MFC_Size_Tag.SetAddr(GetRawSPURegAddrByNum(num, MFC_Size_Tag_offs));
mfc.MFC_CMDStatus.SetAddr(GetRawSPURegAddrByNum(num, MFC_CMDStatus_offs));
mfc.MFC_QStatus.SetAddr(GetRawSPURegAddrByNum(num, MFC_QStatus_offs));
mfc.Prxy_QueryType.SetAddr(GetRawSPURegAddrByNum(num, Prxy_QueryType_offs));
mfc.Prxy_QueryMask.SetAddr(GetRawSPURegAddrByNum(num, Prxy_QueryMask_offs));
mfc.Prxy_TagStatus.SetAddr(GetRawSPURegAddrByNum(num, Prxy_TagStatus_offs));
mfc.SPU_Out_MBox.SetAddr(GetRawSPURegAddrByNum(num, SPU_Out_MBox_offs));
mfc.SPU_In_MBox.SetAddr(GetRawSPURegAddrByNum(num, SPU_In_MBox_offs));
mfc.SPU_MBox_Status.SetAddr(GetRawSPURegAddrByNum(num, SPU_MBox_Status_offs));
mfc.SPU_RunCntl.SetAddr(GetRawSPURegAddrByNum(num, SPU_RunCntl_offs));
mfc.SPU_Status.SetAddr(GetRawSPURegAddrByNum(num, SPU_Status_offs));
mfc.SPU_NPC.SetAddr(GetRawSPURegAddrByNum(num, SPU_NPC_offs));
mfc.SPU_RdSigNotify1.SetAddr(GetRawSPURegAddrByNum(num, SPU_RdSigNotify1_offs));
mfc.SPU_RdSigNotify2.SetAddr(GetRawSPURegAddrByNum(num, SPU_RdSigNotify2_offs));
SPU_RunCntl.SetValue(SPU_RUNCNTL_STOP);
SPU_Status.SetValue(SPU_STATUS_RUNNING);
Prxy_QueryType.SetValue(0);
MFC_CMDStatus.SetValue(0);
PC = SPU_NPC.GetValue();
mfc.SPU_RunCntl.SetValue(SPU_RUNCNTL_STOP);
mfc.SPU_Status.SetValue(SPU_STATUS_RUNNING);
mfc.Prxy_QueryType.SetValue(0);
mfc.MFC_CMDStatus.SetValue(0);
PC = mfc.SPU_NPC.GetValue();
}
void RawSPUThread::Task()
@ -78,39 +81,16 @@ void RawSPUThread::Task()
continue;
}
if(MFC_CMDStatus.GetValue() == 0x40)
{
MFC_CMDStatus.SetValue(0);
u32 lsa = MFC_LSA.GetValue();
u64 ea = (u64)MFC_EAL.GetValue() | ((u64)MFC_EAH.GetValue() << 32);
u32 size_tag = MFC_Size_Tag.GetValue();
u16 tag = (u16)size_tag;
u16 size = size_tag >> 16;
ConLog.Warning("RawSPU DMA GET:");
ConLog.Warning("*** lsa = 0x%x", lsa);
ConLog.Warning("*** ea = 0x%llx", ea);
ConLog.Warning("*** tag = 0x%x", tag);
ConLog.Warning("*** size = 0x%x", size);
ConLog.SkipLn();
memcpy(Memory + m_offset + lsa, Memory + ea, size);
}
mfc.Handle();
if(Prxy_QueryType.GetValue() == 2)
{
Prxy_QueryType.SetValue(0);
u32 mask = Prxy_QueryMask.GetValue();
//
MFC_QStatus.SetValue(mask);
}
if(SPU_RunCntl.GetValue() != SPU_RUNCNTL_RUNNABLE)
if(mfc.SPU_RunCntl.GetValue() != SPU_RUNCNTL_RUNNABLE)
{
if(!is_last_paused)
{
if(is_last_paused = SPU_RunCntl.GetValue() != SPU_RUNCNTL_RUNNABLE)
if(is_last_paused = mfc.SPU_RunCntl.GetValue() != SPU_RUNCNTL_RUNNABLE)
{
SPU_NPC.SetValue(PC);
SPU_Status.SetValue(SPU_STATUS_WAITING_FOR_CHANNEL);
mfc.SPU_NPC.SetValue(PC);
mfc.SPU_Status.SetValue(SPU_STATUS_WAITING_FOR_CHANNEL);
}
}
@ -121,8 +101,8 @@ void RawSPUThread::Task()
if(is_last_paused)
{
is_last_paused = false;
PC = SPU_NPC.GetValue();
SPU_Status.SetValue(SPU_STATUS_RUNNING);
PC = mfc.SPU_NPC.GetValue();
mfc.SPU_Status.SetValue(SPU_STATUS_RUNNING);
}
DoCode(Memory.Read32(m_offset + PC));

View file

@ -49,12 +49,17 @@ public:
RawSPUThread(PPCThreadType type = PPC_THREAD_RAW_SPU);
~RawSPUThread();
virtual wxString RegsToString()
{
wxString ret = PPCThread::RegsToString();
for(uint i=0; i<128; ++i) ret += wxString::Format("GPR[%d] = 0x%s\n", i, GPR[i].ToString());
return ret;
}
virtual u8 ReadLS8 (const u32 lsa) const { return Memory.Read8 (lsa + (m_offset & 0x3fffc)); }
virtual u16 ReadLS16 (const u32 lsa) const { return Memory.Read16 (lsa + m_offset); }
virtual u32 ReadLS32 (const u32 lsa) const { return Memory.Read32 (lsa + m_offset); }
virtual u64 ReadLS64 (const u32 lsa) const { return Memory.Read64 (lsa + m_offset); }
virtual u128 ReadLS128(const u32 lsa) const { return Memory.Read128(lsa + m_offset); }
virtual void WriteLS8 (const u32 lsa, const u8& data) const { Memory.Write8 (lsa + m_offset, data); }
virtual void WriteLS16 (const u32 lsa, const u16& data) const { Memory.Write16 (lsa + m_offset, data); }
virtual void WriteLS32 (const u32 lsa, const u32& data) const { Memory.Write32 (lsa + m_offset, data); }
virtual void WriteLS64 (const u32 lsa, const u64& data) const { Memory.Write64 (lsa + m_offset, data); }
virtual void WriteLS128(const u32 lsa, const u128& data) const { Memory.Write128(lsa + m_offset, data); }
public:
virtual void InitRegs();

View file

@ -1166,7 +1166,7 @@ private:
(~CPU.GPR[rc]._u32[i] & CPU.GPR[ra]._u32[i]);
}
}
void SHUFB(u32 rc, u32 ra, u32 rb, u32 rt)
void SHUFB(u32 rt, u32 ra, u32 rb, u32 rc)
{
ConLog.Warning("SHUFB");
}
@ -1175,7 +1175,7 @@ private:
for (int w = 0; w < 4; w++)
CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2 + 1] * CPU.GPR[rb]._i16[w*2 + 1] + CPU.GPR[rc]._i32[w];
}
void FNMS(u32 rc, u32 ra, u32 rb, u32 rt)
void FNMS(u32 rt, u32 ra, u32 rb, u32 rc)
{
UNIMPLEMENTED();
}

View file

@ -1,6 +1,7 @@
#pragma once
#include "PPCThread.h"
#include "Emu/event.h"
#include "MFC.h"
static const wxString spu_reg_name[128] =
{
@ -127,72 +128,7 @@ class SPUThread : public PPCThread
{
public:
SPU_GPR_hdr GPR[128]; //General-Purpose Register
template<size_t _max_count>
class SPUReg
{
u64 m_addr;
u32 m_pos;
public:
static const size_t max_count = _max_count;
static const size_t size = max_count * 4;
SPUReg()
{
Init();
}
void Init()
{
m_pos = 0;
}
void SetAddr(u64 addr)
{
m_addr = addr;
}
u64 GetAddr() const
{
return m_addr;
}
__forceinline bool Pop(u32& res)
{
if(!m_pos) return false;
res = Memory.Read32(m_addr + m_pos--);
return true;
}
__forceinline bool Push(u32 value)
{
if(m_pos >= max_count) return false;
Memory.Write32(m_addr + m_pos++, value);
return true;
}
u32 GetCount() const
{
return m_pos;
}
u32 GetFreeCount() const
{
return max_count - m_pos;
}
void SetValue(u32 value)
{
Memory.Write32(m_addr, value);
}
u32 GetValue() const
{
return Memory.Read32(m_addr);
}
};
/*
SPUReg<1> MFC_LSA;
SPUReg<1> MFC_EAH;
SPUReg<1> MFC_EAL;
@ -210,9 +146,10 @@ public:
SPUReg<1> SPU_NPC;
SPUReg<1> SPU_RdSigNotify1;
SPUReg<1> SPU_RdSigNotify2;
*/
SizedStack<u32, 1> SPU_OutIntr_Mbox;
u32 LSA;
MFC mfc;
union
{
@ -225,10 +162,10 @@ public:
switch(ch)
{
case SPU_WrOutMbox:
return SPU_Out_MBox.GetFreeCount();
return mfc.SPU_Out_MBox.GetFreeCount();
case SPU_RdInMbox:
return SPU_In_MBox.GetCount();
return mfc.SPU_In_MBox.GetCount();
case SPU_WrOutIntrMbox:
return 0;//return SPU_OutIntr_Mbox.GetFreeCount();
@ -257,11 +194,11 @@ public:
case SPU_WrOutMbox:
ConLog.Warning("SPU_WrOutMbox = 0x%x", v);
if(!SPU_Out_MBox.Push(v))
if(!mfc.SPU_Out_MBox.Push(v))
{
ConLog.Warning("Not enought free rooms.");
}
SPU_Status.SetValue((SPU_Status.GetValue() & ~0xff) | 1);
mfc.SPU_Status.SetValue((mfc.SPU_Status.GetValue() & ~0xff) | 1);
break;
default:
@ -278,8 +215,8 @@ public:
switch(ch)
{
case SPU_RdInMbox:
if(!SPU_In_MBox.Pop(v)) v = 0;
SPU_Status.SetValue((SPU_Status.GetValue() & ~0xff00) | (SPU_In_MBox.GetCount() << 8));
if(!mfc.SPU_In_MBox.Pop(v)) v = 0;
mfc.SPU_Status.SetValue((mfc.SPU_Status.GetValue() & ~0xff00) | (mfc.SPU_In_MBox.GetCount() << 8));
break;
default:
@ -288,18 +225,18 @@ public:
}
}
bool IsGoodLSA(const u32 lsa) const { return Memory.IsGoodAddr(lsa); }
u8 ReadLS8 (const u32 lsa) const { return Memory.Read8 (lsa + (m_offset & 0x3fffc)); }
u16 ReadLS16 (const u32 lsa) const { return Memory.Read16 (lsa + m_offset); }
u32 ReadLS32 (const u32 lsa) const { return Memory.Read32 (lsa + m_offset); }
u64 ReadLS64 (const u32 lsa) const { return Memory.Read64 (lsa + m_offset); }
u128 ReadLS128(const u32 lsa) const { return Memory.Read128(lsa + m_offset); }
bool IsGoodLSA(const u32 lsa) const { return Memory.IsGoodAddr(lsa + m_offset); }
virtual u8 ReadLS8 (const u32 lsa) const { return Memory.Read8 (lsa + (m_offset & 0x3fffc)); }
virtual u16 ReadLS16 (const u32 lsa) const { return Memory.Read16 (lsa + m_offset); }
virtual u32 ReadLS32 (const u32 lsa) const { return Memory.Read32 (lsa + m_offset); }
virtual u64 ReadLS64 (const u32 lsa) const { return Memory.Read64 (lsa + m_offset); }
virtual u128 ReadLS128(const u32 lsa) const { return Memory.Read128(lsa + m_offset); }
void WriteLS8 (const u32 lsa, const u8& data) const { Memory.Write8 (lsa + m_offset, data); }
void WriteLS16 (const u32 lsa, const u16& data) const { Memory.Write16 (lsa + m_offset, data); }
void WriteLS32 (const u32 lsa, const u32& data) const { Memory.Write32 (lsa + m_offset, data); }
void WriteLS64 (const u32 lsa, const u64& data) const { Memory.Write64 (lsa + m_offset, data); }
void WriteLS128(const u32 lsa, const u128& data) const { Memory.Write128(lsa + m_offset, data); }
virtual void WriteLS8 (const u32 lsa, const u8& data) const { Memory.Write8 (lsa + m_offset, data); }
virtual void WriteLS16 (const u32 lsa, const u16& data) const { Memory.Write16 (lsa + m_offset, data); }
virtual void WriteLS32 (const u32 lsa, const u32& data) const { Memory.Write32 (lsa + m_offset, data); }
virtual void WriteLS64 (const u32 lsa, const u64& data) const { Memory.Write64 (lsa + m_offset, data); }
virtual void WriteLS128(const u32 lsa, const u128& data) const { Memory.Write128(lsa + m_offset, data); }
public:
SPUThread(PPCThreadType type = PPC_THREAD_SPU);

View file

@ -1,5 +1,6 @@
#include "stdafx.h"
#include "VFS.h"
#include "Emu\HDD\HDD.h"
int sort_devices(const void* _a, const void* _b)
{
@ -31,13 +32,23 @@ void VFS::UnMount(const wxString& ps3_path)
{
if(!m_devices[i].GetPs3Path().Cmp(ps3_path))
{
m_devices.RemoveAt(i);
delete &m_devices[i];
m_devices.RemoveFAt(i);
return;
}
}
}
void VFS::UnMountAll()
{
for(u32 i=0; i<m_devices.GetCount(); ++i)
{
delete &m_devices[i];
m_devices.RemoveFAt(i);
}
}
vfsStream* VFS::Open(const wxString& ps3_path, vfsOpenMode mode)
{
vfsDevice* stream = nullptr;
@ -89,3 +100,106 @@ vfsDevice* VFS::GetDevice(const wxString& ps3_path, wxString& path)
path = vfsDevice::GetWinPath(m_devices[max_i].GetLocalPath(), ps3_path(max_eq, ps3_path.Len() - max_eq));
return &m_devices[max_i];
}
void VFS::Init(const wxString& path)
{
Array<VFSManagerEntry> entries;
SaveLoadDevices(entries, true);
for(uint i=0; i<entries.GetCount(); ++i)
{
vfsDevice* dev;
switch(entries[i].device)
{
case vfsDevice_LocalFile:
dev = new vfsLocalFile();
break;
case vfsDevice_HDD:
dev = new vfsHDD(entries[i].device_path.GetPtr());
break;
default:
continue;
}
wxString mpath = entries[i].path.GetPtr();
mpath.Replace("$(EmulatorDir)", wxGetCwd());
mpath.Replace("$(GameDir)", vfsDevice::GetRoot(path));
Mount(entries[i].mount.GetPtr(), mpath, dev);
}
}
void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
{
IniEntry<int> entries_count;
entries_count.Init("count", "VFSManager");
int count;
if(is_load)
{
count = entries_count.LoadValue(count);
if(!count)
{
int idx;
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(EmulatorDir)\\dev_hdd0\\";
res[idx].mount = "/dev_hdd0/";
res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(GameDir)";
res[idx].mount = "";
res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(GameDir)";
res[idx].mount = "/";
res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(GameDir)";
res[idx].mount = "/app_home/";
res[idx].device = vfsDevice_LocalFile;
return;
}
res.SetCount(count);
}
else
{
count = res.GetCount();
entries_count.SaveValue(res.GetCount());
}
for(int i=0; i<count; ++i)
{
IniEntry<wxString> entry_path;
IniEntry<wxString> entry_device_path;
IniEntry<wxString> entry_mount;
IniEntry<int> entry_device;
entry_path.Init(wxString::Format("path[%d]", i), "VFSManager");
entry_device_path.Init(wxString::Format("device_path[%d]", i), "VFSManager");
entry_mount.Init(wxString::Format("mount[%d]", i), "VFSManager");
entry_device.Init(wxString::Format("device[%d]", i), "VFSManager");
if(is_load)
{
new (res + i) VFSManagerEntry();
res[i].path = entry_path.LoadValue(wxEmptyString);
res[i].device_path = entry_device_path.LoadValue(wxEmptyString);
res[i].mount = entry_mount.LoadValue(wxEmptyString);
res[i].device = (vfsDeviceType)entry_device.LoadValue(vfsDevice_LocalFile);
}
else
{
entry_path.SaveValue(res[i].path.GetPtr());
entry_device_path.SaveValue(res[i].device_path.GetPtr());
entry_mount.SaveValue(res[i].mount.GetPtr());
entry_device.SaveValue(res[i].device);
}
}
}

View file

@ -1,15 +1,42 @@
#pragma once
#include "vfsDevice.h"
enum vfsDeviceType
{
vfsDevice_LocalFile,
vfsDevice_HDD,
};
static const char* vfsDeviceTypeNames[] =
{
"Local",
"HDD",
};
struct VFSManagerEntry
{
ArrayString device_path;
ArrayString path;
ArrayString mount;
vfsDeviceType device;
VFSManagerEntry() : device(vfsDevice_LocalFile)
{
}
};
struct VFS
{
ArrayF<vfsDevice> m_devices;
void Mount(const wxString& ps3_path, const wxString& local_path, vfsDevice* device);
void UnMount(const wxString& ps3_path);
void UnMountAll();
vfsStream* Open(const wxString& ps3_path, vfsOpenMode mode);
void Create(const wxString& ps3_path);
void Close(vfsStream*& device);
vfsDevice* GetDevice(const wxString& ps3_path, wxString& path);
void Init(const wxString& path);
void SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load);
};

View file

@ -198,4 +198,19 @@ wxString vfsDevice::GetPs3Path(const wxString& l, const wxString& r)
if(r.IsEmpty()) return GetPs3Path(l);
return GetPs3Path(l + '/' + r, false);
}
void vfsDevice::Lock() const
{
m_mtx_lock.lock();
}
void vfsDevice::Unlock() const
{
m_mtx_lock.unlock();
}
bool vfsDevice::TryLock() const
{
return m_mtx_lock.try_lock();
}

View file

@ -1,19 +1,23 @@
#pragma once
#include "vfsStream.h"
#include <mutex>
enum vfsOpenMode
{
vfsRead,
vfsWrite,
vfsReadWrite,
vfsWriteExcl,
vfsWriteAppend,
vfsRead = 0x1,
vfsWrite = 0x2,
vfsExcl = 0x4,
vfsAppend = 0x8,
vfsReadWrite = vfsRead | vfsWrite,
vfsWriteExcl = vfsWrite | vfsExcl,
vfsWriteAppend = vfsWrite | vfsAppend,
};
class vfsDevice : public vfsStream
{
wxString m_ps3_path;
wxString m_local_path;
mutable std::mutex m_mtx_lock;
public:
vfsDevice(const wxString& ps3_path, const wxString& local_path);
@ -36,4 +40,24 @@ public:
static wxString GetWinPath(const wxString& l, const wxString& r);
static wxString GetPs3Path(const wxString& p, bool is_dir = true);
static wxString GetPs3Path(const wxString& l, const wxString& r);
void Lock() const;
void Unlock() const;
bool TryLock() const;
};
class vfsDeviceLocker
{
vfsDevice& m_device;
public:
vfsDeviceLocker(vfsDevice& device) : m_device(device)
{
m_device.Lock();
}
~vfsDeviceLocker()
{
m_device.Unlock();
}
};

View file

@ -40,4 +40,4 @@ wxString vfsFileBase::GetPath() const
vfsOpenMode vfsFileBase::GetOpenMode() const
{
return m_mode;
}
}

View file

@ -21,4 +21,4 @@ public:
*/
wxString GetPath() const;
vfsOpenMode GetOpenMode() const;
};
};

View file

@ -92,4 +92,4 @@ u64 vfsLocalFile::Tell() const
bool vfsLocalFile::IsOpened() const
{
return m_file.IsOpened() && vfsFileBase::IsOpened();
}
}

View file

@ -1375,5 +1375,5 @@ void GLGSRender::Init()
void GLGSRender::CloseOpenGL()
{
Reset();
//Reset();
}

3
rpcs3/Emu/HDD/HDD.cpp Normal file
View file

@ -0,0 +1,3 @@
#include "stdafx.h"
#include "HDD.h"

864
rpcs3/Emu/HDD/HDD.h Normal file
View file

@ -0,0 +1,864 @@
#pragma once
#include "Emu/FS/vfsDevice.h"
static const u64 g_hdd_magic = *(u64*)"PS3eHDD\0";
static const u16 g_hdd_version = 0x0001;
struct vfsHDD_Block
{
struct
{
u64 is_used : 1;
u64 next_block : 63;
};
} static const g_null_block = {0}, g_used_block = {1};
struct vfsHDD_Hdr : public vfsHDD_Block
{
u64 magic;
u16 version;
u64 block_count;
u32 block_size;
};
enum vfsHDD_EntryType : u8
{
vfsHDD_Entry_Dir = 0,
vfsHDD_Entry_File = 1,
vfsHDD_Entry_Link = 2,
};
struct vfsHDD_Entry : public vfsHDD_Block
{
u64 data_block;
vfsOpenMode access;
vfsHDD_EntryType type;
u64 size;
u64 ctime;
u64 mtime;
u64 atime;
};
class vfsHDDManager
{
public:
static void CreateBlock(vfsHDD_Block& block)
{
block.is_used = true;
block.next_block = 0;
}
static void CreateEntry(vfsHDD_Entry& entry)
{
memset(&entry, 0, sizeof(vfsHDD_Entry));
u64 ctime = time(nullptr);
entry.atime = ctime;
entry.ctime = ctime;
entry.mtime = ctime;
entry.access = vfsReadWrite;
CreateBlock(entry);
}
static void CreateHDD(const wxString& path, u64 size, u64 block_size)
{
wxFile f(path, wxFile::write);
static const u64 cur_dir_block = 1;
vfsHDD_Hdr hdr;
CreateBlock(hdr);
hdr.next_block = cur_dir_block;
hdr.magic = g_hdd_magic;
hdr.version = g_hdd_version;
hdr.block_count = (size + block_size) / block_size;
hdr.block_size = block_size;
f.Write(&hdr, sizeof(vfsHDD_Hdr));
{
vfsHDD_Entry entry;
CreateEntry(entry);
entry.type = vfsHDD_Entry_Dir;
entry.data_block = hdr.next_block;
entry.next_block = 0;
f.Seek(cur_dir_block * hdr.block_size);
f.Write(&entry, sizeof(vfsHDD_Entry));
f.Write(".");
}
u8 null = 0;
f.Seek(hdr.block_count * hdr.block_size - sizeof(null));
f.Write(&null, sizeof(null));
}
void Format()
{
}
void AppendEntry(vfsHDD_Entry entry)
{
}
};
class vfsHDDFile
{
u64 m_info_block;
vfsHDD_Entry m_info;
const vfsHDD_Hdr& m_hdd_info;
vfsLocalFile& m_hdd;
u32 m_position;
u64 m_cur_block;
bool goto_block(u64 n)
{
vfsHDD_Block block_info;
if(m_info.data_block >= m_hdd_info.block_count)
{
return false;
}
m_hdd.Seek(m_info.data_block * m_hdd_info.block_size);
block_info.next_block = m_info.data_block;
for(u64 i=0; i<n; ++i)
{
if(!block_info.next_block || !block_info.is_used || block_info.next_block >= m_hdd_info.block_count)
{
return false;
}
m_hdd.Seek(block_info.next_block * m_hdd_info.block_size);
m_hdd.Read(&block_info, sizeof(vfsHDD_Block));
}
return true;
}
void RemoveBlocks(u64 start_block)
{
vfsHDD_Block block_info;
block_info.next_block = start_block;
while(block_info.next_block && block_info.is_used)
{
u64 offset = block_info.next_block * m_hdd_info.block_size;
ReadBlock(offset, block_info);
WriteBlock(offset, g_null_block);
}
}
void WriteBlock(u64 block, const vfsHDD_Block& data)
{
m_hdd.Seek(block * m_hdd_info.block_size);
m_hdd.Write(&data, sizeof(vfsHDD_Block));
}
void ReadBlock(u64 block, vfsHDD_Block& data)
{
m_hdd.Seek(block * m_hdd_info.block_size);
m_hdd.Read(&data, sizeof(vfsHDD_Block));
}
void WriteEntry(u64 block, const vfsHDD_Entry& data)
{
m_hdd.Seek(block * m_hdd_info.block_size);
m_hdd.Write(&data, sizeof(vfsHDD_Entry));
}
void ReadEntry(u64 block, vfsHDD_Entry& data)
{
m_hdd.Seek(block * m_hdd_info.block_size);
m_hdd.Read(&data, sizeof(vfsHDD_Entry));
}
void ReadEntry(u64 block, vfsHDD_Entry& data, wxString& name)
{
m_hdd.Seek(block * m_hdd_info.block_size);
m_hdd.Read(&data, sizeof(vfsHDD_Entry));
m_hdd.Read(wxStringBuffer(name, GetMaxNameLen()), GetMaxNameLen());
}
void ReadEntry(u64 block, wxString& name)
{
m_hdd.Seek(block * m_hdd_info.block_size + sizeof(vfsHDD_Entry));
m_hdd.Read(wxStringBuffer(name, GetMaxNameLen()), GetMaxNameLen());
}
void WriteEntry(u64 block, const vfsHDD_Entry& data, const wxString& name)
{
m_hdd.Seek(block * m_hdd_info.block_size);
m_hdd.Write(&data, sizeof(vfsHDD_Entry));
m_hdd.Write(name.c_str(), min<size_t>(GetMaxNameLen() - 1, name.Len() + 1));
}
__forceinline u32 GetMaxNameLen() const
{
return m_hdd_info.block_size - sizeof(vfsHDD_Entry);
}
public:
vfsHDDFile(vfsLocalFile& hdd, const vfsHDD_Hdr& hdd_info)
: m_hdd(hdd)
, m_hdd_info(hdd_info)
{
}
~vfsHDDFile()
{
}
void Open(u64 info_block)
{
m_info_block = info_block;
ReadEntry(m_info_block, m_info);
m_position = 0;
m_cur_block = m_info.data_block;
}
u64 FindFreeBlock()
{
vfsHDD_Block block_info;
for(u64 i = 0; i<m_hdd_info.block_count; ++i)
{
ReadBlock(i, block_info);
if(!block_info.is_used)
{
return i;
}
}
return 0;
}
u64 GetSize()
{
return m_info.size;
}
bool Seek(u64 pos)
{
if(!goto_block(pos / m_hdd_info.block_size))
{
return false;
}
m_position = pos % m_hdd_info.block_size;
return true;
}
void SaveInfo()
{
m_hdd.Seek(m_info_block * m_hdd_info.block_size);
m_hdd.Write(&m_info, sizeof(vfsHDD_Entry));
}
u64 Read(void* dst, u64 size)
{
if(!size)
return 0;
vfsDeviceLocker lock(m_hdd);
const u32 block_size = m_hdd_info.block_size - sizeof(vfsHDD_Block);
u64 rsize = min<u64>(block_size - m_position, size);
vfsHDD_Block cur_block_info;
m_hdd.Seek(m_cur_block * m_hdd_info.block_size);
m_hdd.Read(&cur_block_info, sizeof(vfsHDD_Block));
m_hdd.Seek(m_cur_block * m_hdd_info.block_size + sizeof(vfsHDD_Block) + m_position);
m_hdd.Read(dst, rsize);
size -= rsize;
m_position += rsize;
if(!size)
{
return rsize;
}
u64 offset = rsize;
for(; size; size -= rsize, offset += rsize)
{
if(!cur_block_info.is_used || !cur_block_info.next_block || cur_block_info.next_block >= m_hdd_info.block_count)
{
return offset;
}
m_cur_block = cur_block_info.next_block;
rsize = min<u64>(block_size, size);
m_hdd.Seek(cur_block_info.next_block * m_hdd_info.block_size);
m_hdd.Read(&cur_block_info, sizeof(vfsHDD_Block));
if(m_hdd.Read((u8*)dst + offset, rsize) != rsize)
{
return offset;
}
}
m_position = rsize;
return offset;
}
u64 Write(const void* src, u64 size)
{
if(!size)
return 0;
vfsDeviceLocker lock(m_hdd);
const u32 block_size = m_hdd_info.block_size - sizeof(vfsHDD_Block);
if(!m_cur_block)
{
if(!m_info.data_block)
{
u64 new_block = FindFreeBlock();
if(!new_block)
{
return 0;
}
WriteBlock(new_block, g_used_block);
m_info.data_block = new_block;
m_info.size = 0;
SaveInfo();
}
m_cur_block = m_info.data_block;
m_position = 0;
}
u64 wsize = min<u64>(block_size - m_position, size);
vfsHDD_Block block_info;
ReadBlock(m_cur_block, block_info);
if(wsize)
{
m_hdd.Seek(m_cur_block * m_hdd_info.block_size + sizeof(vfsHDD_Block) + m_position);
m_hdd.Write(src, wsize);
size -= wsize;
m_info.size += wsize;
m_position += wsize;
SaveInfo();
if(!size)
return wsize;
}
u64 last_block = m_cur_block;
block_info.is_used = true;
u64 offset = wsize;
for(; size; size -= wsize, offset += wsize, m_info.size += wsize)
{
u64 new_block = FindFreeBlock();
if(!new_block)
{
m_position = 0;
SaveInfo();
return offset;
}
m_cur_block = new_block;
wsize = min<u64>(block_size, size);
block_info.next_block = m_cur_block;
m_hdd.Seek(last_block * m_hdd_info.block_size);
if(m_hdd.Write(&block_info, sizeof(vfsHDD_Block)) != sizeof(vfsHDD_Block))
{
m_position = 0;
SaveInfo();
return offset;
}
block_info.next_block = 0;
m_hdd.Seek(m_cur_block * m_hdd_info.block_size);
if(m_hdd.Write(&block_info, sizeof(vfsHDD_Block)) != sizeof(vfsHDD_Block))
{
m_position = 0;
SaveInfo();
return offset;
}
if((m_position = m_hdd.Write((u8*)src + offset, wsize)) != wsize)
{
m_info.size += wsize;
SaveInfo();
return offset;
}
last_block = m_cur_block;
}
SaveInfo();
m_position = wsize;
return offset;
}
bool Eof() const
{
return m_info.size <= (m_cur_block * m_hdd_info.block_size + m_position);
}
};
class vfsHDD : public vfsFileBase
{
vfsHDD_Hdr m_hdd_info;
vfsHDD_Entry m_cur_dir;
u64 m_cur_dir_block;
vfsHDDFile m_file;
vfsLocalFile m_hdd_file;
const wxString& m_hdd_path;
public:
vfsHDD(const wxString& hdd_path)
: m_hdd_file(hdd_path, vfsReadWrite)
, m_file(m_hdd_file, m_hdd_info)
, m_hdd_path(hdd_path)
{
m_hdd_file.Read(&m_hdd_info, sizeof(vfsHDD_Hdr));
m_cur_dir_block = m_hdd_info.next_block;
if(!m_hdd_info.block_size)
{
ConLog.Error("Bad block size!");
m_hdd_info.block_size = 2048;
}
m_hdd_file.Seek(m_cur_dir_block * m_hdd_info.block_size);
m_hdd_file.Read(&m_cur_dir, sizeof(vfsHDD_Entry));
}
virtual vfsDevice* GetNew()
{
return new vfsHDD(m_hdd_path);
}
__forceinline u32 GetMaxNameLen() const
{
return m_hdd_info.block_size - sizeof(vfsHDD_Entry);
}
bool SearchEntry(const wxString& name, u64& entry_block, u64* parent_block = nullptr)
{
u64 last_block = 0;
u64 block = m_cur_dir_block;
vfsHDD_Entry entry;
wxString buf;
while(block)
{
ReadEntry(block, entry, buf);
if(name.CmpNoCase(buf) == 0)
{
entry_block = block;
if(parent_block)
*parent_block = last_block;
return true;
}
last_block = block;
block = entry.is_used ? entry.next_block : 0ULL;
}
return false;
}
int OpenDir(const wxString& name)
{
ConLog.Warning("OpenDir(%s)", name);
u64 entry_block;
if(!SearchEntry(name, entry_block))
return -1;
m_hdd_file.Seek(entry_block * m_hdd_info.block_size);
vfsHDD_Entry entry;
m_hdd_file.Read(&entry, sizeof(vfsHDD_Entry));
if(entry.type == vfsHDD_Entry_File)
return 1;
m_cur_dir_block = entry.data_block;
ReadEntry(m_cur_dir_block, m_cur_dir);
return 0;
}
bool Rename(const wxString& from, const wxString& to)
{
u64 entry_block;
if(!SearchEntry(from, entry_block))
{
return false;
}
vfsHDD_Entry entry;
ReadEntry(entry_block, entry);
WriteEntry(entry_block, entry, to);
return true;
}
u64 FindFreeBlock()
{
vfsHDD_Block block_info;
for(u64 i = 0; i<m_hdd_info.block_count; ++i)
{
ReadBlock(i, block_info);
if(!block_info.is_used)
{
return i;
}
}
return 0;
}
void WriteBlock(u64 block, const vfsHDD_Block& data)
{
m_hdd_file.Seek(block * m_hdd_info.block_size);
m_hdd_file.Write(&data, sizeof(vfsHDD_Block));
}
void ReadBlock(u64 block, vfsHDD_Block& data)
{
m_hdd_file.Seek(block * m_hdd_info.block_size);
m_hdd_file.Read(&data, sizeof(vfsHDD_Block));
}
void WriteEntry(u64 block, const vfsHDD_Entry& data)
{
m_hdd_file.Seek(block * m_hdd_info.block_size);
m_hdd_file.Write(&data, sizeof(vfsHDD_Entry));
}
void ReadEntry(u64 block, vfsHDD_Entry& data)
{
m_hdd_file.Seek(block * m_hdd_info.block_size);
m_hdd_file.Read(&data, sizeof(vfsHDD_Entry));
}
void ReadEntry(u64 block, vfsHDD_Entry& data, wxString& name)
{
m_hdd_file.Seek(block * m_hdd_info.block_size);
m_hdd_file.Read(&data, sizeof(vfsHDD_Entry));
m_hdd_file.Read(wxStringBuffer(name, GetMaxNameLen()), GetMaxNameLen());
}
void ReadEntry(u64 block, wxString& name)
{
m_hdd_file.Seek(block * m_hdd_info.block_size + sizeof(vfsHDD_Entry));
m_hdd_file.Read(wxStringBuffer(name, GetMaxNameLen()), GetMaxNameLen());
}
void WriteEntry(u64 block, const vfsHDD_Entry& data, const wxString& name)
{
m_hdd_file.Seek(block * m_hdd_info.block_size);
m_hdd_file.Write(&data, sizeof(vfsHDD_Entry));
m_hdd_file.Write(name.c_str(), min<size_t>(GetMaxNameLen() - 1, name.Len() + 1));
}
bool Create(vfsHDD_EntryType type, const wxString& name)
{
if(HasEntry(name))
{
return false;
}
u64 new_block = FindFreeBlock();
ConLog.Write("CREATION ENTRY AT 0x%llx", new_block);
if(!new_block)
{
return false;
}
WriteBlock(new_block, g_used_block);
{
vfsHDD_Entry new_entry;
vfsHDDManager::CreateEntry(new_entry);
new_entry.next_block = 0;
new_entry.type = type;
if(type == vfsHDD_Entry_Dir)
{
u64 block_cur = FindFreeBlock();
if(!block_cur)
{
return false;
}
WriteBlock(block_cur, g_used_block);
u64 block_last = FindFreeBlock();
if(!block_last)
{
return false;
}
WriteBlock(block_last, g_used_block);
vfsHDD_Entry entry_cur, entry_last;
vfsHDDManager::CreateEntry(entry_cur);
vfsHDDManager::CreateEntry(entry_last);
entry_cur.type = vfsHDD_Entry_Dir;
entry_cur.data_block = block_cur;
entry_cur.next_block = block_last;
entry_last.type = vfsHDD_Entry_Dir;
entry_last.data_block = m_cur_dir_block;
entry_last.next_block = 0;
new_entry.data_block = block_cur;
WriteEntry(block_cur, entry_cur, ".");
WriteEntry(block_last, entry_last, "..");
}
WriteEntry(new_block, new_entry, name);
}
{
u64 block = m_cur_dir_block;
vfsHDD_Block tmp;
while(block)
{
ReadBlock(block, tmp);
if(!tmp.next_block)
break;
block = tmp.next_block;
}
tmp.next_block = new_block;
WriteBlock(block, tmp);
}
return true;
}
bool GetFirstEntry(u64& block, vfsHDD_Entry& entry, wxString& name)
{
if(!m_cur_dir_block)
{
return false;
}
ReadEntry(m_cur_dir_block, entry, name);
block = entry.is_used ? entry.next_block : 0;
return true;
}
bool GetNextEntry(u64& block, vfsHDD_Entry& entry, wxString& name)
{
if(!block)
{
return false;
}
ReadEntry(block, entry, name);
block = entry.is_used ? entry.next_block : 0;
return true;
}
virtual bool Open(const wxString& path, vfsOpenMode mode = vfsRead)
{
const char* s = path.c_str();
u64 from = 0;
u64 pos = 0;
u64 file_pos = -1;
do
{
if(s[pos] == '\\' || s[pos] == '\0')
{
if(file_pos != -1)
{
return false;
}
if(from != -1)
{
if(pos - from > 1)
{
int res = OpenDir(wxString(s + from, pos));
if(res == -1)
{
return false;
}
if(res == 1)
{
file_pos = from;
}
}
from = pos;
}
else
{
from = pos;
}
}
}
while(s[pos++] != '\0');
if(file_pos == -1)
{
return false;
}
u64 file_block;
if(!SearchEntry(wxString(s + file_pos), file_block))
{
return false;
}
ConLog.Write("ENTRY FINDED AT 0x%llx", file_block);
m_file.Open(file_block);
return vfsFileBase::Open(path, mode);
}
bool HasEntry(const wxString& name)
{
u64 file_block;
if(!SearchEntry(name, file_block))
{
return false;
}
return true;
}
void RemoveBlocksDir(u64 start_block)
{
wxString name;
u64 block = start_block;
vfsHDD_Entry entry;
while(block)
{
ReadEntry(block, entry, name);
WriteBlock(block, g_null_block);
if(entry.type == vfsHDD_Entry_Dir && name != "." && name != "..")
{
ConLog.Warning("removing sub folder '%s'", name);
RemoveBlocksDir(entry.data_block);
}
else if(entry.type == vfsHDD_Entry_File)
{
RemoveBlocksFile(entry.data_block);
}
block = entry.next_block;
}
}
void RemoveBlocksFile(u64 start_block)
{
u64 block = start_block;
vfsHDD_Block block_data;
while(block)
{
ReadBlock(block, block_data);
WriteBlock(block, g_null_block);
block = block_data.next_block;
}
}
bool RemoveEntry(const wxString& name)
{
u64 entry_block, parent_entry;
if(!SearchEntry(name, entry_block, &parent_entry))
{
return false;
}
vfsHDD_Entry entry;
ReadEntry(entry_block, entry);
if(entry.type == vfsHDD_Entry_Dir)
{
RemoveBlocksDir(entry.data_block);
}
else if(entry.type == vfsHDD_Entry_File)
{
RemoveBlocksFile(entry.data_block);
}
if(parent_entry)
{
u64 next = entry.next_block;
ReadEntry(parent_entry, entry);
entry.next_block = next;
WriteEntry(parent_entry, entry);
}
WriteBlock(entry_block, g_null_block);
return true;
}
virtual bool Create(const wxString& path)
{
return false;
}
virtual u32 Write(const void* src, u32 size)
{
return vfsFileBase::Write(src, m_file.Write(src, size));
}
virtual u32 Read(void* dst, u32 size)
{
return vfsFileBase::Read(dst, m_file.Read(dst, size));
}
virtual u64 Seek(s64 offset, vfsSeekMode mode = vfsSeekSet)
{
switch(mode)
{
case vfsSeekCur:
m_file.Seek(Tell() + offset);
break;
case vfsSeekSet:
m_file.Seek(offset);
break;
case vfsSeekEnd:
m_file.Seek(m_file.GetSize() + offset);
break;
}
return vfsFileBase::Seek(offset, mode);
}
virtual bool Eof()
{
return m_file.Eof();
}
virtual u64 GetSize()
{
return m_file.GetSize();
}
};

View file

@ -336,6 +336,7 @@ public:
}
MemoryBlocks.Add((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;
}

View file

@ -36,7 +36,7 @@ protected:
public:
MemoryBlock();
~MemoryBlock();
virtual ~MemoryBlock();
private:
void Init();

View file

@ -318,7 +318,7 @@ s64 SysCalls::DoFunc(const u32 id)
case 0x5f909b17: FUNC_LOG_ERROR("TODO: _cellGcmFunc1");
case 0x626e8518: FUNC_LOG_ERROR("TODO: cellGcmMapEaIoAddressWithFlags");
case 0x63387071: FUNC_LOG_ERROR("TODO: cellGcmGetLastFlipTime");
case 0x63441cb4: FUNC_LOG_ERROR("TODO: cellGcmMapEaIoAddress");
case 0x63441cb4: return cellGcmMapEaIoAddress(SC_ARGS_3); //FUNC_LOG_ERROR("TODO: cellGcmMapEaIoAddress");
case 0x657571f7: FUNC_LOG_ERROR("TODO: cellGcmGetTileInfo");
case 0x661fe266: FUNC_LOG_ERROR("TODO: _cellGcmFunc12");
case 0x688b8ac9: FUNC_LOG_ERROR("TODO: _cellGcmFunc38");

View file

@ -65,51 +65,51 @@ static const g_module_list[] =
{0x0034, "cellSubdisplay"},
{0x0035, "cellSysutilRec"},
{0x0036, "cellVideoExport"},
{0x0037, "cellSysutilGameExec"},
{0x0037, "cellGameExec"},
{0x0038, "sceNp2"},
{0x0039, "cellSysutilAp"},
{0x003a, "cellSysutilNpClans"},
{0x003b, "cellSysutilOskExt"},
{0x003c, "cellVdecDivx"},
{0x003d, "cellJpgEnc"},
{0x003e, "cellSysutilGame"},
{0x003e, "cellGame"},
{0x003f, "cellBgdl"},
{0x0040, "cellFreetypeTT"},
{0x0041, "cellSysutilVideoUpload"},
{0x0042, "cellSysutilSysconfExt"},
{0x0043, "cellFiber"},
{0x0044, "cellSysutilNpCommerce2"},
{0x0045, "cellSysutilNpTus"},
{0x0044, "cellNpCommerce2"},
{0x0045, "cellNpTus"},
{0x0046, "cellVoice"},
{0x0047, "cellAdecCelp8"},
{0x0048, "cellCelp8Enc"},
{0x0049, "cellSysutilLicenseArea"},
{0x004a, "cellSysutilMusic2"},
{0x004e, "cellSysutilScreenshot"},
{0x004f, "cellSysutilMusicDecode"},
{0x0050, "cellSysutilSpursJq"},
{0x0049, "cellLicenseArea"},
{0x004a, "cellMusic2"},
{0x004e, "cellScreenshot"},
{0x004f, "cellMusicDecode"},
{0x0050, "cellSpursJq"},
{0x0052, "cellPngEnc"},
{0x0053, "cellSysutilMusicDecode2"},
{0x0053, "cellMusicDecode2"},
{0x0055, "cellSync2"},
{0x0056, "cellSysutilNpUtil"},
{0x0056, "cellNpUtil"},
{0x0057, "cellRudp"},
{0x0059, "cellSysutilNpSns"},
{0x0059, "cellNpSns"},
{0x005a, "cellGem"},
{0xf00a, "cellScelpEnc"},
{0xf00a, "cellCelpEnc"},
{0xf010, "cellGifDec"},
{0xf019, "cellAdecCelp"},
{0xf01b, "cellAdecM2bc"},
{0xf01d, "cellAdecM4aac"},
{0xf01e, "cellAdecMp3"},
{0xf023, "cellImejp"},
{0xf028, "cellSysutilMusic"},
{0xf028, "cellMusic"},
{0xf029, "cellPhotoExport"},
{0xf02a, "cellPrint"},
{0xf02b, "cellPhotoImport"},
{0xf02c, "cellMusicExport"},
{0xf02e, "cellPhotoDecode"},
{0xf02f, "cellSysutilSearch"},
{0xf030, "cellSysutilAvchat2"},
{0xf02f, "cellSearch"},
{0xf030, "cellAvchat2"},
{0xf034, "cellSailRec"},
{0xf035, "sceNpTrophy"},
{0xf053, "cellAdecAt3multi"},

View file

@ -65,9 +65,11 @@ public:
template<typename T> bool CheckId(u32 id, T*& data);
u32 GetNewId(void* data = nullptr, u8 flags = 0);
__forceinline void Module::AddFunc(u32 id, func_caller* func)
template<typename T>
__forceinline void AddFunc(u32 id, T func)
{
m_funcs_list.Move(new ModuleFunc(id, func));
m_funcs_list.Move(new ModuleFunc(id, bind_func(func)));
}
};

View file

@ -19,20 +19,23 @@ s64 cellGcmSetFlipCommandWithWaitLabel()
void cellGcmSys_init()
{
cellGcmSys.AddFunc(0x055bd74d, bind_func(cellGcmGetTiledPitchSize));
cellGcmSys.AddFunc(0x15bae46b, bind_func(cellGcmInit));
cellGcmSys.AddFunc(0x21397818, bind_func(cellGcmFlush));
cellGcmSys.AddFunc(0x21ac3697, bind_func(cellGcmAddressToOffset));
cellGcmSys.AddFunc(0x3a33c1fd, bind_func(cellGcmFunc15));
cellGcmSys.AddFunc(0x4ae8d215, bind_func(cellGcmSetFlipMode));
cellGcmSys.AddFunc(0x5e2ee0f0, bind_func(cellGcmGetDefaultCommandWordSize));
cellGcmSys.AddFunc(0x72a577ce, bind_func(cellGcmGetFlipStatus));
cellGcmSys.AddFunc(0x8cdf8c70, bind_func(cellGcmGetDefaultSegmentWordSize));
cellGcmSys.AddFunc(0x9ba451e4, bind_func(cellGcmSetDefaultFifoSize));
cellGcmSys.AddFunc(0xa53d12ae, bind_func(cellGcmSetDisplayBuffer));
cellGcmSys.AddFunc(0xa547adde, bind_func(cellGcmGetControlRegister));
cellGcmSys.AddFunc(0xb2e761d4, bind_func(cellGcmResetFlipStatus));
cellGcmSys.AddFunc(0xd8f88e1a, bind_func(cellGcmSetFlipCommandWithWaitLabel));
cellGcmSys.AddFunc(0xe315a0b2, bind_func(cellGcmGetConfiguration));
cellGcmSys.AddFunc(0x9dc04436, bind_func(cellGcmBindZcull));
cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize);
cellGcmSys.AddFunc(0x15bae46b, cellGcmInit);
cellGcmSys.AddFunc(0x21397818, cellGcmFlush);
cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset);
cellGcmSys.AddFunc(0x3a33c1fd, cellGcmFunc15);
cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode);
cellGcmSys.AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize);
cellGcmSys.AddFunc(0x72a577ce, cellGcmGetFlipStatus);
cellGcmSys.AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize);
cellGcmSys.AddFunc(0x9ba451e4, cellGcmSetDefaultFifoSize);
cellGcmSys.AddFunc(0xa53d12ae, cellGcmSetDisplayBuffer);
cellGcmSys.AddFunc(0xa547adde, cellGcmGetControlRegister);
cellGcmSys.AddFunc(0xb2e761d4, cellGcmResetFlipStatus);
cellGcmSys.AddFunc(0xd8f88e1a, cellGcmSetFlipCommandWithWaitLabel);
cellGcmSys.AddFunc(0xe315a0b2, cellGcmGetConfiguration);
cellGcmSys.AddFunc(0x9dc04436, cellGcmBindZcull);
cellGcmSys.AddFunc(0xd9b7653e, cellGcmUnbindTile);
cellGcmSys.AddFunc(0xa75640e8, cellGcmUnbindZcull);
}

View file

@ -86,10 +86,10 @@ int cellSysmoduleIsLoaded(u16 id)
void cellSysmodule_init()
{
cellSysmodule.AddFunc(0x63ff6ff9, bind_func(cellSysmoduleInitialize));
cellSysmodule.AddFunc(0x96c07adf, bind_func(cellSysmoduleFinalize));
cellSysmodule.AddFunc(0xa193143c, bind_func(cellSysmoduleSetMemcontainer));
cellSysmodule.AddFunc(0x32267a31, bind_func(cellSysmoduleLoadModule));
cellSysmodule.AddFunc(0x112a5ee9, bind_func(cellSysmoduleUnloadModule));
cellSysmodule.AddFunc(0x5a59e258, bind_func(cellSysmoduleIsLoaded));
cellSysmodule.AddFunc(0x63ff6ff9, cellSysmoduleInitialize);
cellSysmodule.AddFunc(0x96c07adf, cellSysmoduleFinalize);
cellSysmodule.AddFunc(0xa193143c, cellSysmoduleSetMemcontainer);
cellSysmodule.AddFunc(0x32267a31, cellSysmoduleLoadModule);
cellSysmodule.AddFunc(0x112a5ee9, cellSysmoduleUnloadModule);
cellSysmodule.AddFunc(0x5a59e258, cellSysmoduleIsLoaded);
}

View file

@ -49,34 +49,34 @@ s64 sys_strlen(u32 addr)
void sysPrxForUser_init()
{
sysPrxForUser.AddFunc(0x744680a2, bind_func(sys_initialize_tls));
sysPrxForUser.AddFunc(0x744680a2, sys_initialize_tls);
sysPrxForUser.AddFunc(0x2f85c0ef, bind_func(sys_lwmutex_create));
sysPrxForUser.AddFunc(0xc3476d0c, bind_func(sys_lwmutex_destroy));
sysPrxForUser.AddFunc(0x1573dc3f, bind_func(sys_lwmutex_lock));
sysPrxForUser.AddFunc(0xaeb78725, bind_func(sys_lwmutex_trylock));
sysPrxForUser.AddFunc(0x1bc200f4, bind_func(sys_lwmutex_unlock));
sysPrxForUser.AddFunc(0x2f85c0ef, sys_lwmutex_create);
sysPrxForUser.AddFunc(0xc3476d0c, sys_lwmutex_destroy);
sysPrxForUser.AddFunc(0x1573dc3f, sys_lwmutex_lock);
sysPrxForUser.AddFunc(0xaeb78725, sys_lwmutex_trylock);
sysPrxForUser.AddFunc(0x1bc200f4, sys_lwmutex_unlock);
sysPrxForUser.AddFunc(0x8461e528, bind_func(sys_time_get_system_time));
sysPrxForUser.AddFunc(0x8461e528, sys_time_get_system_time);
sysPrxForUser.AddFunc(0xe6f2c1e7, bind_func(sys_process_exit));
sysPrxForUser.AddFunc(0x2c847572, bind_func(sys_process_atexitspawn));
sysPrxForUser.AddFunc(0x96328741, bind_func(sys_process_at_Exitspawn));
sysPrxForUser.AddFunc(0xe6f2c1e7, sys_process_exit);
sysPrxForUser.AddFunc(0x2c847572, sys_process_atexitspawn);
sysPrxForUser.AddFunc(0x96328741, sys_process_at_Exitspawn);
sysPrxForUser.AddFunc(0x24a1ea07, bind_func(sys_ppu_thread_create));
sysPrxForUser.AddFunc(0x350d454e, bind_func(sys_ppu_thread_get_id));
sysPrxForUser.AddFunc(0xaff080a4, bind_func(sys_ppu_thread_exit));
sysPrxForUser.AddFunc(0xa3e3be68, bind_func(sys_ppu_thread_once));
sysPrxForUser.AddFunc(0x24a1ea07, sys_ppu_thread_create);
sysPrxForUser.AddFunc(0x350d454e, sys_ppu_thread_get_id);
sysPrxForUser.AddFunc(0xaff080a4, sys_ppu_thread_exit);
sysPrxForUser.AddFunc(0xa3e3be68, sys_ppu_thread_once);
sysPrxForUser.AddFunc(0x45fe2fce, bind_func(sys_spu_printf_initialize));
sysPrxForUser.AddFunc(0x45fe2fce, sys_spu_printf_initialize);
sysPrxForUser.AddFunc(0x42b23552, bind_func(sys_prx_register_library));
sysPrxForUser.AddFunc(0xa2c7ba64, bind_func(sys_prx_exitspawn_with_level));
sysPrxForUser.AddFunc(0x42b23552, sys_prx_register_library);
sysPrxForUser.AddFunc(0xa2c7ba64, sys_prx_exitspawn_with_level);
sysPrxForUser.AddFunc(0x2d36462b, bind_func(sys_strlen));
sysPrxForUser.AddFunc(0x2d36462b, sys_strlen);
sysPrxForUser.AddFunc(0x35168520, bind_func(sys_heap_malloc));
//sysPrxForUser.AddFunc(0xaede4b03, bind_func(sys_heap_free));
//sysPrxForUser.AddFunc(0x8a561d92, bind_func(sys_heap_delete_heap));
sysPrxForUser.AddFunc(0xb2fcf2c8, bind_func(sys_heap_create_heap));
sysPrxForUser.AddFunc(0x35168520, sys_heap_malloc);
//sysPrxForUser.AddFunc(0xaede4b03, sys_heap_free);
//sysPrxForUser.AddFunc(0x8a561d92, sys_heap_delete_heap);
sysPrxForUser.AddFunc(0xb2fcf2c8, sys_heap_create_heap);
}

View file

@ -7,18 +7,18 @@ Module sys_fs(0x000e, sys_fs_init);
void sys_fs_init()
{
sys_fs.AddFunc(0x718bf5f8, bind_func(cellFsOpen));
sys_fs.AddFunc(0x4d5ff8e2, bind_func(cellFsRead));
sys_fs.AddFunc(0xecdcf2ab, bind_func(cellFsWrite));
sys_fs.AddFunc(0x2cb51f0d, bind_func(cellFsClose));
sys_fs.AddFunc(0x3f61245c, bind_func(cellFsOpendir));
sys_fs.AddFunc(0x5c74903d, bind_func(cellFsReaddir));
sys_fs.AddFunc(0xff42dcc3, bind_func(cellFsClosedir));
sys_fs.AddFunc(0x7de6dced, bind_func(cellFsStat));
sys_fs.AddFunc(0xef3efa34, bind_func(cellFsFstat));
sys_fs.AddFunc(0xba901fe6, bind_func(cellFsMkdir));
sys_fs.AddFunc(0xf12eecc8, bind_func(cellFsRename));
sys_fs.AddFunc(0x2796fdf3, bind_func(cellFsRmdir));
sys_fs.AddFunc(0x7f4677a8, bind_func(cellFsUnlink));
sys_fs.AddFunc(0xa397d042, bind_func(cellFsLseek));
sys_fs.AddFunc(0x718bf5f8, cellFsOpen);
sys_fs.AddFunc(0x4d5ff8e2, cellFsRead);
sys_fs.AddFunc(0xecdcf2ab, cellFsWrite);
sys_fs.AddFunc(0x2cb51f0d, cellFsClose);
sys_fs.AddFunc(0x3f61245c, cellFsOpendir);
sys_fs.AddFunc(0x5c74903d, cellFsReaddir);
sys_fs.AddFunc(0xff42dcc3, cellFsClosedir);
sys_fs.AddFunc(0x7de6dced, cellFsStat);
sys_fs.AddFunc(0xef3efa34, cellFsFstat);
sys_fs.AddFunc(0xba901fe6, cellFsMkdir);
sys_fs.AddFunc(0xf12eecc8, cellFsRename);
sys_fs.AddFunc(0x2796fdf3, cellFsRmdir);
sys_fs.AddFunc(0x7f4677a8, cellFsUnlink);
sys_fs.AddFunc(0xa397d042, cellFsLseek);
}

View file

@ -7,12 +7,12 @@ Module sys_io(0x0017, sys_io_init);
void sys_io_init()
{
sys_io.AddFunc(0x1cf98800, bind_func(cellPadInit));
sys_io.AddFunc(0x4d9b75d5, bind_func(cellPadEnd));
sys_io.AddFunc(0x0d5f2c14, bind_func(cellPadClearBuf));
sys_io.AddFunc(0x8b72cda1, bind_func(cellPadGetData));
sys_io.AddFunc(0x6bc09c61, bind_func(cellPadGetDataExtra));
sys_io.AddFunc(0xf65544ee, bind_func(cellPadSetActDirect));
sys_io.AddFunc(0xa703a51d, bind_func(cellPadGetInfo2));
sys_io.AddFunc(0x578e3c98, bind_func(cellPadSetPortSetting));
sys_io.AddFunc(0x1cf98800, cellPadInit);
sys_io.AddFunc(0x4d9b75d5, cellPadEnd);
sys_io.AddFunc(0x0d5f2c14, cellPadClearBuf);
sys_io.AddFunc(0x8b72cda1, cellPadGetData);
sys_io.AddFunc(0x6bc09c61, cellPadGetDataExtra);
sys_io.AddFunc(0xf65544ee, cellPadSetActDirect);
sys_io.AddFunc(0xa703a51d, cellPadGetInfo2);
sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting);
}

View file

@ -14,7 +14,7 @@ static func_caller* sc_table[1024] =
null_func, null_func, null_func, null_func, null_func, //34
null_func, null_func, null_func, null_func, null_func, //39
null_func, bind_func(sys_ppu_thread_exit), null_func, bind_func(sys_ppu_thread_yield), bind_func(sys_ppu_thread_join), //44
bind_func(sys_ppu_thread_detach), bind_func(sys_ppu_thread_detach), bind_func(sys_ppu_thread_get_join_state), bind_func(sys_ppu_thread_set_priority), bind_func(sys_ppu_thread_get_priority), //49
bind_func(sys_ppu_thread_detach), bind_func(sys_ppu_thread_get_join_state), bind_func(sys_ppu_thread_set_priority), bind_func(sys_ppu_thread_get_priority), bind_func(sys_ppu_thread_get_stack_information), //49
bind_func(sys_ppu_thread_stop), bind_func(sys_ppu_thread_restart), bind_func(sys_ppu_thread_create), null_func, null_func, //54
null_func, null_func, null_func, null_func, null_func, //59
null_func, null_func, null_func, null_func, null_func, //64

View file

@ -235,6 +235,9 @@ extern int cellGcmSetFlipMode(u32 mode);
extern u32 cellGcmGetDefaultCommandWordSize();
extern u32 cellGcmGetDefaultSegmentWordSize();
extern int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize);
extern int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size);
extern int cellGcmUnbindTile(u8 index);
extern int cellGcmUnbindZcull(u8 index);
//sys_tty
extern int sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr);

View file

@ -63,7 +63,7 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
{
u32 val;
thr->SPU_OutIntr_Mbox.Pop(val);
if(!thr->SPU_Out_MBox.Pop(val)) val = 0;
if(!thr->mfc.SPU_Out_MBox.Pop(val)) val = 0;
equeue->ports[i]->data1 = val;
equeue->ports[i]->data2 = 0;
equeue->ports[i]->data3 = 0;

View file

@ -135,7 +135,7 @@ int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height
u32 cellGcmGetLabelAddress(u8 index)
{
cellGcmSys.Error("cellGcmGetLabelAddress(index=%d)", index);
cellGcmSys.Log("cellGcmGetLabelAddress(index=%d)", index);
return Memory.RSXCMDMem.GetStartAddr() + 0x10 * index;
}
@ -234,3 +234,28 @@ int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize)
cellGcmSys.Warning("cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize);
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);
return CELL_OK;
}
int cellGcmUnbindTile(u8 index)
{
cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index);
if(index >= 15)
return CELL_EINVAL;
return CELL_OK;
}
int cellGcmUnbindZcull(u8 index)
{
cellGcmSys.Warning("cellGcmUnbindZcull(index=%d)", index);
if(index >= 8)
return CELL_EINVAL;
return CELL_OK;
}

View file

@ -1,158 +1,5 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
/*
struct MemContiner
{
u8* continer;
u32 num;
void Create(u32 size)
{
continer = new u8[size];
}
void Delete()
{
if(continer != NULL) free(continer);
}
~MemContiner()
{
Delete();
}
};
class MemContiners : private SysCallBase
{
SysCallsArraysList<MemContiner> continers;
public:
MemContiners() : SysCallBase("MemContainers")
{
}
u64 AddContiner(const u64 size)
{
const u64 id = continers.Add();
bool error;
MemContiner& data = *continers.GetDataById(id, &error);
if(error)
{
ConLog.Error("%s error: id [%d] is not found!", module_name, id);
return 0;
}
data.Create(size);
return id;
}
void DeleteContiner(const u64 id)
{
bool error;
MemContiner& data = *continers.GetDataById(id, &error);
if(error)
{
ConLog.Error("%s error: id [%d] is not found!", module_name, id);
return;
}
data.Delete();
continers.RemoveById(id);
}
};
MemContiners continers;
*/
/*
int SysCalls::lv2MemContinerCreate(PPUThread& CPU)
{
u64& continer = CPU.GPR[3];
u32 size = CPU.GPR[4];
ConLog.Warning("lv2MemContinerCreate[size: 0x%x]", size);
//continer = continers.AddContiner(size);
return 0;
}
int SysCalls::lv2MemContinerDestroy(PPUThread& CPU)
{
u32 container = CPU.GPR[3];
ConLog.Warning("lv2MemContinerDestroy[container: 0x%x]", container);
//continers.DeleteContiner(container);
return 0;
}*/
/*
static const u32 max_user_mem = 0x0d500000; //100mb
u32 free_user_mem = max_user_mem;
static u64 addr_user_mem = 0;
struct MemoryInfo
{
u32 free_user_mem;
u32 aviable_user_mem;
};
enum
{
SYS_MEMORY_PAGE_SIZE_1M = 0x400,
SYS_MEMORY_PAGE_SIZE_64K = 0x200,
};
int SysCalls::sys_memory_allocate(u32 size, u64 flags, u64 alloc_addr)
{
//int sys_memory_allocate(size_t size, uint64_t flags, sys_addr_t * alloc_addr);
const u64 size = CPU.GPR[3];
const u64 flags = CPU.GPR[4];
const u64 alloc_addr = CPU.GPR[5];
ConLog.Write("lv2MemAllocate: size: 0x%llx, flags: 0x%llx, alloc_addr: 0x%llx", size, flags, alloc_addr);
//u32 addr = 0;
switch(flags)
{
case SYS_MEMORY_PAGE_SIZE_1M:
if(size & 0xfffff) return CELL_EALIGN;
//addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(size & 0xffff) return CELL_EALIGN;
//addr = Memory.Alloc(size, 0x10000);
break;
default: return CELL_EINVAL;
}
u32 num = Memory.MemoryBlocks.GetCount();
Memory.MemoryBlocks.Add(new MemoryBlock());
Memory.MemoryBlocks[num].SetRange(Memory.MemoryBlocks[num - 1].GetEndAddr(), size);
Memory.Write32(alloc_addr, Memory.MemoryBlocks[num].GetStartAddr());
ConLog.Write("Test...");
Memory.Write32(Memory.MemoryBlocks[num].GetStartAddr(), 0xfff);
if(Memory.Read32(Memory.MemoryBlocks[num].GetStartAddr()) != 0xfff)
{
ConLog.Write("Test faild");
}
else
{
ConLog.Write("Test OK");
Memory.Write32(Memory.MemoryBlocks[num].GetStartAddr(), 0x0);
}
return CELL_OK;
}
int SysCalls::sys_memory_get_user_memory_size(PPUThread& CPU)
{
ConLog.Write("lv2MemGetUserMemorySize: r3=0x%llx", CPU.GPR[3]);
//int sys_memory_get_user_memory_size(sys_memory_info_t * mem_info);
MemoryInfo& memoryinfo = *(MemoryInfo*)Memory.GetMemFromAddr(CPU.GPR[3]);
memoryinfo.aviable_user_mem = Memory.Reverse32(free_user_mem);
memoryinfo.free_user_mem = Memory.Reverse32(free_user_mem);
return CELL_OK;
}*/
SysCallBase sc_mem("memory");
@ -248,11 +95,13 @@ int sys_memory_free(u32 start_addr)
struct mmapper_info
{
u64 addr;
u32 size;
u32 flags;
mmapper_info(u32 _size, u32 _flags)
: size(_size)
mmapper_info(u64 _addr, u32 _size, u32 _flags)
: addr(_addr)
, size(_size)
, flags(_flags)
{
}
@ -266,7 +115,7 @@ int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_a
{
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr);
Memory.Write32(alloc_addr, Memory.Alloc(size, alignment));
Memory.Write32(alloc_addr, Memory.Alloc(size, 4));
return CELL_OK;
}
@ -276,7 +125,13 @@ int sys_mmapper_allocate_memory(u32 size, u64 flags, u32 mem_id_addr)
sc_mem.Warning("sys_mmapper_allocate_memory(size=0x%x, flags=0x%llx, mem_id_addr=0x%x)", size, flags, mem_id_addr);
if(!Memory.IsGoodAddr(mem_id_addr)) return CELL_EFAULT;
Memory.Write32(mem_id_addr, sc_mem.GetNewId(new mmapper_info(size, flags)));
u64 addr = Memory.Alloc(size, 1);
if(!addr)
return CELL_ENOMEM;
Memory.Write32(mem_id_addr, sc_mem.GetNewId(new mmapper_info(addr, size, flags)));
return CELL_OK;
}
@ -288,6 +143,10 @@ int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags)
mmapper_info* info;
if(!sc_mem.CheckId(mem_id, info)) return CELL_ESRCH;
if(!Memory.Map(start_addr, info->addr, info->size))
{
sc_mem.Error("sys_mmapper_map_memory failed!");
}
//Memory.MemoryBlocks.Add((new MemoryBlock())->SetRange(start_addr, info->size));
return CELL_OK;

View file

@ -350,7 +350,7 @@ int sys_spu_thread_write_spu_mb(u32 id, u32 value)
return CELL_ESRCH;
}
if(!(*(SPUThread*)thr).SPU_In_MBox.Push(value))
if(!(*(SPUThread*)thr).mfc.SPU_In_MBox.Push(value))
{
ConLog.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x): used all mbox items.");
return CELL_EBUSY; //?

View file

@ -174,10 +174,11 @@ void Emulator::Run()
//ConLog.Write("run...");
m_status = Runned;
m_vfs.Mount("/", vfsDevice::GetRoot(m_path), new vfsLocalFile());
m_vfs.Mount("/dev_hdd0/", wxGetCwd() + "\\dev_hdd0\\", new vfsLocalFile());
m_vfs.Mount("/app_home/", vfsDevice::GetRoot(m_path), new vfsLocalFile());
m_vfs.Mount(vfsDevice::GetRootPs3(m_path), vfsDevice::GetRoot(m_path), new vfsLocalFile());
m_vfs.Init(m_path);
//m_vfs.Mount("/", vfsDevice::GetRoot(m_path), new vfsLocalFile());
//m_vfs.Mount("/dev_hdd0/", wxGetCwd() + "\\dev_hdd0\\", new vfsLocalFile());
//m_vfs.Mount("/app_home/", vfsDevice::GetRoot(m_path), new vfsLocalFile());
//m_vfs.Mount(vfsDevice::GetRootPs3(m_path), vfsDevice::GetRoot(m_path), new vfsLocalFile());
ConLog.SkipLn();
ConLog.Write("Mount info:");
@ -245,6 +246,8 @@ void Emulator::Stop()
m_break_points.Clear();
m_marked_points.Clear();
m_vfs.UnMountAll();
GetGSManager().Close();
GetCPU().Close();
//SysCallsManager.Close();

View file

@ -5,6 +5,8 @@
#include "Emu/System.h"
#include "Ini.h"
#include "Emu/GS/sysutil_video.h"
#include "Gui/VHDDManager.h"
#include "Gui/VFSManager.h"
#include <wx/dynlib.h>
BEGIN_EVENT_TABLE(MainFrame, FrameBase)
@ -20,6 +22,8 @@ enum IDs
id_sys_stop,
id_sys_send_exit,
id_config_emu,
id_config_vfs_manager,
id_config_vhdd_manager,
id_update_dbg,
};
@ -31,7 +35,7 @@ wxString GetPaneName()
}
MainFrame::MainFrame()
: FrameBase(NULL, wxID_ANY, "", "MainFrame", wxSize(280, 180))
: FrameBase(NULL, wxID_ANY, "", "MainFrame", wxSize(800, 600))
, m_aui_mgr(this)
{
SetLabel(wxString::Format(_PRGNAME_ " " _PRGVER_));
@ -56,22 +60,29 @@ MainFrame::MainFrame()
menu_sys.Append(id_sys_send_exit, "Send exit cmd")->Enable(false);
menu_conf.Append(id_config_emu, "Settings");
menu_conf.AppendSeparator();
menu_conf.Append(id_config_vfs_manager, "Virtual File System Manager");
menu_conf.Append(id_config_vhdd_manager, "Virtual HDD Manager");
SetMenuBar(&menubar);
m_game_viewer = new GameViewer(this);
AddPane(m_game_viewer, "Game List", wxAUI_DOCK_BOTTOM);
Connect( id_boot_game, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootGame) );
Connect( id_boot_elf, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootElf) );
Connect( id_boot_self, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootSelf) );
Connect( id_boot_game, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootGame) );
Connect( id_boot_elf, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootElf) );
Connect( id_boot_self, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootSelf) );
Connect( id_sys_pause, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Pause) );
Connect( id_sys_stop, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Stop) );
Connect( id_sys_send_exit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendExit) );
Connect( id_update_dbg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::UpdateUI) );
Connect( id_sys_pause, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Pause) );
Connect( id_sys_stop, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Stop) );
Connect( id_sys_send_exit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendExit) );
Connect( id_config_emu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Config) );
Connect( id_config_vfs_manager, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigVFS) );
Connect( id_config_vhdd_manager,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigVHDD) );
Connect( id_update_dbg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::UpdateUI) );
Connect( id_config_emu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Config) );
m_app_connector.Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainFrame::OnKeyDown), (wxObject*)0, this);
m_app_connector.Connect(wxEVT_DBG_COMMAND, wxCommandEventHandler(MainFrame::UpdateUI), (wxObject*)0, this);
}
@ -83,6 +94,7 @@ MainFrame::~MainFrame()
void MainFrame::AddPane(wxWindow* wind, const wxString& caption, int flags)
{
wind->SetSize(-1, 300);
m_aui_mgr.AddPane(wind, wxAuiPaneInfo().Name(GetPaneName()).Caption(caption).Direction(flags).CloseButton(false).MaximizeButton());
}
@ -366,6 +378,16 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
if(paused) Emu.Resume();
}
void MainFrame::ConfigVFS(wxCommandEvent& WXUNUSED(event))
{
VFSManagerDialog(this).ShowModal();
}
void MainFrame::ConfigVHDD(wxCommandEvent& WXUNUSED(event))
{
VHDDManagerDialog(this).ShowModal();
}
void MainFrame::UpdateUI(wxCommandEvent& event)
{
event.Skip();

View file

@ -25,6 +25,8 @@ private:
void Stop(wxCommandEvent& event);
void SendExit(wxCommandEvent& event);
void Config(wxCommandEvent& event);
void ConfigVFS(wxCommandEvent& event);
void ConfigVHDD(wxCommandEvent& event);
void UpdateUI(wxCommandEvent& event);
void OnKeyDown(wxKeyEvent& event);

View file

@ -0,0 +1,37 @@
#include "stdafx.h"
#include "TextInputDialog.h"
TextInputDialog::TextInputDialog(wxWindow* parent, const wxString& defvalue)
: wxDialog(parent, wxID_ANY, "Input text", wxDefaultPosition)
{
m_tctrl_text = new wxTextCtrl(this, wxID_ANY, defvalue);
wxBoxSizer& s_text(*new wxBoxSizer(wxVERTICAL));
s_text.Add(m_tctrl_text, 1, wxEXPAND);
wxBoxSizer& s_btns(*new wxBoxSizer(wxHORIZONTAL));
s_btns.Add(new wxButton(this, wxID_OK));
s_btns.AddSpacer(30);
s_btns.Add(new wxButton(this, wxID_CANCEL));
wxBoxSizer& s_main(*new wxBoxSizer(wxVERTICAL));
s_main.Add(&s_text, 1, wxEXPAND | wxUP | wxLEFT | wxRIGHT, 5);
s_main.AddSpacer(30);
s_main.Add(&s_btns, 0, wxCENTER | wxDOWN | wxLEFT | wxRIGHT, 5);
SetSizerAndFit(&s_main);
SetSize(250, -1);
Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TextInputDialog::OnOk));
}
void TextInputDialog::OnOk(wxCommandEvent& event)
{
m_result = m_tctrl_text->GetValue();
EndModal(wxID_OK);
}
wxString& TextInputDialog::GetResult()
{
return m_result;
}

View file

@ -0,0 +1,13 @@
#pragma once
class TextInputDialog : public wxDialog
{
wxTextCtrl* m_tctrl_text;
wxString m_result;
public:
TextInputDialog(wxWindow* parent, const wxString& defvalue = wxEmptyString);
void OnOk(wxCommandEvent& event);
wxString& GetResult();
};

219
rpcs3/Gui/VFSManager.cpp Normal file
View file

@ -0,0 +1,219 @@
#include "stdafx.h"
#include "VFSManager.h"
VFSEntrySettingsDialog::VFSEntrySettingsDialog(wxWindow* parent, VFSManagerEntry& entry)
: wxDialog(parent, wxID_ANY, "Mount configuration", wxDefaultPosition)
, m_entry(entry)
{
m_tctrl_dev_path = new wxTextCtrl(this, wxID_ANY);
m_btn_select_dev_path = new wxButton(this, wxID_ANY, "...");
m_tctrl_path = new wxTextCtrl(this, wxID_ANY);
m_btn_select_path = new wxButton(this, wxID_ANY, "...");
m_tctrl_mount = new wxTextCtrl(this, wxID_ANY);
m_ch_type = new wxChoice(this, wxID_ANY);
wxBoxSizer& s_type(*new wxBoxSizer(wxHORIZONTAL));
s_type.Add(m_ch_type, 1, wxEXPAND);
wxBoxSizer& s_dev_path(*new wxBoxSizer(wxHORIZONTAL));
s_dev_path.Add(m_tctrl_dev_path, 1, wxEXPAND);
s_dev_path.Add(m_btn_select_dev_path, 0, wxLEFT, 5);
wxBoxSizer& s_path(*new wxBoxSizer(wxHORIZONTAL));
s_path.Add(m_tctrl_path, 1, wxEXPAND);
s_path.Add(m_btn_select_path, 0, wxLEFT, 5);
wxBoxSizer& s_mount(*new wxBoxSizer(wxHORIZONTAL));
s_mount.Add(m_tctrl_mount, 1, wxEXPAND);
wxBoxSizer& s_btns(*new wxBoxSizer(wxHORIZONTAL));
s_btns.Add(new wxButton(this, wxID_OK));
s_btns.AddSpacer(30);
s_btns.Add(new wxButton(this, wxID_CANCEL));
wxBoxSizer& s_main(*new wxBoxSizer(wxVERTICAL));
s_main.Add(&s_type, 1, wxEXPAND | wxALL, 10);
s_main.Add(&s_dev_path, 1, wxEXPAND | wxALL, 10);
s_main.Add(&s_path, 1, wxEXPAND | wxALL, 10);
s_main.Add(&s_mount, 1, wxEXPAND | wxALL, 10);
s_main.AddSpacer(10);
s_main.Add(&s_btns, 0, wxALL | wxCENTER, 10);
SetSizerAndFit(&s_main);
SetSize(350, -1);
for(const auto i : vfsDeviceTypeNames)
{
m_ch_type->Append(i);
}
Connect(m_ch_type->GetId(), wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(VFSEntrySettingsDialog::OnSelectType));
Connect(m_btn_select_path->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(VFSEntrySettingsDialog::OnSelectPath));
Connect(m_btn_select_dev_path->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(VFSEntrySettingsDialog::OnSelectDevPath));
Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(VFSEntrySettingsDialog::OnOk));
m_tctrl_dev_path->SetValue(m_entry.device_path.GetPtr());
m_tctrl_path->SetValue(m_entry.path.GetPtr());
m_tctrl_mount->SetValue(m_entry.mount.GetPtr());
m_ch_type->SetSelection(m_entry.device);
OnSelectType(wxCommandEvent());
}
void VFSEntrySettingsDialog::OnSelectType(wxCommandEvent& event)
{
m_btn_select_path->Enable(m_ch_type->GetSelection() == vfsDevice_LocalFile);
m_tctrl_dev_path->Enable(m_ch_type->GetSelection() != vfsDevice_LocalFile);
m_btn_select_dev_path->Enable(m_ch_type->GetSelection() != vfsDevice_LocalFile);
}
void VFSEntrySettingsDialog::OnSelectPath(wxCommandEvent& event)
{
wxDirDialog ctrl(this, "Select path", wxGetCwd());
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
m_tctrl_path->SetValue(ctrl.GetPath());
}
void VFSEntrySettingsDialog::OnSelectDevPath(wxCommandEvent& event)
{
wxFileDialog ctrl(this, "Select device");
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
m_tctrl_dev_path->SetValue(ctrl.GetPath());
}
void VFSEntrySettingsDialog::OnOk(wxCommandEvent& event)
{
m_entry.device_path = m_tctrl_dev_path->GetValue();
m_entry.path = m_tctrl_path->GetValue();
m_entry.mount = m_tctrl_mount->GetValue();
m_entry.device = (vfsDeviceType)m_ch_type->GetSelection();
EndModal(wxID_OK);
}
enum
{
id_add,
id_remove,
id_config,
};
VFSManagerDialog::VFSManagerDialog(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "Virtual File System Manager", wxDefaultPosition)
{
m_list = new wxListView(this);
wxBoxSizer& s_main(*new wxBoxSizer(wxVERTICAL));
s_main.Add(m_list, 1, wxEXPAND);
SetSizerAndFit(&s_main);
SetSize(800, 600);
m_list->InsertColumn(0, "Path");
m_list->InsertColumn(1, "Device path");
m_list->InsertColumn(2, "Path to Device");
m_list->InsertColumn(3, "Device");
Connect(m_list->GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxCommandEventHandler(VFSManagerDialog::OnEntryConfig));
Connect(m_list->GetId(), wxEVT_COMMAND_RIGHT_CLICK, wxCommandEventHandler(VFSManagerDialog::OnRightClick));
Connect(id_add, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VFSManagerDialog::OnAdd));
Connect(id_remove, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VFSManagerDialog::OnRemove));
Connect(id_config, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VFSManagerDialog::OnEntryConfig));
Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(VFSManagerDialog::OnClose));
LoadEntries();
UpdateList();
}
void VFSManagerDialog::UpdateList()
{
m_list->Freeze();
m_list->DeleteAllItems();
for(uint i=0; i<m_entries.GetCount(); ++i)
{
m_list->InsertItem(i, m_entries[i].mount.GetPtr());
m_list->SetItem(i, 1, m_entries[i].path.GetPtr());
m_list->SetItem(i, 2, m_entries[i].device_path.GetPtr());
m_list->SetItem(i, 3, vfsDeviceTypeNames[m_entries[i].device]);
}
m_list->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(3, wxLIST_AUTOSIZE_USEHEADER);
m_list->Thaw();
}
void VFSManagerDialog::OnEntryConfig(wxCommandEvent& event)
{
int idx = m_list->GetFirstSelected();
if(idx != wxNOT_FOUND)
{
VFSEntrySettingsDialog(this, m_entries[idx]).ShowModal();
UpdateList();
}
}
void VFSManagerDialog::OnRightClick(wxCommandEvent& event)
{
wxMenu* menu = new wxMenu();
int idx = m_list->GetFirstSelected();
menu->Append(id_add, "Add");
menu->Append(id_remove, "Remove")->Enable(idx != wxNOT_FOUND);
menu->AppendSeparator();
menu->Append(id_config, "Config")->Enable(idx != wxNOT_FOUND);
PopupMenu( menu );
}
void VFSManagerDialog::OnAdd(wxCommandEvent& event)
{
u32 idx = m_entries.Move(new VFSManagerEntry());
UpdateList();
for(int i=0; i<m_list->GetItemCount(); ++i)
{
m_list->SetItemState(i, i == idx ? wxLIST_STATE_SELECTED : ~wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
OnEntryConfig(wxCommandEvent());
}
void VFSManagerDialog::OnRemove(wxCommandEvent& event)
{
for(int sel = m_list->GetNextSelected(-1), offs = 0; sel != wxNOT_FOUND; sel = m_list->GetNextSelected(sel), --offs)
{
m_entries.RemoveAt(sel + offs);
}
UpdateList();
}
void VFSManagerDialog::OnClose(wxCloseEvent& event)
{
SaveEntries();
event.Skip();
}
void VFSManagerDialog::LoadEntries()
{
m_entries.Clear();
Emu.GetVFS().SaveLoadDevices(m_entries, true);
}
void VFSManagerDialog::SaveEntries()
{
Emu.GetVFS().SaveLoadDevices(m_entries, false);
}

39
rpcs3/Gui/VFSManager.h Normal file
View file

@ -0,0 +1,39 @@
#pragma once
class VFSEntrySettingsDialog : public wxDialog
{
wxTextCtrl* m_tctrl_dev_path;
wxButton* m_btn_select_dev_path;
wxTextCtrl* m_tctrl_path;
wxButton* m_btn_select_path;
wxTextCtrl* m_tctrl_mount;
wxChoice* m_ch_type;
VFSManagerEntry& m_entry;
public:
VFSEntrySettingsDialog(wxWindow* parent, VFSManagerEntry& entry);
void OnSelectType(wxCommandEvent& event);
void OnSelectPath(wxCommandEvent& event);
void OnSelectDevPath(wxCommandEvent& event);
void OnOk(wxCommandEvent& event);
};
class VFSManagerDialog : public wxDialog
{
wxListView* m_list;
Array<VFSManagerEntry> m_entries;
public:
VFSManagerDialog(wxWindow* parent);
void UpdateList();
void OnEntryConfig(wxCommandEvent& event);
void OnRightClick(wxCommandEvent& event);
void OnAdd(wxCommandEvent& event);
void OnRemove(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
void LoadEntries();
void SaveEntries();
};

551
rpcs3/Gui/VHDDManager.cpp Normal file
View file

@ -0,0 +1,551 @@
#include "stdafx.h"
#include "VHDDManager.h"
#include "TextInputDialog.h"
#include <wx/busyinfo.h>
VHDDListDropTarget::VHDDListDropTarget(wxListView* parent) : m_parent(parent)
{
SetDataObject(new wxDataObjectSimple(wxDF_PRIVATE));
}
wxDragResult VHDDListDropTarget::OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
{
int flags = 0;
int indx = m_parent->HitTest(wxPoint(x, y), flags);
for(int i=0; i<m_parent->GetItemCount(); ++i)
{
m_parent->SetItemState(i, i == indx ? wxLIST_STATE_SELECTED : ~wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
return def;
}
void VHDDListDropTarget::OnLeave()
{
for(int i=0; i<m_parent->GetItemCount(); ++i)
{
m_parent->SetItemState(i, ~wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
}
wxDragResult VHDDListDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
{
int flags = 0;
int dst_indx = m_parent->HitTest(wxPoint(x, y), flags);
ConLog.Write("OnData(%d -> %d)", m_src_indx, dst_indx);
return def;
}
enum
{
id_open = 0x777,
id_rename,
id_remove,
id_create_dir,
id_create_file,
id_import,
id_export,
id_create_hdd,
id_add_hdd
};
VHDDExplorer::VHDDExplorer(wxWindow* parent, const wxString& hdd_path) : wxDialog(parent, wxID_ANY, "Virtual HDD Explorer", wxDefaultPosition)
{
m_list = new wxListView(this);
m_drop_target = new VHDDListDropTarget(m_list);
m_list->SetDropTarget(m_drop_target);
m_list->DragAcceptFiles(true);
wxBoxSizer& s_main(*new wxBoxSizer(wxVERTICAL));
s_main.Add(m_list, 1, wxEXPAND | wxALL, 5);
SetSizerAndFit(&s_main);
SetSize(800, 600);
m_list->InsertColumn(0, "Name");
m_list->InsertColumn(1, "Type");
m_list->InsertColumn(2, "Size");
m_list->InsertColumn(3, "Creation time");
m_hdd = new vfsHDD(hdd_path);
UpdateList();
Connect(m_list->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(VHDDExplorer::OnListDrag));
Connect(m_list->GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(VHDDExplorer::DClick));
Connect(m_list->GetId(), wxEVT_COMMAND_RIGHT_CLICK, wxCommandEventHandler(VHDDExplorer::OnContextMenu));
m_list->Connect(wxEVT_DROP_FILES, wxDropFilesEventHandler(VHDDExplorer::OnDropFiles), (wxObject*)0, this);
Connect(id_open, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDExplorer::OnOpen));
Connect(id_rename, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDExplorer::OnRename));
Connect(id_remove, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDExplorer::OnRemove));
Connect(id_create_dir, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDExplorer::OnCreateDir));
Connect(id_create_file, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDExplorer::OnCreateFile));
Connect(id_import, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDExplorer::OnImport));
Connect(id_export, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDExplorer::OnExport));
}
void VHDDExplorer::UpdateList()
{
m_list->Freeze();
m_list->DeleteAllItems();
m_entries.Clear();
m_names.Clear();
u64 block;
vfsHDD_Entry entry;
wxString name;
for(bool is_ok = m_hdd->GetFirstEntry(block, entry, name); is_ok; is_ok = m_hdd->GetNextEntry(block, entry, name))
{
int item = m_list->GetItemCount();
m_list->InsertItem(item, name);
m_list->SetItem(item, 1, entry.type == vfsHDD_Entry_Dir ? "Dir" : "File");
m_list->SetItem(item, 2, wxString::Format("%lld", entry.size));
m_list->SetItem(item, 3, wxDateTime().Set(time_t(entry.ctime)).Format());
m_entries.AddCpy(entry);
m_names.Add(name);
}
m_list->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
m_list->SetColumnWidth(3, wxLIST_AUTOSIZE_USEHEADER);
m_list->Thaw();
}
void VHDDExplorer::Import(const wxString& path, const wxString& to)
{
if(!m_hdd->Create(vfsHDD_Entry_File, to))
{
wxMessageBox("IMPORT ERROR: file creation error.");
return;
}
if(!m_hdd->Open(to, vfsWrite))
{
wxMessageBox("IMPORT ERROR: file open error.");
return;
}
wxFile f(path);
char buf[256];
while(!f.Eof())
{
m_hdd->Write(buf, f.Read(buf, 256));
}
m_hdd->Close();
}
void VHDDExplorer::Export(const wxString& path, const wxString& to)
{
if(!m_hdd->Open(path))
{
wxMessageBox(wxString::Format("EXPORT ERROR: file open error. (%s)", path));
return;
}
wxFile f(to, wxFile::write);
char buf[256];
while(u64 size = m_hdd->Read(buf, 256))
{
f.Write(buf, size);
}
}
void VHDDExplorer::OpenDir(int sel)
{
if(sel == wxNOT_FOUND)
{
return;
}
if(m_entries[sel].type == vfsHDD_Entry_Dir)
{
m_hdd->OpenDir(m_names[sel]);
UpdateList();
}
}
void VHDDExplorer::OnListDrag(wxListEvent& event)
{
m_drop_target->SetSrcIndx(event.GetIndex());
wxDataObjectSimple obj(wxDF_PRIVATE);
wxDropSource drag(obj, m_list);
drag.DoDragDrop(wxDrag_AllowMove);
}
void VHDDExplorer::OnDropFiles(wxDropFilesEvent& event)
{
int count = event.GetNumberOfFiles();
wxString* dropped = event.GetFiles();
wxBusyCursor busyCursor;
wxWindowDisabler disabler;
wxBusyInfo busyInfo("Adding files, wait please...");
for(int i=0; i<count; ++i)
{
ConLog.Write("Importing '%s'", dropped[i]);
Import(dropped[i], wxFileName(dropped[i]).GetFullName());
}
UpdateList();
}
void VHDDExplorer::DClick(wxListEvent& event)
{
OpenDir(event.GetIndex());
}
void VHDDExplorer::OnContextMenu(wxCommandEvent& event)
{
wxMenu* menu = new wxMenu();
int idx = m_list->GetFirstSelected();
menu->Append(id_open, "Open")->Enable(idx != wxNOT_FOUND && m_entries[idx].type == vfsHDD_Entry_Dir);
menu->Append(id_rename, "Rename")->Enable(idx != wxNOT_FOUND && m_names[idx] != "." && m_names[idx] != "..");
menu->Append(id_remove, "Remove")->Enable(idx != wxNOT_FOUND && m_names[idx] != "." && m_names[idx] != "..");
menu->AppendSeparator();
menu->Append(id_create_dir, "Create dir");
menu->Append(id_create_file, "Create file");
menu->AppendSeparator();
menu->Append(id_import, "Import");
menu->Append(id_export, "Export")->Enable(idx != wxNOT_FOUND);
PopupMenu( menu );
}
void VHDDExplorer::OnOpen(wxCommandEvent& event)
{
m_hdd->OpenDir(m_names[m_list->GetFirstSelected()]);
UpdateList();
}
void VHDDExplorer::OnRename(wxCommandEvent& event)
{
TextInputDialog dial(this, m_names[m_list->GetFirstSelected()]);
if(dial.ShowModal() == wxID_OK)
{
m_hdd->Rename(m_names[m_list->GetFirstSelected()], dial.GetResult());
UpdateList();
}
}
void VHDDExplorer::OnRemove(wxCommandEvent& event)
{
for(int sel = m_list->GetNextSelected(-1); sel != wxNOT_FOUND; sel = m_list->GetNextSelected(sel))
{
m_hdd->RemoveEntry(m_names[sel]);
}
UpdateList();
}
void VHDDExplorer::OnCreateDir(wxCommandEvent& event)
{
int i = 1;
static const wxString& fmt = "New Dir (%d)";
while(m_hdd->HasEntry(wxString::Format(fmt, i))) i++;
m_hdd->Create(vfsHDD_Entry_Dir, wxString::Format(fmt, i));
UpdateList();
}
void VHDDExplorer::OnCreateFile(wxCommandEvent& event)
{
int i = 1;
static const wxString& fmt = "New File (%d)";
while(m_hdd->HasEntry(wxString::Format(fmt, i))) i++;
m_hdd->Create(vfsHDD_Entry_File, wxString::Format(fmt, i));
UpdateList();
}
void VHDDExplorer::OnImport(wxCommandEvent& event)
{
wxFileDialog ctrl(this, "Select import files", wxEmptyString, wxEmptyString, wxFileSelectorDefaultWildcardStr,
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
wxArrayString paths;
ctrl.GetPaths(paths);
for(size_t i=0; i<paths.GetCount(); ++i)
{
if(wxFileExists(paths[i]))
{
Import(paths[i], wxFileName(paths[i]).GetFullName());
}
}
UpdateList();
}
void VHDDExplorer::OnExport(wxCommandEvent& event)
{
if(m_list->GetSelectedItemCount() > 1)
{
wxDirDialog ctrl(this, "Select export folder", wxGetCwd());
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
for(int sel = m_list->GetNextSelected(-1); sel != wxNOT_FOUND; sel = m_list->GetNextSelected(sel))
{
Export(m_names[sel], ctrl.GetPath() + '\\' + m_names[sel]);
}
}
else
{
int sel = m_list->GetFirstSelected();
wxFileDialog ctrl(this, "Select export file", wxEmptyString, m_names[sel], wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
Export(m_names[sel], ctrl.GetPath());
}
UpdateList();
}
VHDDSetInfoDialog::VHDDSetInfoDialog(wxWindow* parent) : wxDialog(parent, wxID_ANY, "HDD Settings", wxDefaultPosition)
{
m_spin_size = new wxSpinCtrl(this);
m_ch_type = new wxChoice(this, wxID_ANY);
m_spin_block_size = new wxSpinCtrl(this);
wxBoxSizer& s_sinf(*new wxBoxSizer(wxHORIZONTAL));
s_sinf.Add(m_spin_size, wxSizerFlags().Border(wxALL, 5).Expand());
s_sinf.Add(m_ch_type, wxSizerFlags().Border(wxALL, 5).Expand());
wxBoxSizer& s_binf(*new wxBoxSizer(wxHORIZONTAL));
s_binf.Add(m_spin_block_size, wxSizerFlags().Border(wxALL, 5).Expand());
wxBoxSizer& s_btns(*new wxBoxSizer(wxHORIZONTAL));
s_btns.Add(new wxButton(this, wxID_OK), wxSizerFlags().Align(wxALIGN_LEFT).Border(wxALL, 5));
s_btns.Add(new wxButton(this, wxID_CANCEL), wxSizerFlags().Align(wxALIGN_RIGHT).Border(wxALL, 5));
wxBoxSizer& s_main(*new wxBoxSizer(wxVERTICAL));
s_main.Add(&s_sinf, wxSizerFlags().Align(wxALIGN_TOP).Expand());
s_main.Add(&s_binf, wxSizerFlags().Align(wxALIGN_TOP).Expand());
s_main.Add(&s_btns, wxSizerFlags().Align(wxALIGN_BOTTOM).Expand());
SetSizerAndFit(&s_main);
m_ch_type->Append("B");
m_ch_type->Append("KB");
m_ch_type->Append("MB");
m_ch_type->Append("GB");
m_spin_size->SetMin(1);
m_spin_size->SetMax(0x7fffffff);
m_spin_size->SetValue(64);
m_ch_type->SetSelection(3);
m_spin_block_size->SetMin(64);
m_spin_block_size->SetMax(0x7fffffff);
m_spin_block_size->SetValue(2048);
Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(VHDDSetInfoDialog::OnOk));
}
void VHDDSetInfoDialog::OnOk(wxCommandEvent& event)
{
m_res_size = m_spin_size->GetValue();
for(int i=0; i<m_ch_type->GetSelection(); ++i)
{
m_res_size *= 1024;
}
m_res_block_size = m_spin_block_size->GetValue();
EndModal(wxID_OK);
}
void VHDDSetInfoDialog::GetResult(u64& size, u64& block_size)
{
size = m_res_size;
block_size = m_res_block_size;
}
VHDDManagerDialog::VHDDManagerDialog(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "Virtual HDD Manager", wxDefaultPosition)
{
m_list = new wxListView(this);
wxBoxSizer& s_main(*new wxBoxSizer(wxVERTICAL));
s_main.Add(m_list, 1, wxEXPAND | wxALL, 5);
SetSizerAndFit(&s_main);
SetSize(800, 600);
m_list->InsertColumn(0, "Path");
//m_list->InsertColumn(1, "Size");
//m_list->InsertColumn(2, "Block size");
Connect(m_list->GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(VHDDManagerDialog::DClick));
Connect(m_list->GetId(), wxEVT_COMMAND_RIGHT_CLICK, wxCommandEventHandler(VHDDManagerDialog::OnContextMenu));
Connect(id_add_hdd, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDManagerDialog::AddHDD));
Connect(id_open, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDManagerDialog::OnOpen));
Connect(id_remove, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDManagerDialog::OnRemove));
Connect(id_create_hdd, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VHDDManagerDialog::OnCreateHDD));
Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(VHDDManagerDialog::OnClose));
LoadPathes();
UpdateList();
}
void VHDDManagerDialog::UpdateList()
{
m_list->Freeze();
m_list->DeleteAllItems();
for(size_t i=0; i<m_pathes.GetCount(); ++i)
{
m_list->InsertItem(i, m_pathes[i]);
}
m_list->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
//m_list->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
//m_list->SetColumnWidth(2, wxLIST_AUTOSIZE_USEHEADER);
m_list->Thaw();
}
void VHDDManagerDialog::Open(int sel)
{
VHDDExplorer dial(this, m_pathes[sel]);
dial.ShowModal();
}
void VHDDManagerDialog::DClick(wxListEvent& event)
{
Open(event.GetIndex());
}
void VHDDManagerDialog::AddHDD(wxCommandEvent& event)
{
wxFileDialog ctrl(this, "Select HDDs", wxEmptyString, wxEmptyString, "Virtual HDD (*.hdd) | *.hdd",
wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
wxArrayString pathes;
ctrl.GetPaths(pathes);
for(size_t i=0; i<pathes.GetCount(); ++i)
{
bool skip = false;
for(size_t j=0; j<m_pathes.GetCount(); ++j)
{
if(m_pathes[j].CmpNoCase(pathes[i]) == 0)
{
skip = true;
break;
}
}
if(!skip)
{
m_pathes.Move(new wxString(pathes[i].c_str()));
}
}
UpdateList();
}
void VHDDManagerDialog::OnContextMenu(wxCommandEvent& event)
{
wxMenu* menu = new wxMenu();
int idx = m_list->GetFirstSelected();
menu->Append(id_open, "Open")->Enable(idx != wxNOT_FOUND);
menu->Append(id_remove, "Remove")->Enable(idx != wxNOT_FOUND);
menu->AppendSeparator();
menu->Append(id_add_hdd, "Add");
menu->Append(id_create_hdd, "Create");
PopupMenu(menu);
}
void VHDDManagerDialog::OnOpen(wxCommandEvent& event)
{
int idx = m_list->GetFirstSelected();
if(idx >= 0) Open(idx);
}
void VHDDManagerDialog::OnRemove(wxCommandEvent& event)
{
for(int sel = m_list->GetNextSelected(-1), offs = 0; sel != wxNOT_FOUND; sel = m_list->GetNextSelected(sel), --offs)
{
m_pathes.RemoveAt(sel + offs);
}
UpdateList();
}
void VHDDManagerDialog::OnCreateHDD(wxCommandEvent& event)
{
wxFileDialog ctrl(this, "Select HDD path", wxEmptyString, "new_hdd.hdd", "Virtual HDD (*.hdd) | *.hdd",
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if(ctrl.ShowModal() == wxID_CANCEL)
{
return;
}
VHDDSetInfoDialog dial(this);
if(dial.ShowModal() == wxID_OK)
{
u64 size, bsize;
dial.GetResult(size, bsize);
vfsHDDManager::CreateHDD(ctrl.GetPath(), size, bsize);
m_pathes.AddCpy(ctrl.GetPath());
UpdateList();
}
}
void VHDDManagerDialog::OnClose(wxCloseEvent& event)
{
SavePathes();
event.Skip();
}
void VHDDManagerDialog::LoadPathes()
{
IniEntry<int> path_count;
path_count.Init("path_count", "HDDManager");
int count = 0;
count = path_count.LoadValue(count);
m_pathes.SetCount(count);
for(size_t i=0; i<m_pathes.GetCount(); ++i)
{
IniEntry<wxString> path_entry;
path_entry.Init(wxString::Format("path[%d]", i), "HDDManager");
new (m_pathes + i) wxString(path_entry.LoadValue(wxEmptyString));
}
}
void VHDDManagerDialog::SavePathes()
{
IniEntry<int> path_count;
path_count.Init("path_count", "HDDManager");
path_count.SaveValue(m_pathes.GetCount());
for(size_t i=0; i<m_pathes.GetCount(); ++i)
{
IniEntry<wxString> path_entry;
path_entry.Init(wxString::Format("path[%d]", i), "HDDManager");
path_entry.SaveValue(m_pathes[i]);
}
}

87
rpcs3/Gui/VHDDManager.h Normal file
View file

@ -0,0 +1,87 @@
#pragma once
#include <wx/dnd.h>
#include "Emu/HDD/HDD.h"
class VHDDListDropTarget : public wxDropTarget
{
wxListView* m_parent;
int m_src_indx;
public:
VHDDListDropTarget(wxListView* parent);
virtual wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def);
virtual void OnLeave();
virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def);
void SetSrcIndx(int src_indx)
{
m_src_indx = src_indx;
}
};
class VHDDExplorer : public wxDialog
{
Array<vfsHDD_Entry> m_entries;
wxArrayString m_names;
wxListView* m_list;
vfsHDD* m_hdd;
VHDDListDropTarget* m_drop_target;
public:
VHDDExplorer(wxWindow* parent, const wxString& hdd_path);
void UpdateList();
void Import(const wxString& path, const wxString& to);
void Export(const wxString& path, const wxString& to);
void OnListDrag(wxListEvent& event);
void OnDropFiles(wxDropFilesEvent& event);
void OpenDir(int sel);
void DClick(wxListEvent& event);
void OnContextMenu(wxCommandEvent& event);
void OnOpen(wxCommandEvent& event);
void OnRename(wxCommandEvent& event);
void OnRemove(wxCommandEvent& event);
void OnCreateDir(wxCommandEvent& event);
void OnCreateFile(wxCommandEvent& event);
void OnImport(wxCommandEvent& event);
void OnExport(wxCommandEvent& event);
};
class VHDDSetInfoDialog : public wxDialog
{
wxSpinCtrl* m_spin_size;
wxChoice* m_ch_type;
wxSpinCtrl* m_spin_block_size;
u64 m_res_size;
u64 m_res_block_size;
public:
VHDDSetInfoDialog(wxWindow* parent);
void OnOk(wxCommandEvent& event);
void GetResult(u64& size, u64& block_size);
};
class VHDDManagerDialog : public wxDialog
{
Array<wxString> m_pathes;
wxListView* m_list;
public:
VHDDManagerDialog(wxWindow* parent);
void UpdateList();
void Open(int sel);
void DClick(wxListEvent& event);
void AddHDD(wxCommandEvent& event);
void OnContextMenu(wxCommandEvent& event);
void OnOpen(wxCommandEvent& event);
void OnRemove(wxCommandEvent& event);
void OnCreateHDD(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
void LoadPathes();
void SavePathes();
};

View file

@ -7,7 +7,12 @@ Inis Ini;
static bool StringToBool(const wxString str)
{
if(!str.CmpNoCase("enable") || !str.CmpNoCase("e") || !str.CmpNoCase("1"))
if(
!str.CmpNoCase("enable") ||
!str.CmpNoCase("e") ||
!str.CmpNoCase("1") ||
!str.CmpNoCase("true") ||
!str.CmpNoCase("t") )
{
return true;
}

View file

@ -176,7 +176,7 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
break;
}
if(note.descsz < sizeof(note.desc))
if(note.descsz != sizeof(note.desc) && note.descsz != 32)
{
ConLog.Error("ELF32: Bad NOTE descsz (%d)", note.descsz);
break;
@ -188,9 +188,16 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
// break;
//}
ConLog.Warning("name = %s", note.name);
ConLog.Warning("ls_size = %d", note.desc.ls_size);
ConLog.Warning("stack_size = %d", note.desc.stack_size);
if(note.descsz == sizeof(note.desc))
{
ConLog.Warning("name = %s", note.name);
ConLog.Warning("ls_size = %d", note.desc.ls_size);
ConLog.Warning("stack_size = %d", note.desc.stack_size);
}
else
{
ConLog.Warning("desc = '%s'", note.desc_text);
}
}
#ifdef LOADER_DEBUG
ConLog.SkipLn();

View file

@ -97,7 +97,11 @@ struct Elf32_Note
u32 descsz;
u32 type;
u8 name[8];
Elf32_Desc desc;
union
{
Elf32_Desc desc;
char desc_text[32];
};
void Load(vfsStream& f)
{
@ -105,7 +109,15 @@ struct Elf32_Note
descsz = Read32(f);
type = Read32(f);
f.Read(name, 8);
desc.Load(f);
if(descsz == 32)
{
f.Read(desc_text, descsz);
}
else
{
desc.Load(f);
}
}
};

View file

@ -339,7 +339,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset)
Module* module = GetModuleByName(module_name);
if(module)
{
module->SetLoaded();
//module->SetLoaded();
}
else
{

View file

@ -22,15 +22,7 @@ bool Rpcs3App::OnInit()
SetTopWindow(m_MainFrame);
Emu.Init();
try
{
(new CompilerELF(m_MainFrame))->Show();
}
catch(...)
{
ConLog.Warning("CompilerELF is broken.");
}
(new CompilerELF(m_MainFrame))->Show();
m_debugger_frame = new DebuggerPanel(m_MainFrame);
ConLogFrame = new LogFrame(m_MainFrame);

View file

@ -57,7 +57,7 @@ public:
MainFrame* m_MainFrame;
DebuggerPanel* m_debugger_frame;
virtual bool OnInit();
virtual bool OnInit();
virtual void Exit();
void SendDbgCommand(DbgCommand id, PPCThread* thr=nullptr);

View file

@ -197,6 +197,7 @@
<ItemGroup>
<ClCompile Include="..\Utilities\Thread.cpp" />
<ClCompile Include="AppConnector.cpp" />
<ClCompile Include="Emu\Cell\MFC.cpp" />
<ClCompile Include="Emu\Cell\PPCThread.cpp" />
<ClCompile Include="Emu\Cell\PPCThreadManager.cpp" />
<ClCompile Include="Emu\Cell\PPUProgramCompiler.cpp" />
@ -220,6 +221,7 @@
<ClCompile Include="Emu\GS\GSManager.cpp" />
<ClCompile Include="Emu\GS\GSRender.cpp" />
<ClCompile Include="Emu\GS\RSXThread.cpp" />
<ClCompile Include="Emu\HDD\HDD.cpp" />
<ClCompile Include="Emu\Io\Pad.cpp" />
<ClCompile Include="Emu\Memory\Memory.cpp" />
<ClCompile Include="Emu\SysCalls\Callback.cpp" />
@ -258,6 +260,9 @@
<ClCompile Include="Gui\InterpreterDisAsm.cpp" />
<ClCompile Include="Gui\MainFrame.cpp" />
<ClCompile Include="Gui\MemoryViewer.cpp" />
<ClCompile Include="Gui\TextInputDialog.cpp" />
<ClCompile Include="Gui\VFSManager.cpp" />
<ClCompile Include="Gui\VHDDManager.cpp" />
<ClCompile Include="Ini.cpp" />
<ClCompile Include="Loader\ELF.cpp" />
<ClCompile Include="Loader\ELF32.cpp" />

View file

@ -44,6 +44,9 @@
<Filter Include="Emu\SysCalls\Modules">
<UniqueIdentifier>{dfd581c4-aed0-4229-bb30-7ee5816049e1}</UniqueIdentifier>
</Filter>
<Filter Include="Emu\HDD">
<UniqueIdentifier>{718bc358-b7ef-4988-8547-2148d14bb08b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="rpcs3.cpp">
@ -262,6 +265,21 @@
<ClCompile Include="Emu\Cell\RawSPUThread.cpp">
<Filter>Emu\CPU</Filter>
</ClCompile>
<ClCompile Include="Emu\Cell\MFC.cpp">
<Filter>Emu\CPU</Filter>
</ClCompile>
<ClCompile Include="Emu\HDD\HDD.cpp">
<Filter>Emu\HDD</Filter>
</ClCompile>
<ClCompile Include="Gui\VHDDManager.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="Gui\VFSManager.cpp">
<Filter>Gui</Filter>
</ClCompile>
<ClCompile Include="Gui\TextInputDialog.cpp">
<Filter>Gui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="rpcs3.rc" />