From 5ce57e963f6a0f89d01434b0319c5a17f3cc3069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Fri, 29 Nov 2013 05:56:26 +0100 Subject: [PATCH] New functions & Minor changes * cellGameBootCheck, cellSysutilGetSystemParamString partially implemented. * Improved debug SELF loader (I applied DH's changes over another part of code that Hykem wrote). * Added checkbox in the Config>Settings menu to ignore Read/Write errors (disabled by default). * Minor issues. --- rpcs3/Emu/GS/GL/GLGSRender.cpp | 4 +- rpcs3/Emu/Memory/Memory.cpp | 30 ++++++---- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 49 +++++++++++++++- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 31 +++++++++++ rpcs3/Emu/SysCalls/SysCalls.cpp | 2 +- rpcs3/Gui/MainFrame.cpp | 65 +++++++++++----------- rpcs3/Ini.h | 4 ++ 7 files changed, 137 insertions(+), 48 deletions(-) diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 284c9fc52e..21074093bd 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -915,9 +915,9 @@ void GLGSRender::ExecCMD() if(m_set_depth_bounds) { - //ConLog.Warning("glDepthRange(%f, %f)", m_depth_bounds_min, m_depth_bounds_max); + //ConLog.Warning("glDepthBounds(%f, %f)", m_depth_bounds_min, m_depth_bounds_max); glDepthBounds(m_depth_bounds_min, m_depth_bounds_max); - checkForGlError("glDepthRange"); + checkForGlError("glDepthBounds"); } if(m_set_clip) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 8eb88cb3f5..d9e7f0bd4f 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -332,70 +332,80 @@ bool MemoryBlockLE::Write128(const u64 addr, const u128 value) bool NullMemoryBlock::Read8(const u64 addr, u8* ) { ConLog.Error("Read8 from null block: [%08llx]", addr); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } bool NullMemoryBlock::Read16(const u64 addr, u16* ) { ConLog.Error("Read16 from null block: [%08llx]", addr); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } bool NullMemoryBlock::Read32(const u64 addr, u32* ) { ConLog.Error("Read32 from null block: [%08llx]", addr); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } bool NullMemoryBlock::Read64(const u64 addr, u64* ) { ConLog.Error("Read64 from null block: [%08llx]", addr); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } bool NullMemoryBlock::Read128(const u64 addr, u128* ) { ConLog.Error("Read128 from null block: [%08llx]", addr); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } bool NullMemoryBlock::Write8(const u64 addr, const u8 value) { ConLog.Error("Write8 to null block: [%08llx]: %x", addr, value); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } bool NullMemoryBlock::Write16(const u64 addr, const u16 value) { ConLog.Error("Write16 to null block: [%08llx]: %x", addr, value); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } bool NullMemoryBlock::Write32(const u64 addr, const u32 value) { ConLog.Error("Write32 to null block: [%08llx]: %x", addr, value); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } bool NullMemoryBlock::Write64(const u64 addr, const u64 value) { ConLog.Error("Write64 to null block: [%08llx]: %llx", addr, value); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } bool NullMemoryBlock::Write128(const u64 addr, const u128 value) { ConLog.Error("Write128 to null block: [%08llx]: %llx_%llx", addr, value.hi, value.lo); - Emu.Pause(); + if (!Ini.CPUIgnoreRWErrors.GetValue()) + Emu.Pause(); return false; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 0fcec5e42b..2b8c47f63e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -31,6 +31,32 @@ enum CELL_GAME_ERROR_BOOTPATH = 0x8002cb50, }; +// Definitions +enum +{ + CELL_GAME_PATH_MAX = 128, + CELL_GAME_DIRNAME_SIZE = 32, + CELL_GAME_THEMEFILENAME_SIZE = 48, + CELL_GAME_SYSP_TITLE_SIZE = 128, + CELL_GAME_SYSP_TITLEID_SIZE = 10, + CELL_GAME_SYSP_VERSION_SIZE = 6, + CELL_GAME_SYSP_APP_VER_SIZE = 6, + + CELL_GAME_GAMETYPE_DISC = 1, + CELL_GAME_GAMETYPE_HDD = 2, + + CELL_GAME_SIZEKB_NOTCALC = -1, + + CELL_GAME_ATTRIBUTE_PATCH = 0x1, + CELL_GAME_ATTRIBUTE_APP_HOME = 0x2, + CELL_GAME_ATTRIBUTE_DEBUG = 0x4, + CELL_GAME_ATTRIBUTE_XMBBUY = 0x8, + CELL_GAME_ATTRIBUTE_COMMERCE2_BROWSER = 0x10, + CELL_GAME_ATTRIBUTE_INVITE_MESSAGE = 0x20, + CELL_GAME_ATTRIBUTE_CUSTOM_DATA_MESSAGE = 0x40, + CELL_GAME_ATTRIBUTE_WEB_BROWSER = 0x100, +}; + //Parameter IDs of PARAM.SFO enum { @@ -66,9 +92,28 @@ enum CELL_GAME_PARAMID_APP_VER = 106, }; -int cellGameBootCheck() +struct CellGameContentSize { - UNIMPLEMENTED_FUNC(cellGame); + be_t hddFreeSizeKB; + be_t sizeKB; + be_t sysSizeKB; +}; + +int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t size, mem_list_ptr_t dirName) +{ + cellGame.Warning("cellGameBootCheck(type_addr=0x%x, attributes_addr=0x%x, size_addr=0x%x, dirName_addr=0x%x)", + type.GetAddr(), attributes.GetAddr(), size.GetAddr(), dirName.GetAddr()); + + if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood()) + return CELL_GAME_ERROR_PARAM; + + type = CELL_GAME_GAMETYPE_DISC; + attributes = 0; + size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run. + size->sizeKB = CELL_GAME_SIZEKB_NOTCALC; + size->sysSizeKB = 0; + //TODO: dirName + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 3ff0351403..46ff1d3965 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -2,8 +2,10 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" +// Parameter IDs enum { + //Integers CELL_SYSUTIL_SYSTEMPARAM_ID_LANG = 0x0111, CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN = 0x0112, CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT = 0x0114, @@ -19,6 +21,10 @@ enum CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD = 0x0154, CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD = 0x0155, CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF = 0x0156, + + //Strings + CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME = 0x113, + CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME = 0x131, }; enum @@ -218,6 +224,30 @@ int cellSysutilGetSystemParamInt(int id, mem32_t value) return CELL_OK; } +int cellSysutilGetSystemParamString(s32 id, mem_list_ptr_t buf, u32 bufsize) +{ + cellSysutil.Log("cellSysutilGetSystemParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.GetAddr(), bufsize); + + if (!buf.IsGood()) + return CELL_EFAULT; + + switch(id) + { + case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: + cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME"); + break; + + case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: + cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME"); + break; + + default: + return CELL_EINVAL; + } + + return CELL_OK; +} + int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr) { cellSysutil.Log("cellVideoOutGetState(videoOut=0x%x, deviceIndex=0x%x, state_addr=0x%x)", videoOut, deviceIndex, state_addr); @@ -484,6 +514,7 @@ int cellMsgDialogOpen2(u32 type, u32 msgString_addr, u32 callback_addr, u32 user void cellSysutil_init() { cellSysutil.AddFunc(0x40e895d3, cellSysutilGetSystemParamInt); + cellSysutil.AddFunc(0x938013a0, cellSysutilGetSystemParamString); cellSysutil.AddFunc(0x887572d5, cellVideoOutGetState); cellSysutil.AddFunc(0xe558748d, cellVideoOutGetResolution); diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 88fa4ae462..6cbc20a907 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -74,7 +74,7 @@ static func_caller* sc_table[1024] = bind_func(sys_cond_wait), //107 (0x06B) bind_func(sys_cond_signal), //108 (0x06C) bind_func(sys_cond_signal_all), //109 (0x06D) - null_func, null_func, null_func, null_func, //110 (0x06E) + null_func, null_func, null_func, null_func, //113 (0x071) bind_func(sys_semaphore_get_value), //114 (0x072) null_func, null_func, null_func, null_func, null_func, //119 (0x077) bind_func(sys_rwlock_create), //120 (0x078) diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index c5d4f5a3c6..75c5993a9f 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -190,56 +190,51 @@ void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event)) wxString fileOut = (ctrl.GetPath()+elf[i])+".elf"; // Check if the data really needs to be decrypted. - FILE *f; - if((f = fopen(fileIn.mb_str(), "rb")) == NULL) + if(!wxFileExists(fileIn)) { ConLog.Error("Could not open game boot file!"); return; } + wxFile f(fileIn); // Get the key version. - fseek(f, 0x08, SEEK_SET); - s16 key_version; - fread(&key_version, 1, sizeof(key_version), f); - be_t key_version_be; - key_version_be.FromLE(key_version); + f.Seek(0x08); + be_t key_version; + f.Read(&key_version, sizeof(key_version)); - // Get the real elf offset. - fseek(f, 0x10, SEEK_SET); - s64 elf_offset; - fread(&elf_offset, 1, sizeof(elf_offset), f); - be_t elf_offset_be; - elf_offset_be.FromLE(elf_offset); - - fclose(f); - - if(key_version_be.ToBE() == 0x8000) + if(key_version.ToBE() == const_se_t::value) { ConLog.Warning("Debug SELF detected! Removing fake header..."); - FILE *in; - FILE *out; - in = fopen(fileIn, "rb"); - out = fopen(fileOut, "wb"); + + // Get the real elf offset. + f.Seek(0x10); + be_t elf_offset; + f.Read(&elf_offset, sizeof(elf_offset)); // Start at the real elf offset. - fseek(in, elf_offset_be.ToBE(), SEEK_SET); - - // Copy the data. - int c; - while ((c = fgetc(in)) != EOF) - fputc(c, out); + f.Seek(elf_offset); - fclose(out); - fclose(in); + wxFile out(fileOut, wxFile::write); + + // Copy the data. + char buf[2048]; + while (ssize_t size = f.Read(buf, 2048)) + out.Write(buf, size); } else { - scetool_decrypt((scetool::s8 *)fileIn.mb_str(), (scetool::s8 *)fileOut.mb_str()); + if (!scetool_decrypt((scetool::s8 *)fileIn.mb_str(), (scetool::s8 *)fileOut.mb_str())) + { + ConLog.Write("Could not decrypt game boot file"); + return; + } } - - Emu.SetPath((ctrl.GetPath()+elf[i])+".elf"); + + f.Close(); + + Emu.SetPath(fileOut); Emu.Load(); - if (!wxRemoveFile((ctrl.GetPath()+elf[i])+".elf")) + if (!wxRemoveFile(fileOut)) ConLog.Warning("Could not delete the decrypted ELF file"); ConLog.Write("Game: boot done."); @@ -463,6 +458,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) wxComboBox* cbox_keyboard_handler = new wxComboBox(&diag, wxID_ANY); wxComboBox* cbox_mouse_handler = new wxComboBox(&diag, wxID_ANY); + wxCheckBox* chbox_cpu_ignore_rwerrors = new wxCheckBox(&diag, wxID_ANY, "Ignore Read/Write errors"); wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(&diag, wxID_ANY, "Dump Depth Buffer"); wxCheckBox* chbox_gs_dump_color = new wxCheckBox(&diag, wxID_ANY, "Dump Color Buffers"); wxCheckBox* chbox_gs_vsync = new wxCheckBox(&diag, wxID_ANY, "VSync"); @@ -495,6 +491,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) cbox_mouse_handler->Append("Windows"); //cbox_mouse_handler->Append("DirectInput"); + chbox_cpu_ignore_rwerrors->SetValue(Ini.CPUIgnoreRWErrors.GetValue()); chbox_gs_dump_depth->SetValue(Ini.GSDumpDepthBuffer.GetValue()); chbox_gs_dump_color->SetValue(Ini.GSDumpColorBuffers.GetValue()); chbox_gs_vsync->SetValue(Ini.GSVSyncEnable.GetValue()); @@ -509,6 +506,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) s_round_cpu_decoder->Add(cbox_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); s_round_cpu->Add(s_round_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_cpu->Add(chbox_cpu_ignore_rwerrors, wxSizerFlags().Border(wxALL, 5).Expand()); s_round_gs_render->Add(cbox_gs_render, wxSizerFlags().Border(wxALL, 5).Expand()); s_round_gs_res->Add(cbox_gs_resolution, wxSizerFlags().Border(wxALL, 5).Expand()); @@ -548,6 +546,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) if(diag.ShowModal() == wxID_OK) { Ini.CPUDecoderMode.SetValue(cbox_cpu_decoder->GetSelection() + 1); + Ini.CPUIgnoreRWErrors.SetValue(chbox_cpu_ignore_rwerrors->GetValue()); Ini.GSRenderMode.SetValue(cbox_gs_render->GetSelection()); Ini.GSResolution.SetValue(ResolutionNumToId(cbox_gs_resolution->GetSelection() + 1)); Ini.GSAspectRatio.SetValue(cbox_gs_aspect->GetSelection() + 1); diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index 917498f8f7..dcbfb4f0fb 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -93,6 +93,7 @@ private: public: IniEntry CPUDecoderMode; + IniEntry CPUIgnoreRWErrors; IniEntry GSRenderMode; IniEntry GSResolution; IniEntry GSAspectRatio; @@ -110,6 +111,7 @@ public: path = DefPath + "\\" + "CPU"; CPUDecoderMode.Init("DecoderMode", path); + CPUIgnoreRWErrors.Init("IgnoreRWErrors", path); path = DefPath + "\\" + "GS"; GSRenderMode.Init("RenderMode", path); @@ -128,6 +130,7 @@ public: void Load() { CPUDecoderMode.Load(2); + CPUIgnoreRWErrors.Load(false); GSRenderMode.Load(1); GSResolution.Load(4); GSAspectRatio.Load(2); @@ -142,6 +145,7 @@ public: void Save() { CPUDecoderMode.Save(); + CPUIgnoreRWErrors.Save(); GSRenderMode.Save(); GSResolution.Save(); GSAspectRatio.Save();