diff --git a/Utilities/Array.h b/Utilities/Array.h index c672ef4fe6..02c80417c8 100644 --- a/Utilities/Array.h +++ b/Utilities/Array.h @@ -2,6 +2,7 @@ template 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) 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 +{ +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 struct Stack : public Array { Stack() : Array() diff --git a/rpcs3/Emu/Cell/MFC.cpp b/rpcs3/Emu/Cell/MFC.cpp new file mode 100644 index 0000000000..f63341b79c --- /dev/null +++ b/rpcs3/Emu/Cell/MFC.cpp @@ -0,0 +1,2 @@ +#include "stdafx.h" +#include "MFC.h" diff --git a/rpcs3/Emu/Cell/MFC.h b/rpcs3/Emu/Cell/MFC.h new file mode 100644 index 0000000000..0ab2b35fee --- /dev/null +++ b/rpcs3/Emu/Cell/MFC.h @@ -0,0 +1,252 @@ +#pragma once +#include + +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 +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 queue_pos; + std::atomic 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); + } + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/Cell/PPUProgramCompiler.cpp b/rpcs3/Emu/Cell/PPUProgramCompiler.cpp index 8733ab4a36..c645a2cf7f 100644 --- a/rpcs3/Emu/Cell/PPUProgramCompiler.cpp +++ b/rpcs3/Emu/Cell/PPUProgramCompiler.cpp @@ -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= 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> 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); diff --git a/rpcs3/Emu/Cell/PPUProgramCompiler.h b/rpcs3/Emu/Cell/PPUProgramCompiler.h index b86d4f7a3e..23b92e43d6 100644 --- a/rpcs3/Emu/Cell/PPUProgramCompiler.h +++ b/rpcs3/Emu/Cell/PPUProgramCompiler.h @@ -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 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) diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index e10f97d6dc..370550cea7 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -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)); diff --git a/rpcs3/Emu/Cell/RawSPUThread.h b/rpcs3/Emu/Cell/RawSPUThread.h index d95bb702c6..829f87878f 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.h +++ b/rpcs3/Emu/Cell/RawSPUThread.h @@ -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(); diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 293f5a32a1..d34c42512f 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -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(); } diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index c311dfef28..26775a6ec9 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -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 - 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 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); diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index 3aa909ffd6..86e1e87b7d 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -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 entries; + SaveLoadDevices(entries, true); + + for(uint i=0; i& res, bool is_load) +{ + IniEntry 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 entry_path; + IniEntry entry_device_path; + IniEntry entry_mount; + IniEntry 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); + } + } +} \ No newline at end of file diff --git a/rpcs3/Emu/FS/VFS.h b/rpcs3/Emu/FS/VFS.h index 75e0f2dc49..798e951142 100644 --- a/rpcs3/Emu/FS/VFS.h +++ b/rpcs3/Emu/FS/VFS.h @@ -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 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& res, bool is_load); }; \ No newline at end of file diff --git a/rpcs3/Emu/FS/vfsDevice.cpp b/rpcs3/Emu/FS/vfsDevice.cpp index 1560fa647b..2a05018c11 100644 --- a/rpcs3/Emu/FS/vfsDevice.cpp +++ b/rpcs3/Emu/FS/vfsDevice.cpp @@ -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(); } \ No newline at end of file diff --git a/rpcs3/Emu/FS/vfsDevice.h b/rpcs3/Emu/FS/vfsDevice.h index 47e7269dc5..a0545b113b 100644 --- a/rpcs3/Emu/FS/vfsDevice.h +++ b/rpcs3/Emu/FS/vfsDevice.h @@ -1,19 +1,23 @@ #pragma once #include "vfsStream.h" +#include 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(); + } }; \ No newline at end of file diff --git a/rpcs3/Emu/FS/vfsFileBase.cpp b/rpcs3/Emu/FS/vfsFileBase.cpp index 5606491d37..ed4afc0b1b 100644 --- a/rpcs3/Emu/FS/vfsFileBase.cpp +++ b/rpcs3/Emu/FS/vfsFileBase.cpp @@ -40,4 +40,4 @@ wxString vfsFileBase::GetPath() const vfsOpenMode vfsFileBase::GetOpenMode() const { return m_mode; -} \ No newline at end of file +} diff --git a/rpcs3/Emu/FS/vfsFileBase.h b/rpcs3/Emu/FS/vfsFileBase.h index 0b33913dc2..da776df4ec 100644 --- a/rpcs3/Emu/FS/vfsFileBase.h +++ b/rpcs3/Emu/FS/vfsFileBase.h @@ -21,4 +21,4 @@ public: */ wxString GetPath() const; vfsOpenMode GetOpenMode() const; -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/FS/vfsLocalFile.cpp b/rpcs3/Emu/FS/vfsLocalFile.cpp index 244cb68e8a..ec30d24ed0 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.cpp +++ b/rpcs3/Emu/FS/vfsLocalFile.cpp @@ -92,4 +92,4 @@ u64 vfsLocalFile::Tell() const bool vfsLocalFile::IsOpened() const { return m_file.IsOpened() && vfsFileBase::IsOpened(); -} \ No newline at end of file +} diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index a2da8e5a7b..4f1cd9973a 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -1375,5 +1375,5 @@ void GLGSRender::Init() void GLGSRender::CloseOpenGL() { - Reset(); + //Reset(); } \ No newline at end of file diff --git a/rpcs3/Emu/HDD/HDD.cpp b/rpcs3/Emu/HDD/HDD.cpp new file mode 100644 index 0000000000..00f20832bd --- /dev/null +++ b/rpcs3/Emu/HDD/HDD.cpp @@ -0,0 +1,3 @@ +#include "stdafx.h" +#include "HDD.h" + diff --git a/rpcs3/Emu/HDD/HDD.h b/rpcs3/Emu/HDD/HDD.h new file mode 100644 index 0000000000..58438a6a4e --- /dev/null +++ b/rpcs3/Emu/HDD/HDD.h @@ -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= 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(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(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(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(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(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(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(); + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 0d56b45863..312ae36c91 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -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; } diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index 05cfbc1f18..63687f4a38 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -36,7 +36,7 @@ protected: public: MemoryBlock(); - ~MemoryBlock(); + virtual ~MemoryBlock(); private: void Init(); diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index 1fe792894f..0dbc923703 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -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"); diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index a32b6d4ac4..9e3c98bb2f 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -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"}, diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index d3678e4ea0..b6b98b0e68 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -65,9 +65,11 @@ public: template bool CheckId(u32 id, T*& data); u32 GetNewId(void* data = nullptr, u8 flags = 0); - __forceinline void Module::AddFunc(u32 id, func_caller* func) + + template + __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))); } }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index ae7eb0746e..ba4990e08b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -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); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp index fb7bb2e3c7..3f18a17da7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp @@ -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); } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 42a0f50e17..ab26b6d773 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -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); } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 56bd3ccc9c..c4d4736cff 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -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); } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp index f01c950d8d..385f5c99d1 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp @@ -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); } diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 6adafdddf0..2692ccc9b9 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -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 diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 554f8992e8..8553cc0d86 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -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); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp index fe0cf1de46..29b5c28aaf 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp @@ -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; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp index fb2461e7c0..b18323c1a1 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp @@ -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; +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp index e7e2c41fe3..65e98f195c 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp @@ -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 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; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index 81d3925fc3..5ecad4f566 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -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; //? diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 76ad909a66..eed635de4b 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -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(); diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 0a6b1c435f..0825fecdc8 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -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 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(); diff --git a/rpcs3/Gui/MainFrame.h b/rpcs3/Gui/MainFrame.h index b7e479a324..955a160fda 100644 --- a/rpcs3/Gui/MainFrame.h +++ b/rpcs3/Gui/MainFrame.h @@ -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); diff --git a/rpcs3/Gui/TextInputDialog.cpp b/rpcs3/Gui/TextInputDialog.cpp new file mode 100644 index 0000000000..619bcf57c4 --- /dev/null +++ b/rpcs3/Gui/TextInputDialog.cpp @@ -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; +} \ No newline at end of file diff --git a/rpcs3/Gui/TextInputDialog.h b/rpcs3/Gui/TextInputDialog.h new file mode 100644 index 0000000000..cb4cf0ab52 --- /dev/null +++ b/rpcs3/Gui/TextInputDialog.h @@ -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(); +}; \ No newline at end of file diff --git a/rpcs3/Gui/VFSManager.cpp b/rpcs3/Gui/VFSManager.cpp new file mode 100644 index 0000000000..cfd82c446d --- /dev/null +++ b/rpcs3/Gui/VFSManager.cpp @@ -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; iInsertItem(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; iGetItemCount(); ++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); +} \ No newline at end of file diff --git a/rpcs3/Gui/VFSManager.h b/rpcs3/Gui/VFSManager.h new file mode 100644 index 0000000000..e46f4911af --- /dev/null +++ b/rpcs3/Gui/VFSManager.h @@ -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 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(); +}; \ No newline at end of file diff --git a/rpcs3/Gui/VHDDManager.cpp b/rpcs3/Gui/VHDDManager.cpp new file mode 100644 index 0000000000..367b144c6f --- /dev/null +++ b/rpcs3/Gui/VHDDManager.cpp @@ -0,0 +1,551 @@ +#include "stdafx.h" +#include "VHDDManager.h" +#include "TextInputDialog.h" +#include + +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; iGetItemCount(); ++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; iGetItemCount(); ++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; iGetFirstSelected(); + + 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; iGetSelectedItemCount() > 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; iGetSelection(); ++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; iInsertItem(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; iGetFirstSelected(); + 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 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 path_entry; + path_entry.Init(wxString::Format("path[%d]", i), "HDDManager"); + new (m_pathes + i) wxString(path_entry.LoadValue(wxEmptyString)); + } +} + +void VHDDManagerDialog::SavePathes() +{ + IniEntry path_count; + path_count.Init("path_count", "HDDManager"); + path_count.SaveValue(m_pathes.GetCount()); + + for(size_t i=0; i path_entry; + path_entry.Init(wxString::Format("path[%d]", i), "HDDManager"); + path_entry.SaveValue(m_pathes[i]); + } +} \ No newline at end of file diff --git a/rpcs3/Gui/VHDDManager.h b/rpcs3/Gui/VHDDManager.h new file mode 100644 index 0000000000..744760f27e --- /dev/null +++ b/rpcs3/Gui/VHDDManager.h @@ -0,0 +1,87 @@ +#pragma once +#include +#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 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 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(); +}; diff --git a/rpcs3/Ini.cpp b/rpcs3/Ini.cpp index d141b5bc4a..05a4ed6fb8 100644 --- a/rpcs3/Ini.cpp +++ b/rpcs3/Ini.cpp @@ -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; } diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 99951b8515..74bb8a3112 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -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(); diff --git a/rpcs3/Loader/ELF32.h b/rpcs3/Loader/ELF32.h index 5657eb7d27..586d5f4bb9 100644 --- a/rpcs3/Loader/ELF32.h +++ b/rpcs3/Loader/ELF32.h @@ -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); + } } }; diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index c49eb4b384..70f89523aa 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -339,7 +339,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset) Module* module = GetModuleByName(module_name); if(module) { - module->SetLoaded(); + //module->SetLoaded(); } else { diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index 8222acffc0..f716e8b532 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -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); diff --git a/rpcs3/rpcs3.h b/rpcs3/rpcs3.h index 4f3a4649d4..533118cb92 100644 --- a/rpcs3/rpcs3.h +++ b/rpcs3/rpcs3.h @@ -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); diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 271eebaa2a..f65f9194e6 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -197,6 +197,7 @@ + @@ -220,6 +221,7 @@ + @@ -258,6 +260,9 @@ + + + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index b9bee6158c..728fc0fe06 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -44,6 +44,9 @@ {dfd581c4-aed0-4229-bb30-7ee5816049e1} + + {718bc358-b7ef-4988-8547-2148d14bb08b} + @@ -262,6 +265,21 @@ Emu\CPU + + Emu\CPU + + + Emu\HDD + + + Gui + + + Gui + + + Gui +