From 83a7c837617d0a8c067f19b096e4aef0d66faea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Wed, 19 Feb 2014 05:33:31 +0100 Subject: [PATCH 1/4] Moved some lines and deleted old code * Removed Compiler ELF references from rpcs3.cpp * Reordered the menu bar lines. * Moved the construction of some panels of MainFrame from rpcs3.cpp to MainFrame.cpp --- rpcs3/Gui/MainFrame.cpp | 26 +++++++++++++++----------- rpcs3/Gui/MainFrame.h | 6 +++++- rpcs3/rpcs3.cpp | 9 --------- rpcs3/rpcs3.h | 2 -- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 16d9e2ff00..916f960731 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -5,7 +5,6 @@ #include "RSXDebugger.h" #include "git-version.h" -#include "Emu/System.h" #include "Ini.h" #include "Emu/GS/sysutil_video.h" #include "Gui/VHDDManager.h" @@ -81,45 +80,50 @@ MainFrame::MainFrame() wxMenuBar& menubar(*new wxMenuBar()); wxMenu& menu_boot(*new wxMenu()); - wxMenu& menu_sys(*new wxMenu()); - wxMenu& menu_conf(*new wxMenu()); - wxMenu& menu_tools(*new wxMenu()); - wxMenu& menu_help(*new wxMenu()); - menubar.Append(&menu_boot, "Boot"); - menubar.Append(&menu_sys, "System"); - menubar.Append(&menu_conf, "Config"); - menubar.Append(&menu_tools, "Tools"); - menubar.Append(&menu_help, "Help"); - menu_boot.Append(id_boot_game, "Boot game"); menu_boot.Append(id_install_pkg, "Install PKG"); menu_boot.AppendSeparator(); menu_boot.Append(id_boot_elf, "Boot (S)ELF"); + wxMenu& menu_sys(*new wxMenu()); + menubar.Append(&menu_sys, "System"); menu_sys.Append(id_sys_pause, "Pause")->Enable(false); menu_sys.Append(id_sys_stop, "Stop\tCtrl + S")->Enable(false); menu_sys.AppendSeparator(); menu_sys.Append(id_sys_send_open_menu, "Send open system menu cmd")->Enable(false); menu_sys.Append(id_sys_send_exit, "Send exit cmd")->Enable(false); + wxMenu& menu_conf(*new wxMenu()); + menubar.Append(&menu_conf, "Config"); menu_conf.Append(id_config_emu, "Settings"); menu_conf.Append(id_config_pad, "PAD 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"); + wxMenu& menu_tools(*new wxMenu()); + menubar.Append(&menu_tools, "Tools"); menu_tools.Append(id_tools_compiler, "ELF Compiler"); menu_tools.Append(id_tools_memory_viewer, "Memory Viewer"); menu_tools.Append(id_tools_rsx_debugger, "RSX Debugger"); + wxMenu& menu_help(*new wxMenu()); + menubar.Append(&menu_help, "Help"); menu_help.Append(id_help_about, "About..."); SetMenuBar(&menubar); + // Panels m_game_viewer = new GameViewer(this); + m_debugger_frame = new DebuggerPanel(this); + ConLogFrame = new LogFrame(this); + AddPane(m_game_viewer, "Game List", wxAUI_DOCK_BOTTOM); + AddPane(ConLogFrame, "Log", wxAUI_DOCK_BOTTOM); + AddPane(m_debugger_frame, "Debugger", wxAUI_DOCK_RIGHT); + // Events Connect( id_boot_game, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootGame) ); Connect( id_install_pkg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::InstallPkg) ); Connect( id_boot_elf, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootElf) ); diff --git a/rpcs3/Gui/MainFrame.h b/rpcs3/Gui/MainFrame.h index ea4e1d0bce..af1cc69419 100644 --- a/rpcs3/Gui/MainFrame.h +++ b/rpcs3/Gui/MainFrame.h @@ -1,9 +1,13 @@ #pragma once -#include "GameViewer.h" + +#include "Gui/Debugger.h" +#include "Gui/GameViewer.h" + #include class MainFrame : public FrameBase { + DebuggerPanel* m_debugger_frame; GameViewer* m_game_viewer; wxAuiManager m_aui_mgr; AppConnector m_app_connector; diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index 87b82ed0ca..d2d015c2cb 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -3,7 +3,6 @@ #include "Ini.h" #include "Emu/System.h" #include -#include "Gui/CompilerELF.h" const wxEventType wxEVT_DBG_COMMAND = wxNewEventType(); @@ -22,15 +21,7 @@ bool Rpcs3App::OnInit() SetTopWindow(m_MainFrame); Emu.Init(); - // (new CompilerELF(m_MainFrame))->Show(); - m_debugger_frame = new DebuggerPanel(m_MainFrame); - ConLogFrame = new LogFrame(m_MainFrame); - - m_MainFrame->AddPane(ConLogFrame, "Log", wxAUI_DOCK_BOTTOM); - m_MainFrame->AddPane(m_debugger_frame, "Debugger", wxAUI_DOCK_RIGHT); - //ConLogFrame->Show(); m_MainFrame->Show(); - m_MainFrame->DoSettings(true); return true; diff --git a/rpcs3/rpcs3.h b/rpcs3/rpcs3.h index 019185cce4..7100b182f0 100644 --- a/rpcs3/rpcs3.h +++ b/rpcs3/rpcs3.h @@ -1,7 +1,6 @@ #pragma once #include "Gui/MainFrame.h" -#include "Gui/Debugger.h" template T min(const T a, const T b) { return a < b ? a : b; } template T max(const T a, const T b) { return a > b ? a : b; } @@ -55,7 +54,6 @@ class Rpcs3App : public wxApp { public: MainFrame* m_MainFrame; - DebuggerPanel* m_debugger_frame; virtual bool OnInit(); virtual void Exit(); From 5f9e60c45ff1f4ddcad166ce6aadea264a4f35bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Fri, 21 Feb 2014 02:35:33 +0100 Subject: [PATCH 2/4] PKG Loader rewritten * Rewritten unpkg.c -> Loader/PKG.cpp * MainFrame::InstallPkg now *only* installs the PKG. * Fixed crash when unpacking big debug PKG files. * Debug PKGs are no longer recrypted. * 'About...' dialog updated to remove PKG-related notice. * Unpkg removed. NOTE: The class PKGLoader is using wxWidgets functions to access the files. I think VFS would be better, but the Emulator isn't necessarily running when installing the PKG. In the other hand, initializing VFS with RPCS3 may be somewhat risky... Any alternatives? TODO: Get rid of the decrypted "*.dec" files, and try to decrypt and read contents of the PKG on the fly using the information stored in m_entries. --- rpcs3.sln | 8 - rpcs3/Gui/AboutDialog.h | 2 +- rpcs3/Gui/MainFrame.cpp | 46 +--- rpcs3/Loader/PKG.cpp | 242 ++++++++++++++++++++ rpcs3/Loader/PKG.h | 76 +++++++ rpcs3/rpcs3.vcxproj | 1 + rpcs3/rpcs3.vcxproj.filters | 3 + unpkg/oddkeys.h | 20 -- unpkg/ps3_common.h | 106 --------- unpkg/unpkg.c | 435 ------------------------------------ unpkg/unpkg.h | 180 --------------- 11 files changed, 335 insertions(+), 784 deletions(-) create mode 100644 rpcs3/Loader/PKG.cpp create mode 100644 rpcs3/Loader/PKG.h delete mode 100644 unpkg/oddkeys.h delete mode 100644 unpkg/ps3_common.h delete mode 100644 unpkg/unpkg.c delete mode 100644 unpkg/unpkg.h diff --git a/rpcs3.sln b/rpcs3.sln index 0d54438b39..fd82dacfc1 100644 --- a/rpcs3.sln +++ b/rpcs3.sln @@ -104,14 +104,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scetool", "scetool", "{AB33 scetool\zlib.h = scetool\zlib.h EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unpkg", "unpkg", "{9F2D2094-BA46-4456-8C45-FD9EC108F1EE}" - ProjectSection(SolutionItems) = preProject - unpkg\oddkeys.h = unpkg\oddkeys.h - unpkg\ps3_common.h = unpkg\ps3_common.h - unpkg\unpkg.c = unpkg\unpkg.c - unpkg\unpkg.h = unpkg\unpkg.h - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ribbon", "wxWidgets\build\msw\wx_vc10_ribbon.vcxproj", "{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stc", "wxWidgets\build\msw\wx_vc10_stc.vcxproj", "{23E1C437-A951-5943-8639-A17F3CF2E606}" diff --git a/rpcs3/Gui/AboutDialog.h b/rpcs3/Gui/AboutDialog.h index 3096f4c85b..1ac1839100 100644 --- a/rpcs3/Gui/AboutDialog.h +++ b/rpcs3/Gui/AboutDialog.h @@ -47,7 +47,7 @@ AboutDialog::AboutDialog(wxWindow *parent) wxBoxSizer* s_panel_credits(new wxBoxSizer(wxHORIZONTAL)); wxStaticText* t_section1 = new wxStaticText(this, wxID_ANY, "\nDevelopers:\n\nDH\nAlexAltea\nHykem\nOil", wxDefaultPosition, wxSize(156,160)); wxStaticText* t_section2 = new wxStaticText(this, wxID_ANY, "\nThanks:\n\nBlackDaemon", wxDefaultPosition, wxSize(156,160)); - wxStaticText* t_section3 = new wxStaticText(this, wxID_ANY, "\nExternal code:\n\n - SELF Decrypter based on scetool (C) 2011-2013 by naehrwert\n - PKG Installer based on ps3pkgtool (C) 2011-2013 by avtolstoy and PKG Finalize (C) by geohot", wxDefaultPosition, wxSize(156,160)); + wxStaticText* t_section3 = new wxStaticText(this, wxID_ANY, "\nExternal code:\n\n - SELF Decrypter based on scetool (C) 2011-2013 by naehrwert", wxDefaultPosition, wxSize(156,160)); s_panel_credits->AddSpacer(12); s_panel_credits->Add(t_section1); diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 916f960731..150c4be1e3 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -12,7 +12,7 @@ #include "Gui/AboutDialog.h" #include -#include "unpkg/unpkg.c" +#include "Loader/PKG.h" BEGIN_EVENT_TABLE(MainFrame, FrameBase) EVT_CLOSE(MainFrame::OnQuit) @@ -225,43 +225,21 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) return; } - ConLog.Write("PKG: extracting..."); - Emu.Stop(); - - wxString fileName = ctrl.GetPath(); - if (!pkg_unpack(static_cast(fileName))) - ConLog.Error("Could not unpack PKG!"); - else ConLog.Success("PKG: extract done."); - - if (!wxRemoveFile(ctrl.GetPath()+".dec")) - ConLog.Warning("Could not delete the decoded DEC file"); - - pkg_header *header; - pkg_info(static_cast(fileName), &header); - - wxString titleID_full (header->title_id); - wxString titleID = titleID_full.SubString(7, 15); - - wxString mainDir = wxGetCwd(); - wxString gamePath = "\\dev_hdd0\\game\\"; - - wxString pkgDir = mainDir + gamePath + titleID; - - // Save the title ID. - Emu.SetTitleID(titleID); - - //Refresh game list - m_game_viewer->Refresh(); - if(Emu.BootGame(pkgDir.ToStdString())) + // Open and install PKG file + std::string filePath = ctrl.GetPath(); + wxFile pkg_f(filePath, wxFile::read); // TODO: Use VFS to install PKG files + + if (pkg_f.IsOpened()) { - ConLog.Success("Game: boot done."); - } - else - { - ConLog.Error("Ps3 executable not found in folder (%s)", pkgDir.wx_str()); + PKGLoader pkg(pkg_f); + pkg.Install("/dev_hdd0/game/"); + pkg.Close(); } + + // Refresh game list + m_game_viewer->Refresh(); } void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event)) diff --git a/rpcs3/Loader/PKG.cpp b/rpcs3/Loader/PKG.cpp new file mode 100644 index 0000000000..fa861df607 --- /dev/null +++ b/rpcs3/Loader/PKG.cpp @@ -0,0 +1,242 @@ +#include "stdafx.h" +#include "PKG.h" +#include "scetool/aes.h" +#include "scetool/sha1.h" + +#include + +PKGLoader::PKGLoader(wxFile& f) : pkg_f(f) +{ +} + +bool PKGLoader::Install(std::string dest, bool show) +{ + // Initial checks + if(!pkg_f.IsOpened()) + return false; + + dest = wxGetCwd() + dest; + if (!dest.empty() && dest.back() != '/') + dest += '/'; + + if(!LoadHeader(show)) + return false; + + std::string titleID = std::string(m_header.title_id).substr(7, 9); + std::string decryptedFile = wxGetCwd() + "/dev_hdd1/" + titleID + ".dec"; + + if (wxDirExists(dest+titleID)) { + ConLog.Error("PKG Loader: Another installation found in: %s", wxString(titleID).wx_str()); + return false; + } + if (!wxMkdir(dest+titleID)) { + ConLog.Error("PKG Loader: Could not make the installation directory: %s", wxString(titleID).wx_str()); + return false; + } + + // Decrypt the PKG file + wxFile out; + out.Create(decryptedFile, true); + Decrypt(out); + out.Close(); + + // Unpack the decrypted file + wxFile dec(decryptedFile, wxFile::read); + LoadEntries(dec); + wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, unpacking...", m_entries.size(), 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); + + for (const PKGEntry& entry : m_entries) + { + UnpackEntry(dec, entry, dest+titleID+'/'); + pdlg.Update(pdlg.GetValue() + 1); + } + pdlg.Update(m_entries.size()); + + // Delete decrypted file + dec.Close(); + wxRemoveFile(decryptedFile); + ConLog.Write("PKG Loader: Package successfully installed in: /dev_hdd0/game/%s", wxString(titleID.c_str()).wx_str()); + return true; +} + +bool PKGLoader::Close() +{ + return pkg_f.Close(); +} + +bool PKGLoader::LoadHeader(bool show) +{ + pkg_f.Seek(0); + if (pkg_f.Read(&m_header, sizeof(PKGHeader)) != sizeof(PKGHeader)) { + ConLog.Error("PKG Loader: Package file is too short!"); + return false; + } + + if (!CheckHeader()) + return false; + + return true; +} + +bool PKGLoader::CheckHeader() +{ + if (m_header.pkg_magic != 0x7F504B47) { + ConLog.Error("PKG Loader: Not a package file!"); + return false; + } + + switch (m_header.pkg_type) + { + case PKG_RELEASE_TYPE_DEBUG: break; + case PKG_RELEASE_TYPE_RELEASE: break; + default: + ConLog.Error("PKG Loader: Unknown PKG type!"); + return false; + } + + switch (m_header.pkg_platform) + { + case PKG_PLATFORM_TYPE_PS3: break; + case PKG_PLATFORM_TYPE_PSP: break; + default: + ConLog.Error("PKG Loader: Unknown PKG type!"); + return false; + } + + if (m_header.header_size != PKG_HEADER_SIZE) { + ConLog.Error("PKG Loader: Wrong header size!"); + return false; + } + + if (m_header.pkg_size != pkg_f.Length()) { + ConLog.Error("PKG Loader: File size mismatch."); + return false; + } + + if (m_header.data_size + m_header.data_offset + 0x60 != pkg_f.Length()) { + ConLog.Error("PKG Loader: Data size mismatch."); + return false; + } + + return true; +} + +bool PKGLoader::LoadEntries(wxFile& dec) +{ + m_entries.resize(m_header.file_count); + + dec.Seek(0); + dec.Read(&m_entries[0], sizeof(PKGEntry) * m_header.file_count); + + if (m_entries[0].name_offset / sizeof(PKGEntry) != m_header.file_count) { + ConLog.Error("PKG Loader: Entries are damaged!"); + return false; + } + + return true; +} + +bool PKGLoader::UnpackEntry(wxFile& dec, const PKGEntry& entry, std::string dir) +{ + u8 buf[BUF_SIZE]; + + dec.Seek(entry.name_offset); + dec.Read(buf, entry.name_size); + buf[entry.name_size] = 0; + + switch (entry.type & (0xffff)) + { + case PKG_FILE_ENTRY_NPDRM: + case PKG_FILE_ENTRY_NPDRMEDAT: + case PKG_FILE_ENTRY_SDAT: + case PKG_FILE_ENTRY_REGULAR: + { + wxFile out; + out.Create(dir + buf); + dec.Seek(entry.file_offset); + + for (u64 size = 0; size < entry.file_size; ) { + size += dec.Read(buf, BUF_SIZE); + if (size > entry.file_size) + out.Write(buf, BUF_SIZE - (size - entry.file_size)); + else + out.Write(buf, BUF_SIZE); + } + out.Close(); + } + break; + + case PKG_FILE_ENTRY_FOLDER: + wxMkdir(dir + buf); + break; + } + return true; +} + +void PKGLoader::Decrypt(wxFile& out) +{ + aes_context c; + u8 iv[HASH_LEN]; + u8 buf[BUF_SIZE]; + u8 ctr[BUF_SIZE]; + + // Debug key + u8 key[0x40]; + memset(key, 0, 0x40); + memcpy(key+0x00, &m_header.qa_digest[0], 8); // &data[0x60] + memcpy(key+0x08, &m_header.qa_digest[0], 8); // &data[0x60] + memcpy(key+0x10, &m_header.qa_digest[8], 8); // &data[0x68] + memcpy(key+0x18, &m_header.qa_digest[8], 8); // &data[0x68] + + pkg_f.Seek(m_header.data_offset); + u32 parts = (m_header.data_size + BUF_SIZE - 1) / BUF_SIZE; + + wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, decrypting...", parts, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); + + memcpy(iv, m_header.klicensee, sizeof(iv)); + aes_setkey_enc(&c, PKG_AES_KEY, 128); + + for (u32 i=0; i*)&key[0x38] += 1; + } + } + + if (m_header.pkg_type == PKG_RELEASE_TYPE_RELEASE) + { + for (u32 j=0; j hi = *(be_t*)&iv[0]; + be_t lo = *(be_t*)&iv[8] + 1; + + if (lo == 0) + hi += 1; + + *(be_t*)&iv[0] = hi; + *(be_t*)&iv[8] = lo; + } + + for (u32 j=0; j pkg_magic; // Magic (0x7f504b47) + be_t pkg_type; // Release type (Retail:0x8000, Debug:0x0000) + be_t pkg_platform; // Platform type (PS3:0x0001, PSP:0x0002) + be_t header_size; // Header size (0xc0) + be_t unk1; // Some PKG version maybe? + be_t meta_size; // Size of metadata (block after header & hashes) + be_t file_count; // Number of files + be_t pkg_size; // PKG size in bytes + be_t data_offset; // Encrypted data offset + be_t data_size; // Encrypted data size in bytes + char title_id[48]; // Title ID + u8 qa_digest[16]; // This should be the hash of "files + attribs" + u8 klicensee[16]; // Nonce +}; + +struct PKGEntry +{ + be_t name_offset; // File name offset + be_t name_size; // File name size + be_t file_offset; // File offset + be_t file_size; // File size + be_t type; // File type + be_t pad; // Padding (zeros) +}; + +class PKGLoader +{ + wxFile& pkg_f; + PKGHeader m_header; + std::vector m_entries; + + virtual void Decrypt(wxFile& out); + +public: + PKGLoader(wxFile& f); + virtual bool Install(std::string dest, bool show = false); + + virtual bool LoadHeader(bool show = false); + virtual bool CheckHeader(); + + virtual bool LoadEntries(wxFile& dec); + virtual bool UnpackEntry(wxFile& dec, const PKGEntry& entry, std::string dir); + + virtual bool Close(); +}; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index dd103943cc..e60df54659 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -318,6 +318,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 67d1df150a..691c4365c9 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -406,6 +406,9 @@ Emu\FS + + Loader + diff --git a/unpkg/oddkeys.h b/unpkg/oddkeys.h deleted file mode 100644 index 9c53edab34..0000000000 --- a/unpkg/oddkeys.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include "stdafx.h" - -u8 retail_pkg_aes_key[] = {0x2E,0x7B,0x71,0xD7,0xC9,0xC9,0xA1,0x4E,0xA3,0x22,0x1F,0x18,0x88,0x28,0xB8,0xF8}; - -u8 npdrm_keypair_e[] = { -0xA1,0xC0,0x13,0xAB,0xCE,0x98,0xA7,0xE3,0xDC,0x69,0x92,0x3B,0x07,0xC0,0x28,0x5F, -0x75,0x54,0xC5,0x12,0xB0,0xB0,0xA9,0x6F,0x24,0x52,0x40,0xF2,0xFD,0x43,0x3A,0xF2, -0x3F,0x4E,0xFE,0xC6,0xC1,0x83,0xEA,0x37,0x8D,0x1B,0xEC,0xB0,0x9D,0x88,0xDB,0x32, -0x8F,0x2C,0x86,0x37,0xB7,0xAC,0x72,0x05,0x9B,0x15,0x56,0xB0,0xD9,0x5B,0x5B,0xE0}; - -u8 npdrm_keypair_d[] = { -0x87,0xC7,0x4F,0xFE,0x66,0x93,0x0B,0xAA,0xA1,0x6F,0x86,0x40,0x91,0xC5,0x66,0xFB, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x08,0x28,0xB5,0x8F,0xAC,0xF9,0xDE,0xC8,0xD7,0x0D,0xFE,0xF0,0xF3,0x76,0x63,0xAE, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - -u8 npdrm_omac_key1[] = {0x72,0xF9,0x90,0x78,0x8F,0x9C,0xFF,0x74,0x57,0x25,0xF0,0x8E,0x4C,0x12,0x83,0x87}; -u8 npdrm_omac_key2[] = {0x6B,0xA5,0x29,0x76,0xEF,0xDA,0x16,0xEF,0x3C,0x33,0x9F,0xB2,0x97,0x1E,0x25,0x6B}; -u8 npdrm_omac_key3[] = {0x9B,0x51,0x5F,0xEA,0xCF,0x75,0x06,0x49,0x81,0xAA,0x60,0x4D,0x91,0xA5,0x4E,0x97}; diff --git a/unpkg/ps3_common.h b/unpkg/ps3_common.h deleted file mode 100644 index 73d8e2185d..0000000000 --- a/unpkg/ps3_common.h +++ /dev/null @@ -1,106 +0,0 @@ -#pragma once -#include "stdafx.h" - -typedef struct { - u32 magic; - u32 debugFlag; - u32 infoOffset; - u32 unknown1; - u32 headSize; - u32 itemCount; - u64 packageSize; - u64 dataOffset; - u64 dataSize; -} pkg_header2; - -u64 get_u64(void* vd) { - u8 *d = (u8*)vd; - return ((u64)d[0]<<56) | ((u64)d[1]<<48) | ((u64)d[2]<<40) | ((u64)d[3]<<32) | (d[4]<<24) | (d[5]<<16) | (d[6]<<8) | d[7]; -} - -void set_u64(void* vd, u64 v) { - u8 *d = (u8*)vd; - d[0] = v>>56; - d[1] = v>>48; - d[2] = v>>40; - d[3] = v>>32; - d[4] = v>>24; - d[5] = v>>16; - d[6] = v>>8; - d[7] = v>>0; -} - -void set_u32(void* vd, u32 v) { - u8 *d = (u8*)vd; - d[0] = v>>24; - d[1] = v>>16; - d[2] = v>>8; - d[3] = v>>0; -} - -void set_u16(void* vd, u16 v) { - u8 *d = (u8*)vd; - d[0] = v>>8; - d[1] = v>>0; -} - -u32 get_u32(void* vd) { - u8 *d = (u8*)vd; - return (d[0]<<24) | (d[1]<<16) | (d[2]<<8) | d[3]; -} - -float get_float(u8* d) { - float ret; - u32 inter = (d[0]<<24) | (d[1]<<16) | (d[2]<<8) | d[3]; - memcpy(&ret, &inter, 4); - return ret; -} - -u32 get_u16(void* vd) { - u8 *d = (u8*)vd; - return (d[0]<<8) | d[1]; -} - -void hexdump(u8* d, int l) { - int i; - for(i=0;i - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include "unpkg.h" -#include "ps3_common.h" -#include "oddkeys.h" - -#include //in a *.c file ? - -static void hash_tostring(char *str, u8 *hash, u32 len) -{ - u8 *p; - memset(str, 0, 2*len+1); - for (p = hash; p-hash < len; p++) - { - str += 2; - } -} - -static void *pkg_open(const char *fname) -{ - FILE *f; - - f = fopen(fname, "rb"); - if (f == NULL) - { - ConLog.Error ("UnPkg: Could not open package file!"); - return NULL; - } - - return f; -} - -static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fname) -{ - pkg_header *header = (pkg_header*)malloc(sizeof(pkg_header)); - u64 tmp; - - if (!fread(header, sizeof(pkg_header), 1, f)) - { - ConLog.Error("UnPkg: Package file is too short!"); - return 1; - } - - // some sanity checks - - if (ntohl(header->magic) != PKG_MAGIC) - { - ConLog.Error("UnPkg: Not a package file!"); - return 1; - } - - switch (ntohl(header->rel_type) >> 16 & (0xffff)) - { - case PKG_RELEASE_TYPE_DEBUG: - { - ConLog.Warning ("UnPkg: Debug PKG detected."); - wxProgressDialog pdlg ("PKG Decrypter / Installer", "Please wait, recrypting...", 0, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); - - u8* data; - u8 sha_key[0x40]; - int i; - f= fopen(fname, "rb"); - _fseeki64(f, 0, SEEK_END); - int nlen = _ftelli64(f); - _fseeki64(f, 0, SEEK_SET); - data = (u8*)malloc(nlen); - fread(data, 1, nlen, f); - fclose(f); - - pkg_header2 *header = (pkg_header2 *)data; - int data_offset = get_u64(&(header->dataOffset)); - int data_size = get_u64(&(header->dataSize)); - - // decrypt debug - u8 sha_crap[0x40]; - memset(sha_crap, 0, 0x40); - memcpy(sha_crap, &data[0x60], 8); - memcpy(sha_crap+0x8, &data[0x60], 8); - memcpy(sha_crap+0x10, &data[0x68], 8); - memcpy(sha_crap+0x18, &data[0x68], 8); - - int dptr; - for(dptr = data_offset; dptr < (data_offset+data_size); dptr+=0x10) { - u8 hash[0x14]; - sha1(sha_crap, 0x40, hash); - for(i=0;i<0x10;i++) data[dptr+i] ^= hash[i]; - - set_u64(sha_crap+0x38, get_u64(sha_crap+0x38)+1); - } - - // recrypt retail - u8 pkg_key[0x10]; - memcpy(pkg_key, &data[0x70], 0x10); - - //AES_KEY aes_key; - aes_context aes_key; - aes_setkey_enc(&aes_key, retail_pkg_aes_key, 128); - - size_t num=0; u8 ecount_buf[0x10]; memset(ecount_buf, 0, 0x10); - aes_crypt_ctr(&aes_key, data_size, &num, pkg_key, ecount_buf, &data[data_offset], &data[data_offset]); - - // write back - g = fopen(fname, "wb"); - data[4] = 0x80; // set finalize flag - memset(&data[(data_offset+data_size)], 0, 0x60); - - // add hash - sha1(data, nlen-0x20, &data[nlen-0x20]); - - fwrite(data, 1, nlen, g); - //fclose(g); // not close the file for continuing - - _fseeki64(g, 0, SEEK_END); - tmp = _ftelli64(g); - } - break; - - - case PKG_RELEASE_TYPE_RELEASE: - { - ConLog.Warning ("UnPkg: Retail PKG detected."); - _fseeki64(f, 0, SEEK_END); - tmp = _ftelli64(f); - } - break; - - default: - ConLog.Error("UnPkg: Unknown release type."); - return 1; - - - } - switch (ntohl(header->rel_type) & (0xffff)) - { - case PKG_PLATFORM_TYPE_PS3: - case PKG_PLATFORM_TYPE_PSP: - break; - - default: - ConLog.Error("UnPkg: Unknown platform type."); - return 1; - } - - if (ntohl(header->header_size) != PKG_HEADER_SIZE) - { - ConLog.Error("UnPkg: Wrong header size: "); - return 1; - } - - //fseek(g, 0, SEEK_END); - //tmp = ftell(g); - if (ntohll(header->pkg_size) != tmp) - { - ConLog.Error("UnPkg: File size mismatch."); - return 1; - } - - tmp -= ntohll(header->data_offset) + 0x60; - if (ntohll(header->data_size) != tmp) - { - ConLog.Error("UnPkg: Data size mismatch."); - return 1; - } - - if (h_ptr != NULL) - { - (*h_ptr) = (pkg_header*) malloc(sizeof(pkg_header)); - memcpy(h_ptr, &header, sizeof(pkg_header*)); - } - - return 0; -} - -static void print_pkg_header(pkg_header *header) -{ - char qa[33], kl[33]; - - if (header == NULL) - return; - - hash_tostring(qa, header->qa_digest, sizeof(header->qa_digest)); - hash_tostring(kl, header->klicensee, sizeof(header->klicensee)); - - ConLog.Write("Magic: 0x%x", ntohl(header->magic)); - ConLog.Write("Release Type: 0x%x", ntohl(header->rel_type) >> 16 & (0xffff)); - ConLog.Write("Platform Type: 0x%x", ntohl(header->rel_type) & (0xffff)); - ConLog.Write("Header size: 0x%x", ntohl(header->header_size)); - ConLog.Write("Unk1: 0x%x", ntohl(header->unk1)); - ConLog.Write("Metadata size: 0x%x", ntohl(header->meta_size)); - ConLog.Write("File count: %u", ntohl(header->file_count)); - ConLog.Write("Pkg size: %llu", ntohll(header->pkg_size)); - ConLog.Write("Data offset: 0x%llx", ntohll(header->data_offset)); - ConLog.Write("Data size: 0x%llu", ntohll(header->data_size)); - ConLog.Write("TitleID: %s", wxString(header->title_id, 48).wx_str()); - ConLog.Write("QA Digest: %s", wxString(qa, 33).wx_str()); - ConLog.Write("KLicensee: %s", wxString(kl, 33).wx_str()); -} - -static void *pkg_info(const char *fname, pkg_header **h_ptr) -{ - FILE *f; - pkg_header *header; - - f = (FILE*) pkg_open(fname); - if (f == NULL) - return NULL; - - if (pkg_sanity_check(f, NULL, &header, fname)) - return NULL; - - print_pkg_header(header); - - if (h_ptr != NULL) - { - (*h_ptr) = header; - } - else - { - free(header); - } - - - return f; -} - - -static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f, - u64 len, FILE *out) -{ - aes_context c; - u32 parts, bits; - u32 i, j; - u8 iv[HASH_LEN]; - u8 buf[BUF_SIZE]; - u8 ctr[BUF_SIZE]; - u8 out_buf[BUF_SIZE]; - u32 l; - u64 hi, lo; - - int max = len / BUF_SIZE; - wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, decrypting...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); - - parts = len / BUF_SIZE; - if (len % BUF_SIZE != 0) - parts++; - - memcpy(iv, kl, sizeof(iv)); - aes_setkey_enc(&c, key, 128); - - for (i = 0; iname_offset, SEEK_SET); - - memset(buf, 0, sizeof(buf)); - fread(buf, fentry->name_size, 1, dec); - - switch (fentry->type & (0xffff)) - { - case PKG_FILE_ENTRY_NPDRM: - case PKG_FILE_ENTRY_NPDRMEDAT: - case PKG_FILE_ENTRY_SDAT: - case PKG_FILE_ENTRY_REGULAR: - out = fopen((char *)buf, "wb"); - _fseeki64(dec, fentry->file_offset, SEEK_SET); - for (size = 0; size < fentry->file_size; ) - { - size += fread(buf, sizeof(u8), BUF_SIZE, dec); - if (size > fentry->file_size) - tmp = size - fentry->file_size; - else - tmp = 0; - - fwrite(buf, sizeof(u8), BUF_SIZE - tmp, out); - } - - fclose(out); - break; - - case PKG_FILE_ENTRY_FOLDER: - mkdir ((char *)buf); - break; - } - return true; -} - -static void pkg_unpack_data(u32 file_count, FILE *dec) -{ - int max = file_count; - wxProgressDialog pdlg ("PKG Decrypter / Installer", "Please wait, unpacking...", max, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); - - u32 i; - pkg_file_entry *file_table = NULL; - - _fseeki64(dec, 0, SEEK_SET); - - file_table = (pkg_file_entry *)malloc(sizeof(pkg_file_entry)*file_count); - i = fread(file_table, sizeof(pkg_file_entry), file_count, dec); - - if (ntohl(file_table->name_offset) / sizeof(pkg_file_entry) != file_count) - { - ConLog.Error("UnPkg: ERROR. Impossiburu!"); - return; - } - - for (i = 0; iname_offset = ntohl((file_table+i)->name_offset); - (file_table+i)->name_size = ntohl((file_table+i)->name_size); - (file_table+i)->file_offset = ntohll((file_table+i)->file_offset); - (file_table+i)->file_size = ntohll((file_table+i)->file_size); - (file_table+i)->type = ntohl((file_table+i)->type); - - if(pkg_unpack_file(file_table+i, dec)) pdlg.Update(i); - } - - free(file_table); - pdlg.Update(max); -} - -bool pkg_unpack(const char *fname) -{ - FILE *f, *dec; - char *dec_fname; - pkg_header *header; - struct stat sb; - - f = (FILE*) pkg_info(fname, &header); - - if (f == NULL) - return false; - - // Save the main dir. - wxString mainDir = wxGetCwd(); - - // Set the working directory. - wxSetWorkingDirectory(wxGetCwd() + "\\dev_hdd0\\game\\"); - - std::string gamePath = "\\dev_hdd0\\game\\"; - - // Get the PKG title ID from the header and format it (should match TITLE ID from PARAM.SFO). - std::string titleID_full (header->title_id); - std::string titleID = titleID_full.substr(7, 9); - std::string pkgDir = mainDir + gamePath + titleID; - - _fseeki64(f, ntohll(header->data_offset), SEEK_SET); - - dec_fname = (char*)malloc(strlen(fname)+4); - memset(dec_fname, 0, strlen(fname)+4); - sprintf(dec_fname, "%s.dec", fname); - - dec = fopen(dec_fname, "wb+"); - if (dec == NULL) - { - ConLog.Error("UnPkg: Could not create temp file for decrypted data."); - free(header); - return false; - } - unlink(dec_fname); - - pkg_crypt(PKG_AES_KEY, header->klicensee, f, ntohll(header->data_size), - dec); - _fseeki64(dec, 0, SEEK_SET); - - fclose(f); - - if (stat(header->title_id, &sb) != 0) - { - if (mkdir(titleID.c_str()) < 0) - { - ConLog.Error("UnPkg: Could not mkdir."); - ConLog.Error("UnPkg: Possibly, folder already exists in dev_hdd0\\game : %s", wxString(titleID).wx_str()); - wxSetWorkingDirectory(mainDir); - free(header); - return false; - } - } - - chdir(titleID.c_str()); - - pkg_unpack_data(ntohl(header->file_count), dec); - fclose(dec); - - wxSetWorkingDirectory(mainDir); - return true; -} \ No newline at end of file diff --git a/unpkg/unpkg.h b/unpkg/unpkg.h deleted file mode 100644 index fa8262eb0e..0000000000 --- a/unpkg/unpkg.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2011 Andrey Tolstoy - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - - -#ifndef UNPKG_H_ -#define UNPKG_H_ - -#include "stdafx.h" -#include "scetool/aes.h" -#include "scetool/sha1.h" - -#ifdef __GNUG__ -#include -#endif - -#define ntohll(x) (((u64) ntohl (x) << 32) | (u64) ntohl (x >> 32) ) -#define htonll(x) (((u64) htonl (x) << 32) | (u64) htonl (x >> 32) ) -#define conv_ntohl(x) { x = ntohl(x); } -#define conv_ntohll(x) { x = ntohll(x); } -#define conv_htonl(x) { x = htonl(x); } -#define conv_htonll(x) { x = htonll(x); } - -#define unpack32(x) ((u32) ((u32)*(x) << 24 | \ - (u32)*(x+1) << 16 | \ - (u32)*(x+2) << 8 | \ - (u32)*(x+3) << 0)) - -#define unpack64(x) ((u64)unpack32(x) << 32 | (u64)unpack32(x+4)) - -#define pack32(x, p) \ - { \ - *(x) = (u8)(p >> 24); \ - *((x)+1) = (u8)(p >> 16); \ - *((x)+2) = (u8)(p >> 8); \ - *((x)+3) = (u8)(p >> 0); \ - } - -#define pack64(x, p) { pack32((x + 4), p); pack32((x), p >> 32); } - -#define HASH_LEN 16 -#define BUF_SIZE 4096 - -typedef struct { - u32 magic; // magic 0x7f504b47 - u32 rel_type; // release type - u32 header_size; // 0xc0 - u32 unk1; //some pkg version maybe - u32 meta_size; //size of metadata (block after header & hashes) - u32 file_count; // number of files - u64 pkg_size; // pkg size in bytes - u64 data_offset; // encrypted data offset - u64 data_size; // encrypted data size in bytes - char title_id[48]; // title id - u8 qa_digest[16]; // this should be the hash of "files + attribs" - u8 klicensee[16]; // nonce -} pkg_header; - -typedef struct { - u8 hash1[16]; - u8 hash2[16]; - u8 hash3[16]; - u8 hash4[16]; -} pkg_unk_checksum; - -/* - is it in meta or sfo? - # CATEGORY : HG - # BOOTABLE : YES - # VERSION : 01.00 - # APP_VER : 01.00 - # PS3_SYSTEM_VER : 03.0000 - */ - -/* meta hell structure */ -typedef struct { - u32 unk1; - u32 unk2; - u32 drm_type; - u32 unk3; - - u32 unk4; - u32 unk5; - u32 unk6; - u32 unk7; - - u32 unk8; - u32 unk9; - u32 unk10; - u32 unk11; - - u32 data_size; - u32 unk12; - u32 unk13; - u32 packager; - - u8 unk14[64]; -} pkg_meta; - -typedef struct { - u32 name_offset; // file name offset - u32 name_size; // file name size - u64 file_offset; // file offset - u64 file_size; // file size - u32 type; // file type - /* - 0x80000003 - regular file - 0x80000001 - npdrm - 0x80000004 - folder - 0x80000009 - sdat ? - 0x80000002 - npdrm.edat ? - */ - u32 pad; // padding (zeros) -} pkg_file_entry; - -typedef struct { - pkg_file_entry fe; - char *name; - char *path; -} file_table_tr; - -#define PKG_MAGIC 0x7f504b47 // \x7fPKG -#define PKG_HEADER_SIZE sizeof(pkg_header) + sizeof(pkg_unk_checksum) -#define PKG_RELEASE_TYPE_RELEASE 0x8000 -#define PKG_RELEASE_TYPE_DEBUG 0x0000 -#define PKG_PLATFORM_TYPE_PS3 0x0001 -#define PKG_PLATFORM_TYPE_PSP 0x0002 - -#define PKG_FILE_ENTRY_OVERWRITE 0x80000000 -#define PKG_FILE_ENTRY_NPDRM 0x0001 -#define PKG_FILE_ENTRY_NPDRMEDAT 0x0002 // npdrm.edat -#define PKG_FILE_ENTRY_REGULAR 0x0003 -#define PKG_FILE_ENTRY_FOLDER 0x0004 -#define PKG_FILE_ENTRY_SDAT 0x0009 // .sdat ? - -static const u8 PKG_AES_KEY[16] = { - 0x2e, 0x7b, 0x71, 0xd7, - 0xc9, 0xc9, 0xa1, 0x4e, - 0xa3, 0x22, 0x1f, 0x18, - 0x88, 0x28, 0xb8, 0xf8 -}; - -static void hash_tostring(char *str, u8 *hash, u32 len); - -static void *pkg_open(const char *fname); - -static int pkg_sanity_check(FILE *f, FILE *g, pkg_header **h_ptr, const char *fname); - -static void print_pkg_header(pkg_header *header); - -static void *pkg_info(const char *fname, pkg_header **h_ptr); - -static void pkg_crypt(const u8 *key, const u8 *kl, FILE *f, - u64 len, FILE *out); - -bool pkg_unpack(const char *fname); - -static void pkg_unpack_data(u32 file_count, FILE *dec); - -static bool pkg_unpack_file(pkg_file_entry *fentry, FILE *dec);; - -static int pkg_pack_data(file_table_tr *ftr, pkg_file_entry *table, - int file_count, sha1_context *ctx, FILE *out); - - -static void *pkg_pack_create_filetable(file_table_tr *tr, int file_count, - char **n_table, u32 *n_table_len); - -#endif From 17b877e448b204c44f65291fc0e9e4bd5f1b1147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Fri, 21 Feb 2014 14:21:08 +0100 Subject: [PATCH 3/4] Minor changes in RSXTexture.h and PKG Loader * Moved RSXTexture from RSXThread.h to RSXTexture.h * Renamed RSXTexture::Getmipmap to RSXTexture::GetMipmap * Used more GCM texture format constants in GLGSRender.h * PKG Loader: Added an "Overwrite?" dialog in case the folder dest+titleID (i.e. "/dev_hdd0/game/"+titleID) already exists. Note that in that case, the game won't be installed regardless of the option you choose on the dialog. --- rpcs3/Emu/GS/GL/GLGSRender.h | 8 ++--- rpcs3/Emu/GS/RSXTexture.cpp | 6 ++-- rpcs3/Emu/GS/RSXTexture.h | 62 ++++++++++++++++++++++++++++++++++++ rpcs3/Emu/GS/RSXThread.h | 62 +----------------------------------- rpcs3/Gui/RSXDebugger.cpp | 2 +- rpcs3/Loader/PKG.cpp | 8 ++++- 6 files changed, 78 insertions(+), 70 deletions(-) create mode 100644 rpcs3/Emu/GS/RSXTexture.h diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index b0ea63df71..e3875f665d 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -175,10 +175,10 @@ public: default: ConLog.Error("Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, is_swizzled ? "swizzled" : "linear", tex.GetFormat() & 0x40); break; } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.Getmipmap() - 1); - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.Getmipmap() > 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.GetMipmap() - 1); + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.GetMipmap() > 1); - if(format != 0x81 && format != 0x94) + if(format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16) { u8 remap_a = tex.GetRemap() & 0x3; u8 remap_r = (tex.GetRemap() >> 2) & 0x3; @@ -245,7 +245,7 @@ public: //Unbind(); - if(is_swizzled && format == 0x85) + if(is_swizzled && format == CELL_GCM_TEXTURE_A8R8G8B8) { free(unswizzledPixels); } diff --git a/rpcs3/Emu/GS/RSXTexture.cpp b/rpcs3/Emu/GS/RSXTexture.cpp index 9ac888c8e9..966e97a0af 100644 --- a/rpcs3/Emu/GS/RSXTexture.cpp +++ b/rpcs3/Emu/GS/RSXTexture.cpp @@ -1,5 +1,5 @@ #include "stdafx.h" -#include "RSXThread.h" +#include "RSXTexture.h" RSXTexture::RSXTexture() { @@ -70,7 +70,7 @@ u8 RSXTexture::GetFormat() const return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 8) & 0xff); } -u16 RSXTexture::Getmipmap() const +u16 RSXTexture::GetMipmap() const { return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 16) & 0xffff); } @@ -199,4 +199,4 @@ void RSXTexture::SetControl3(u16 depth, u32 pitch) { m_depth = depth; m_pitch = pitch; -} \ No newline at end of file +} diff --git a/rpcs3/Emu/GS/RSXTexture.h b/rpcs3/Emu/GS/RSXTexture.h new file mode 100644 index 0000000000..8b87a9d7d9 --- /dev/null +++ b/rpcs3/Emu/GS/RSXTexture.h @@ -0,0 +1,62 @@ +#pragma once + +class RSXTexture +{ + u8 m_index; + +public: + u32 m_pitch; + u16 m_depth; + +public: + RSXTexture(); + RSXTexture(u8 index); + void Init(); + + // Offset + u32 GetOffset() const; + + // Format + u8 GetLocation() const; + bool isCubemap() const; + u8 GetBorderType() const; + u8 GetDimension() const; + u8 GetFormat() const; + u16 GetMipmap() const; + + // Address + u8 GetWrapS() const; + u8 GetWrapT() const; + u8 GetWrapR() const; + u8 GetUnsignedRemap() const; + u8 GetZfunc() const; + u8 GetGamma() const; + u8 GetAnisoBias() const; + u8 GetSignedRemap() const; + + // Control0 + bool IsEnabled() const; + u16 GetMinLOD() const; + u16 GetMaxLOD() const; + u8 GetMaxAniso() const; + bool IsAlphaKillEnabled() const; + + // Control1 + u32 GetRemap() const; + + // Filter + u16 GetBias() const; + u8 GetMinFilter() const; + u8 GetMagFilter() const; + u8 GetConvolutionFilter() const; + bool isASigned() const; + bool isRSigned() const; + bool isGSigned() const; + bool isBSigned() const; + + // Image Rect + u16 GetWidth() const; + u16 GetHeight() const; + + void SetControl3(u16 depth, u32 pitch); +}; diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index bfe5256ddb..3063520c2e 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -1,5 +1,6 @@ #pragma once #include "GCM.h" +#include "RSXTexture.h" #include "RSXVertexProgram.h" #include "RSXFragmentProgram.h" #include "Emu/SysCalls/Callback.h" @@ -15,67 +16,6 @@ enum Method extern u32 methodRegisters[0xffff]; u32 GetAddress(u32 offset, u8 location); -class RSXTexture -{ - u8 m_index; - -public: - u32 m_pitch; - u16 m_depth; - -public: - RSXTexture(); - RSXTexture(u8 index); - void Init(); - - // Offset - u32 GetOffset() const; - - // Format - u8 GetLocation() const; - bool isCubemap() const; - u8 GetBorderType() const; - u8 GetDimension() const; - u8 GetFormat() const; - u16 Getmipmap() const; - - // Address - u8 GetWrapS() const; - u8 GetWrapT() const; - u8 GetWrapR() const; - u8 GetUnsignedRemap() const; - u8 GetZfunc() const; - u8 GetGamma() const; - u8 GetAnisoBias() const; - u8 GetSignedRemap() const; - - // Control0 - bool IsEnabled() const; - u16 GetMinLOD() const; - u16 GetMaxLOD() const; - u8 GetMaxAniso() const; - bool IsAlphaKillEnabled() const; - - // Control1 - u32 GetRemap() const; - - // Filter - u16 GetBias() const; - u8 GetMinFilter() const; - u8 GetMagFilter() const; - u8 GetConvolutionFilter() const; - bool isASigned() const; - bool isRSigned() const; - bool isGSigned() const; - bool isBSigned() const; - - // Image Rect - u16 GetWidth() const; - u16 GetHeight() const; - - void SetControl3(u16 depth, u32 pitch); -}; - struct RSXVertexData { u32 frequency; diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index e49614c029..a1df62713e 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -548,7 +548,7 @@ void RSXDebugger::GetTexture() m_list_texture->SetItem(i, 3, wxString::Format("%dD", render.m_textures[i].GetDimension())); m_list_texture->SetItem(i, 4, render.m_textures[i].IsEnabled() ? "True" : "False"); m_list_texture->SetItem(i, 5, wxString::Format("0x%x", render.m_textures[i].GetFormat())); - m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render.m_textures[i].Getmipmap())); + m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render.m_textures[i].GetMipmap())); m_list_texture->SetItem(i, 7, wxString::Format("0x%x", render.m_textures[i].m_pitch)); m_list_texture->SetItem(i, 8, wxString::Format("%dx%d", render.m_textures[i].GetWidth(), diff --git a/rpcs3/Loader/PKG.cpp b/rpcs3/Loader/PKG.cpp index fa861df607..fba5988eb6 100644 --- a/rpcs3/Loader/PKG.cpp +++ b/rpcs3/Loader/PKG.cpp @@ -12,7 +12,7 @@ PKGLoader::PKGLoader(wxFile& f) : pkg_f(f) bool PKGLoader::Install(std::string dest, bool show) { // Initial checks - if(!pkg_f.IsOpened()) + if (!pkg_f.IsOpened()) return false; dest = wxGetCwd() + dest; @@ -26,6 +26,12 @@ bool PKGLoader::Install(std::string dest, bool show) std::string decryptedFile = wxGetCwd() + "/dev_hdd1/" + titleID + ".dec"; if (wxDirExists(dest+titleID)) { + wxMessageDialog d_overwrite(NULL, "Another installation was found. Do you want to overwrite it?", "PKG Decrypter / Installer", wxYES_NO|wxCENTRE); + if (d_overwrite.ShowModal() != wxID_YES) { + ConLog.Error("PKG Loader: Another installation found in: %s", wxString(titleID).wx_str()); + return false; + } + // TODO: Remove the following two lines and remove the folder dest+titleID ConLog.Error("PKG Loader: Another installation found in: %s", wxString(titleID).wx_str()); return false; } From e7a721a1fbd47452ce289de405ae4a697f0912fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandro=20S=C3=A1nchez=20Bach?= Date: Fri, 21 Feb 2014 17:13:57 +0100 Subject: [PATCH 4/4] Merge pull request #46 from krofna --- Utilities/GNU.h | 1 + rpcs3/CMakeLists.txt | 13 +++++++++++-- rpcs3/Emu/Cell/MFC.h | 8 ++++---- rpcs3/Emu/GS/GL/GLGSRender.cpp | 7 ++++++- rpcs3/Emu/GS/GL/GLProcTable.tbl | 2 +- rpcs3/Emu/GS/GL/OpenGL.cpp | 8 ++++++++ rpcs3/Emu/GS/GL/OpenGL.h | 6 +++++- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 2 +- rpcs3/Emu/System.cpp | 2 +- rpcs3/Gui/CompilerELF.cpp | 4 ++++ rpcs3/Gui/ConLog.cpp | 2 ++ rpcs3/Gui/RSXDebugger.cpp | 10 +++++----- rpcs3/Gui/RSXDebugger.h | 2 +- rpcs3/Ini.cpp | 8 +++++++- rpcs3/rpcs3.cpp | 3 +++ 15 files changed, 60 insertions(+), 18 deletions(-) diff --git a/Utilities/GNU.h b/Utilities/GNU.h index 4995297187..f3678958d8 100644 --- a/Utilities/GNU.h +++ b/Utilities/GNU.h @@ -10,4 +10,5 @@ #define Sleep(x) usleep(x * 1000) #define mkdir(x) mkdir(x, 0777) #define INFINITE 0xFFFFFFFF +#define _CRT_ALIGN(x) __attribute__((aligned(x))) #endif diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index 8412a2d5a9..e9e5502f41 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -11,7 +11,12 @@ if (CMAKE_COMPILER_IS_GNUCXX) add_definitions(-fpermissive) # TODO: remove me endif() -find_package(wxWidgets) +add_definitions(-DGL_GLEXT_PROTOTYPES) +add_definitions(-DGLX_GLXEXT_PROTOTYPES) + +find_package(wxWidgets COMPONENTS core base net aui gl REQUIRED) +find_package(OpenGL REQUIRED) +find_package(ZLIB REQUIRED) include("${wxWidgets_USE_FILE}") @@ -27,11 +32,15 @@ ${CMAKE_SOURCE_DIR}/.. file( GLOB_RECURSE RPCS3_SRC +${CMAKE_SOURCE_DIR}/rpcs3.cpp +${CMAKE_SOURCE_DIR}/AppConnector.cpp +${CMAKE_SOURCE_DIR}/Ini.cpp ${CMAKE_SOURCE_DIR}/Emu/* ${CMAKE_SOURCE_DIR}/Gui/* ${CMAKE_SOURCE_DIR}/Loader/* ${CMAKE_SOURCE_DIR}/../Utilities/* +${CMAKE_SOURCE_DIR}/../scetool/scetool.cpp ) add_executable(rpcs3 ${RPCS3_SRC}) -target_link_libraries(rpcs3 ${wxWidgets_LIBRARIES}) +target_link_libraries(rpcs3 ${wxWidgets_LIBRARIES} ${OPENGL_LIBRARIES} ${ZLIB_LIBRARIES}) diff --git a/rpcs3/Emu/Cell/MFC.h b/rpcs3/Emu/Cell/MFC.h index 5ddf7a073a..ca8235c05a 100644 --- a/rpcs3/Emu/Cell/MFC.h +++ b/rpcs3/Emu/Cell/MFC.h @@ -158,7 +158,7 @@ struct DMAC u32 queue_pos; u32 proxy_pos; long queue_lock; - long proxy_lock; + volatile std::atomic proxy_lock; bool ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) { @@ -193,7 +193,7 @@ struct DMAC return MFC_PPU_DMA_QUEUE_FULL; } - /* while (_InterlockedExchange(&proxy_lock, 1)); + /* while (std::atomic_exchange(&proxy_lock, 1)); _mm_lfence(); DMAC_Proxy& p = proxy[proxy_pos]; p.cmd = cmd; @@ -212,7 +212,7 @@ struct DMAC void ClearCmd() { - while (_InterlockedExchange(&proxy_lock, 1)); + while (std::atomic_exchange(&proxy_lock, 1)); _mm_lfence(); memcpy(proxy, proxy + 1, --proxy_pos * sizeof(DMAC_Proxy)); _mm_sfence(); @@ -298,4 +298,4 @@ struct MFC MFC_QStatus.SetValue(mask); } } -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 98cb204231..386921abdf 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -652,7 +652,12 @@ void GLGSRender::OnInitThread() glEnable(GL_TEXTURE_2D); glEnable(GL_SCISSOR_TEST); +#ifdef _WIN32 glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0); +#else + if (GLXDrawable drawable = glXGetCurrentDrawable()) + glXSwapIntervalEXT(glXGetCurrentDisplay(), drawable, Ini.GSVSyncEnable.GetValue() ? 1 : 0); +#endif } void GLGSRender::OnExitThread() @@ -961,7 +966,7 @@ void GLGSRender::ExecCMD() if(m_set_depth_bounds) { //ConLog.Warning("glDepthBounds(%f, %f)", m_depth_bounds_min, m_depth_bounds_max); - glDepthBounds(m_depth_bounds_min, m_depth_bounds_max); + glDepthBoundsEXT(m_depth_bounds_min, m_depth_bounds_max); checkForGlError("glDepthBounds"); } diff --git a/rpcs3/Emu/GS/GL/GLProcTable.tbl b/rpcs3/Emu/GS/GL/GLProcTable.tbl index 265eda6154..fb6acb64c7 100644 --- a/rpcs3/Emu/GS/GL/GLProcTable.tbl +++ b/rpcs3/Emu/GS/GL/GLProcTable.tbl @@ -78,7 +78,7 @@ OPENGL_PROC(PFNGLPROGRAMUNIFORM1FPROC, ProgramUniform1f); OPENGL_PROC(PFNGLPROGRAMUNIFORM4FPROC, ProgramUniform4f); OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv); OPENGL_PROC(PFNGLUSEPROGRAMPROC, UseProgram); -OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBounds, glDepthBoundsEXT); +OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBoundsEXT, glDepthBoundsEXT); OPENGL_PROC(PFNGLSTENCILOPSEPARATEPROC, StencilOpSeparate); OPENGL_PROC(PFNGLSTENCILFUNCSEPARATEPROC, StencilFuncSeparate); OPENGL_PROC(PFNGLSTENCILMASKSEPARATEPROC, StencilMaskSeparate); diff --git a/rpcs3/Emu/GS/GL/OpenGL.cpp b/rpcs3/Emu/GS/GL/OpenGL.cpp index f113c447de..8de1efdd79 100644 --- a/rpcs3/Emu/GS/GL/OpenGL.cpp +++ b/rpcs3/Emu/GS/GL/OpenGL.cpp @@ -3,18 +3,22 @@ void InitProcTable() { +#ifdef _WIN32 #define OPENGL_PROC(p, n) OPENGL_PROC2(p, n, gl##n) #define OPENGL_PROC2(p, n, tn) /*if(!gl##n)*/ if(!(gl##n = (p)wglGetProcAddress(#tn))) ConLog.Error("OpenGL: initialization of " #tn " failed.") #include "GLProcTable.tbl" #undef OPENGL_PROC #undef OPENGL_PROC2 +#endif } +#ifdef _WIN32 #define OPENGL_PROC(p, n) p gl##n = nullptr #define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n) #include "GLProcTable.tbl" #undef OPENGL_PROC #undef OPENGL_PROC2 +#endif OpenGL::OpenGL() { @@ -29,18 +33,22 @@ OpenGL::~OpenGL() void OpenGL::Init() { +#ifdef _WIN32 #define OPENGL_PROC(p, n) OPENGL_PROC2(p, n, gl##n) #define OPENGL_PROC2(p, n, tn) if(!(n = (p)wglGetProcAddress(#tn))) ConLog.Error("OpenGL: initialization of " #tn " failed.") #include "GLProcTable.tbl" #undef OPENGL_PROC #undef OPENGL_PROC2 +#endif } void OpenGL::Close() { +#ifdef _WIN32 #define OPENGL_PROC(p, n) n = nullptr #define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n) #include "GLProcTable.tbl" #undef OPENGL_PROC #undef OPENGL_PROC2 +#endif } diff --git a/rpcs3/Emu/GS/GL/OpenGL.h b/rpcs3/Emu/GS/GL/OpenGL.h index 67cfe0c6c5..4089f466e1 100644 --- a/rpcs3/Emu/GS/GL/OpenGL.h +++ b/rpcs3/Emu/GS/GL/OpenGL.h @@ -4,7 +4,6 @@ #ifdef _WIN32 typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval); -#endif #define OPENGL_PROC(p, n) extern p gl##n #define OPENGL_PROC2(p, n, tn) OPENGL_PROC(p, n) @@ -12,6 +11,11 @@ typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval); #undef OPENGL_PROC #undef OPENGL_PROC2 +#else +#include +#include +#endif + void InitProcTable(); struct OpenGL diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 71bf06d477..35b1f8ab79 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -44,7 +44,7 @@ int cellPngDecOpen(u32 mainHandle, mem32_t subHandle, mem_ptr_t s // Get size of file MemoryAllocator sb; // Alloc a CellFsStat struct - ret = cellFsFstat(current_subHandle->fd, sb); + ret = cellFsFstat(current_subHandle->fd, sb.GetAddr()); if(ret != CELL_OK) return ret; current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size break; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 5846edec19..bff251bd08 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -190,7 +190,7 @@ void Emulator::Load() if(IsSelf(m_path.ToStdString())) { - std::string self_path = m_path; + std::string self_path = m_path.mb_str(); std::string elf_path = wxFileName(m_path).GetPath().c_str(); if(wxFileName(m_path).GetFullName().CmpNoCase("EBOOT.BIN") == 0) diff --git a/rpcs3/Gui/CompilerELF.cpp b/rpcs3/Gui/CompilerELF.cpp index d455da5390..9ef926ba6b 100644 --- a/rpcs3/Gui/CompilerELF.cpp +++ b/rpcs3/Gui/CompilerELF.cpp @@ -127,8 +127,10 @@ CompilerELF::CompilerELF(wxWindow* parent) " b exit, 0, 0\n" ); +#ifdef _WIN32 ::SendMessage((HWND)hex_list->GetHWND(), WM_VSCROLL, SB_BOTTOM, 0); ::SendMessage((HWND)asm_list->GetHWND(), WM_VSCROLL, SB_BOTTOM, 0); +#endif } CompilerELF::~CompilerELF() @@ -318,6 +320,7 @@ void CompilerELF::OnScroll(wxScrollWinEvent& event) dst = hex_list; } +#ifdef _WIN32 if(!m_disable_scroll && src && dst && event.GetOrientation() == wxVERTICAL) { s64 kind = -1; @@ -364,6 +367,7 @@ void CompilerELF::OnScroll(wxScrollWinEvent& event) m_disable_scroll = false; } } +#endif event.Skip(); } diff --git a/rpcs3/Gui/ConLog.cpp b/rpcs3/Gui/ConLog.cpp index ca658c0813..33a324dd9e 100644 --- a/rpcs3/Gui/ConLog.cpp +++ b/rpcs3/Gui/ConLog.cpp @@ -268,7 +268,9 @@ void LogFrame::Task() m_log.SetColumnWidth(0, -1); // crashes on exit m_log.SetColumnWidth(1, -1); +#ifdef _WIN32 ::SendMessage((HWND)m_log.GetHWND(), WM_VSCROLL, SB_BOTTOM, 0); +#endif } LogBuffer.Flush(); diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index a1df62713e..207f8c237c 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -571,7 +571,7 @@ void RSXDebugger::GetSettings() LIST_SETTINGS_ADD("Alpha func", !(render.m_set_alpha_func) ? "(none)" : wxString::Format("0x%x (%s)", render.m_alpha_func, - ParseGCMEnum(render.m_alpha_func, CELL_GCM_ENUM).wx_str())); + ParseGCMEnum(render.m_alpha_func, CELL_GCM_ENUM))); LIST_SETTINGS_ADD("Blend color", !(render.m_set_blend_color) ? "(none)" : wxString::Format("R:%d, G:%d, B:%d, A:%d", render.m_blend_color_r, render.m_blend_color_g, @@ -591,10 +591,10 @@ void RSXDebugger::GetSettings() LIST_SETTINGS_ADD("Depth bounds", wxString::Format("Min:%f, Max:%f", render.m_depth_bounds_min, render.m_depth_bounds_max)); LIST_SETTINGS_ADD("Depth func", !(render.m_set_depth_func) ? "(none)" : wxString::Format("0x%x (%s)", render.m_depth_func, - ParseGCMEnum(render.m_depth_func, CELL_GCM_ENUM).wx_str())); + ParseGCMEnum(render.m_depth_func, CELL_GCM_ENUM))); LIST_SETTINGS_ADD("Draw mode", wxString::Format("%d (%s)", render.m_draw_mode, - ParseGCMEnum(render.m_draw_mode, CELL_GCM_PRIMITIVE_ENUM).wx_str())); + ParseGCMEnum(render.m_draw_mode, CELL_GCM_PRIMITIVE_ENUM))); LIST_SETTINGS_ADD("Scissor", wxString::Format("X:%d, Y:%d, W:%d, H:%d", render.m_scissor_x, render.m_scissor_y, @@ -602,7 +602,7 @@ void RSXDebugger::GetSettings() render.m_scissor_h)); LIST_SETTINGS_ADD("Stencil func", !(render.m_set_stencil_func) ? "(none)" : wxString::Format("0x%x (%s)", render.m_stencil_func, - ParseGCMEnum(render.m_stencil_func, CELL_GCM_ENUM).wx_str())); + ParseGCMEnum(render.m_stencil_func, CELL_GCM_ENUM))); LIST_SETTINGS_ADD("Surface Pitch A", wxString::Format("0x%x", render.m_surface_pitch_a)); LIST_SETTINGS_ADD("Surface Pitch B", wxString::Format("0x%x", render.m_surface_pitch_b)); LIST_SETTINGS_ADD("Surface Pitch C", wxString::Format("0x%x", render.m_surface_pitch_c)); @@ -692,7 +692,7 @@ void RSXDebugger::OnSelectTexture(wxListEvent& event) UpdateInformation(); } -wxString RSXDebugger::ParseGCMEnum(u32 value, u32 type) +const char* RSXDebugger::ParseGCMEnum(u32 value, u32 type) { switch(type) { diff --git a/rpcs3/Gui/RSXDebugger.h b/rpcs3/Gui/RSXDebugger.h index 8877016974..872735b4db 100644 --- a/rpcs3/Gui/RSXDebugger.h +++ b/rpcs3/Gui/RSXDebugger.h @@ -79,7 +79,7 @@ public: virtual void SetPrograms(wxListEvent& event); virtual void OnSelectTexture(wxListEvent& event); - wxString ParseGCMEnum(u32 value, u32 type); + const char* ParseGCMEnum(u32 value, u32 type); wxString DisAsmCommand(u32 cmd, u32 count, u32 currentAddr, u32 ioAddr); diff --git a/rpcs3/Ini.cpp b/rpcs3/Ini.cpp index 96240a09d4..292f8d0f13 100644 --- a/rpcs3/Ini.cpp +++ b/rpcs3/Ini.cpp @@ -1,7 +1,9 @@ #include "stdafx.h" #include "Ini.h" +#ifdef _WIN32 #include +#endif Inis Ini; @@ -148,9 +150,13 @@ static wxString WindowInfoToString(const WindowInfo wind) //Ini Ini::Ini() { +#ifdef _WIN32 m_Config = new wxIniConfig( wxEmptyString, wxEmptyString, wxGetCwd() + "\\rpcs3.ini", wxEmptyString, wxCONFIG_USE_LOCAL_FILE ); +#else + m_Config = new wxConfig("rpcs3"); +#endif } void Ini::Save(wxString key, int value) @@ -211,4 +217,4 @@ wxString Ini::Load(wxString key, const wxString& def_value) WindowInfo Ini::Load(wxString key, const WindowInfo& def_value) { return StringToWindowInfo(m_Config->Read(key, WindowInfoToString(def_value))); -} \ No newline at end of file +} diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index d2d015c2cb..3ecc343150 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -2,7 +2,10 @@ #include "rpcs3.h" #include "Ini.h" #include "Emu/System.h" + +#ifdef _WIN32 #include +#endif const wxEventType wxEVT_DBG_COMMAND = wxNewEventType();