mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
- Implemented HDD manager.
- Implemented VFS manager. - Implemented MFC. - Fixed ELF Compiler. - Improved HLE Func binder.
This commit is contained in:
parent
559852a8fc
commit
81e874c9e2
52 changed files with 2684 additions and 468 deletions
|
@ -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
2
rpcs3/Emu/Cell/MFC.cpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include "stdafx.h"
|
||||
#include "MFC.h"
|
252
rpcs3/Emu/Cell/MFC.h
Normal file
252
rpcs3/Emu/Cell/MFC.h
Normal 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);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
};
|
|
@ -40,4 +40,4 @@ wxString vfsFileBase::GetPath() const
|
|||
vfsOpenMode vfsFileBase::GetOpenMode() const
|
||||
{
|
||||
return m_mode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,4 +21,4 @@ public:
|
|||
*/
|
||||
wxString GetPath() const;
|
||||
vfsOpenMode GetOpenMode() const;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -92,4 +92,4 @@ u64 vfsLocalFile::Tell() const
|
|||
bool vfsLocalFile::IsOpened() const
|
||||
{
|
||||
return m_file.IsOpened() && vfsFileBase::IsOpened();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1375,5 +1375,5 @@ void GLGSRender::Init()
|
|||
|
||||
void GLGSRender::CloseOpenGL()
|
||||
{
|
||||
Reset();
|
||||
//Reset();
|
||||
}
|
3
rpcs3/Emu/HDD/HDD.cpp
Normal file
3
rpcs3/Emu/HDD/HDD.cpp
Normal file
|
@ -0,0 +1,3 @@
|
|||
#include "stdafx.h"
|
||||
#include "HDD.h"
|
||||
|
864
rpcs3/Emu/HDD/HDD.h
Normal file
864
rpcs3/Emu/HDD/HDD.h
Normal 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();
|
||||
}
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ protected:
|
|||
|
||||
public:
|
||||
MemoryBlock();
|
||||
~MemoryBlock();
|
||||
virtual ~MemoryBlock();
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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; //?
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
37
rpcs3/Gui/TextInputDialog.cpp
Normal file
37
rpcs3/Gui/TextInputDialog.cpp
Normal 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;
|
||||
}
|
13
rpcs3/Gui/TextInputDialog.h
Normal file
13
rpcs3/Gui/TextInputDialog.h
Normal 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
219
rpcs3/Gui/VFSManager.cpp
Normal 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
39
rpcs3/Gui/VFSManager.h
Normal 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
551
rpcs3/Gui/VHDDManager.cpp
Normal 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
87
rpcs3/Gui/VHDDManager.h
Normal 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();
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset)
|
|||
Module* module = GetModuleByName(module_name);
|
||||
if(module)
|
||||
{
|
||||
module->SetLoaded();
|
||||
//module->SetLoaded();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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" />
|
||||
|
|
Loading…
Add table
Reference in a new issue