rpcsx/rpcs3/Gui/GameViewer.cpp

528 lines
12 KiB
C++
Raw Normal View History

#include "stdafx.h"
#include "stdafx_gui.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "GameViewer.h"
#include "Loader/PSF.h"
2015-10-24 12:38:24 +02:00
#include "SettingsDialog.h"
2016-05-13 16:01:48 +02:00
#include <algorithm>
static const std::string m_class_name = "GameViewer";
// Auxiliary classes
class sortGameData
{
int sortColumn;
bool sortAscending;
public:
sortGameData(u32 column, bool ascending) : sortColumn(column), sortAscending(ascending) {}
bool operator()(const GameInfo& game1, const GameInfo& game2) const
{
// Note that the column index has to match the appropriate GameInfo member
2014-12-13 18:27:34 +01:00
switch (sortColumn - 1) // skip *icon* column
{
case 0: return sortAscending ? (game1.name < game2.name) : (game1.name > game2.name);
case 1: return sortAscending ? (game1.serial < game2.serial) : (game1.serial > game2.serial);
case 2: return sortAscending ? (game1.fw < game2.fw) : (game1.fw > game2.fw);
case 3: return sortAscending ? (game1.app_ver < game2.app_ver) : (game1.app_ver > game2.app_ver);
case 4: return sortAscending ? (game1.category < game2.category) : (game1.category > game2.category);
case 5: return sortAscending ? (game1.root < game2.root) : (game1.root > game2.root);
default: return false;
}
}
};
// GameViewer functions
GameViewer::GameViewer(wxWindow* parent) : wxListView(parent)
{
LoadSettings();
m_columns.Show(this);
2014-12-14 07:54:26 +01:00
m_sortColumn = 1;
m_sortAscending = true;
m_popup = new wxMenu();
InitPopupMenu();
Bind(wxEVT_LIST_ITEM_ACTIVATED, &GameViewer::DClick, this);
Bind(wxEVT_LIST_COL_CLICK, &GameViewer::OnColClick, this);
Bind(wxEVT_LIST_ITEM_RIGHT_CLICK, &GameViewer::RightClick, this);
Refresh();
}
GameViewer::~GameViewer()
{
SaveSettings();
}
void GameViewer::InitPopupMenu()
{
2017-03-27 12:08:00 +02:00
wxMenuItem* boot_item = new wxMenuItem(m_popup, 0, "Boot");
#if defined (_WIN32)
// wxMenuItem::Set(Get)Font only available for the wxMSW port
wxFont font = GetFont();
font.SetWeight(wxFONTWEIGHT_BOLD);
boot_item->SetFont(font);
#endif
m_popup->Append(boot_item);
2017-03-27 12:08:00 +02:00
m_popup->Append(1, "Configure");
m_popup->AppendSeparator();
2017-03-27 12:08:00 +02:00
m_popup->Append(2, "Remove Game");
m_popup->Append(3, "Remove Custom Configuration");
m_popup->AppendSeparator();
2017-03-27 12:08:00 +02:00
m_popup->Append(4, "Open Game Folder");
m_popup->Append(5, "Open Config Folder");
Bind(wxEVT_MENU, &GameViewer::BootGame, this, 0);
Bind(wxEVT_MENU, &GameViewer::ConfigureGame, this, 1);
Bind(wxEVT_MENU, &GameViewer::RemoveGame, this, 2);
Bind(wxEVT_MENU, &GameViewer::RemoveGameConfig, this, 3);
2017-03-27 00:11:08 +02:00
Bind(wxEVT_MENU, &GameViewer::OpenGameFolder, this, 4);
2017-03-27 12:08:00 +02:00
Bind(wxEVT_MENU, &GameViewer::OpenConfigFolder, this, 5);
}
void GameViewer::DoResize(wxSize size)
{
SetSize(size);
}
void GameViewer::OnColClick(wxListEvent& event)
{
if (event.GetColumn() == m_sortColumn)
m_sortAscending ^= true;
else
m_sortAscending = true;
m_sortColumn = event.GetColumn();
2014-05-25 22:59:26 +02:00
// Sort entries, update columns and refresh the panel
std::sort(m_game_data.begin(), m_game_data.end(), sortGameData(m_sortColumn, m_sortAscending));
m_columns.Update(m_game_data);
ShowData();
}
void GameViewer::LoadGames()
{
m_games.clear();
2016-06-02 17:16:01 +02:00
for (const auto& entry : fs::dir(Emu.GetGameDir()))
{
2016-02-01 22:46:27 +01:00
if (entry.is_directory)
{
2016-02-01 22:46:27 +01:00
m_games.push_back(entry.name);
}
}
}
void GameViewer::LoadPSF()
{
m_game_data.clear();
2016-02-01 22:46:27 +01:00
2016-06-02 17:16:01 +02:00
const std::string& game_path = Emu.GetGameDir();
for (u32 i = 0; i < m_games.size(); ++i)
{
2016-06-02 17:16:01 +02:00
const std::string& dir = game_path + m_games[i];
const std::string& sfb = dir + "/PS3_DISC.SFB";
const std::string& sfo = dir + (fs::is_file(sfb) ? "/PS3_GAME/PARAM.SFO" : "/PARAM.SFO");
2016-02-01 22:46:27 +01:00
const fs::file sfo_file(sfo);
if (!sfo_file)
2015-04-20 03:54:19 +02:00
{
continue;
2015-04-20 03:54:19 +02:00
}
2016-02-01 22:46:27 +01:00
const auto& psf = psf::load_object(sfo_file);
2014-12-14 10:36:32 +01:00
GameInfo game;
game.root = m_games[i];
game.serial = psf::get_string(psf, "TITLE_ID", "");
2016-01-26 19:13:36 +01:00
game.name = psf::get_string(psf, "TITLE", "unknown");
game.app_ver = psf::get_string(psf, "APP_VER", "unknown");
game.category = psf::get_string(psf, "CATEGORY", "unknown");
game.fw = psf::get_string(psf, "PS3_SYSTEM_VER", "unknown");
game.parental_lvl = psf::get_integer(psf, "PARENTAL_LEVEL");
game.resolution = psf::get_integer(psf, "RESOLUTION");
game.sound_format = psf::get_integer(psf, "SOUND_FORMAT");
2016-02-01 22:46:27 +01:00
if (game.category == "HG")
2014-12-14 08:04:29 +01:00
{
game.category = "HDD Game";
2016-06-02 17:16:01 +02:00
game.icon_path = dir + "/ICON0.PNG";
2014-12-14 08:04:29 +01:00
}
2016-02-01 22:46:27 +01:00
else if (game.category == "DG")
2014-12-14 08:04:29 +01:00
{
game.category = "Disc Game";
2016-06-02 17:16:01 +02:00
game.icon_path = dir + "/PS3_GAME/ICON0.PNG";
2014-12-14 08:04:29 +01:00
}
2016-02-01 22:46:27 +01:00
else if (game.category == "HM")
{
game.category = "Home";
2016-06-02 17:16:01 +02:00
game.icon_path = dir + "/ICON0.PNG";
}
2016-02-01 22:46:27 +01:00
else if (game.category == "AV")
{
game.category = "Audio/Video";
2016-06-02 17:16:01 +02:00
game.icon_path = dir + "/ICON0.PNG";
}
2016-02-01 22:46:27 +01:00
else if (game.category == "GD")
{
game.category = "Game Data";
2016-06-02 17:16:01 +02:00
game.icon_path = dir + "/ICON0.PNG";
}
m_game_data.push_back(game);
}
// Sort entries and update columns
std::sort(m_game_data.begin(), m_game_data.end(), sortGameData(m_sortColumn, m_sortAscending));
m_columns.Update(m_game_data);
}
void GameViewer::ShowData()
{
m_columns.ShowData(this);
}
void GameViewer::Refresh()
{
LoadGames();
LoadPSF();
ShowData();
}
void GameViewer::SaveSettings()
{
m_columns.LoadSave(false, m_class_name, this);
}
void GameViewer::LoadSettings()
{
m_columns.LoadSave(true, m_class_name);
}
void GameViewer::DClick(wxListEvent& event)
{
long i = GetFirstSelected();
if (i < 0) return;
2016-06-02 17:16:01 +02:00
const std::string& path = Emu.GetGameDir() + m_game_data[i].root;
Emu.Stop();
2016-06-02 17:16:01 +02:00
if (!Emu.BootGame(path))
{
2016-06-02 17:16:01 +02:00
LOG_ERROR(LOADER, "Failed to boot /dev_hdd0/game/%s", m_game_data[i].root);
}
2013-11-19 11:30:58 +01:00
}
void GameViewer::RightClick(wxListEvent& event)
{
PopupMenu(m_popup, event.GetPoint());
}
2015-10-24 12:38:24 +02:00
void GameViewer::BootGame(wxCommandEvent& WXUNUSED(event))
{
wxListEvent unused_event;
DClick(unused_event);
}
void GameViewer::ConfigureGame(wxCommandEvent& WXUNUSED(event))
{
long i = GetFirstSelected();
if (i < 0) return;
SettingsDialog(this, "data/" + m_game_data[i].serial);
2015-10-24 12:38:24 +02:00
}
void GameViewer::RemoveGame(wxCommandEvent& event)
{
long i = GetFirstSelected();
if (i < 0) return;
2016-05-16 20:42:35 +02:00
if (wxMessageBox("Permanently delete game files?", "Confirm Delete", wxYES_NO | wxNO_DEFAULT) == wxYES)
{
2017-03-11 22:41:48 +01:00
fs::remove_all(Emu.GetGameDir() + fmt::ToUTF8(this->GetItemText(i, 6)));
2016-05-16 20:42:35 +02:00
}
Refresh();
}
2016-02-01 22:46:27 +01:00
void GameViewer::RemoveGameConfig(wxCommandEvent& event)
{
long i = GetFirstSelected();
if (i < 0) return;
2017-03-27 14:12:34 +02:00
const std::string config_path = fs::get_config_dir() + "data/" + m_game_data[i].serial + "/config.yml";
if (fs::is_file(config_path))
{
if (wxMessageBox("Delete custom game configuration?", "Confirm Delete", wxYES_NO | wxNO_DEFAULT) == wxYES)
{
2017-03-27 14:12:34 +02:00
if (fs::remove_file(config_path))
{
LOG_SUCCESS(GENERAL, "Removed configuration file: %s", config_path);
}
else
{
LOG_FATAL(GENERAL, "Failed to delete configuration file: %s\nError: %s", config_path, fs::g_tls_error);
}
}
}
2017-03-27 14:12:34 +02:00
else
{
LOG_ERROR(GENERAL, "Configuration file not found: %s", config_path);
}
}
static void open_dir(const std::string& spath)
2017-03-27 00:11:08 +02:00
{
2017-03-27 12:08:00 +02:00
fs::create_dir(spath);
2017-03-27 00:11:08 +02:00
#ifdef _WIN32
std::string command = "explorer " + spath;
std::replace(command.begin(), command.end(), '/', '\\');
2017-03-27 00:11:08 +02:00
#elif __APPLE__
std::string command = "open " + spath;
Improve portability for BSDs (#2813) * sys_net: don't use fds_bits from a system header on FreeBSD rpcs3/Emu/Cell/Modules/sys_net.cpp:137:14: error: no member named '__fds_bits' in 'sys_net::fd_set'; did you mean 'fds_bits'? if (src->fds_bits[i] & (1 << bit)) ^~~~~~~~ fds_bits /usr/include/sys/select.h:75:18: note: expanded from macro 'fds_bits' #define fds_bits __fds_bits ^ rpcs3/Emu/Cell/Modules/sys_net.h:114:13: note: 'fds_bits' declared here be_t<u32> fds_bits[32]; ^ * GUI: fallback to xdg-open on other Unices rpcs3/Gui/GameViewer.cpp:289:26: error: use of undeclared identifier 'command' wxExecute(fmt::FromUTF8(command)); ^ * File: FreeBSD never supported copyfile(3) but sendfile(2) works fine Utilities/File.cpp:114:10: fatal error: 'copyfile.h' file not found #include <copyfile.h> ^~~~~~~~~~~~ * Thread: add signal handling for BSDs Utilities/Thread.cpp:761:23: error: use of undeclared identifier 'REG_RAX' static const decltype(REG_RAX) reg_table[] = ^ Utilities/Thread.cpp:763:2: error: use of undeclared identifier 'REG_RAX' REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, ^ Utilities/Thread.cpp:763:11: error: use of undeclared identifier 'REG_RCX' REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, ^ Utilities/Thread.cpp:763:20: error: use of undeclared identifier 'REG_RDX' REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, ^ Utilities/Thread.cpp:763:29: error: use of undeclared identifier 'REG_RBX' REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, ^ Utilities/Thread.cpp:763:38: error: use of undeclared identifier 'REG_RSP' REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, ^ Utilities/Thread.cpp:763:47: error: use of undeclared identifier 'REG_RBP' REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, ^ Utilities/Thread.cpp:763:56: error: use of undeclared identifier 'REG_RSI' REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, ^ Utilities/Thread.cpp:763:65: error: use of undeclared identifier 'REG_RDI' REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, ^ Utilities/Thread.cpp:764:2: error: use of undeclared identifier 'REG_R8' REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP ^ Utilities/Thread.cpp:764:10: error: use of undeclared identifier 'REG_R9' REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP ^ Utilities/Thread.cpp:764:18: error: use of undeclared identifier 'REG_R10' REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP ^ Utilities/Thread.cpp:764:27: error: use of undeclared identifier 'REG_R11' REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP ^ Utilities/Thread.cpp:764:36: error: use of undeclared identifier 'REG_R12' REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP ^ Utilities/Thread.cpp:764:45: error: use of undeclared identifier 'REG_R13' REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP ^ Utilities/Thread.cpp:764:54: error: use of undeclared identifier 'REG_R14' REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP ^ Utilities/Thread.cpp:764:63: error: use of undeclared identifier 'REG_R15' REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP ^ Utilities/Thread.cpp:764:72: error: use of undeclared identifier 'REG_RIP' REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP ^ Utilities/Thread.cpp:792:26: error: no member named 'gregs' in '__mcontext' const u64 reg_value = *X64REG(context, reg - X64R_RAX); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:804:21: error: no member named 'gregs' in '__mcontext' out_value = (u8)(*X64REG(context, reg - X64R_AL)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:809:21: error: no member named 'gregs' in '__mcontext' out_value = (u8)(*X64REG(context, reg - X64R_AH) >> 8); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:815:31: error: no member named 'gregs' in '__mcontext' const s8 imm_value = *(s8*)(RIP(context) + i_size - 1); ^~~~~~~~~~~~ Utilities/Thread.cpp:784:18: note: expanded from macro 'RIP' #define RIP(c) (*X64REG((c), 16)) ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:827:33: error: no member named 'gregs' in '__mcontext' const s16 imm_value = *(s16*)(RIP(context) + i_size - 2); ^~~~~~~~~~~~ Utilities/Thread.cpp:784:18: note: expanded from macro 'RIP' #define RIP(c) (*X64REG((c), 16)) ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:836:33: error: no member named 'gregs' in '__mcontext' const s32 imm_value = *(s32*)(RIP(context) + i_size - 4); ^~~~~~~~~~~~ Utilities/Thread.cpp:784:18: note: expanded from macro 'RIP' #define RIP(c) (*X64REG((c), 16)) ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:846:20: error: no member named 'gregs' in '__mcontext' out_value = (u32)RCX(context); ^~~~~~~~~~~~ Utilities/Thread.cpp:779:18: note: expanded from macro 'RCX' #define RCX(c) (*X64REG((c), 1)) ^~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:851:19: error: no member named 'gregs' in '__mcontext' const u32 _cf = EFLAGS(context) & 0x1; ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:851:19: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:852:19: error: no member named 'gregs' in '__mcontext' const u32 _zf = EFLAGS(context) & 0x40; ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:852:19: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:853:19: error: no member named 'gregs' in '__mcontext' const u32 _sf = EFLAGS(context) & 0x80; ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:853:19: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:854:19: error: no member named 'gregs' in '__mcontext' const u32 _of = EFLAGS(context) & 0x800; ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:854:19: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:855:19: error: no member named 'gregs' in '__mcontext' const u32 _pf = EFLAGS(context) & 0x4; ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:855:19: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:885:12: error: no member named 'gregs' in '__mcontext' case 1: *X64REG(context, reg - X64R_RAX) = value & 0xff | *X64REG(context, re... ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:885:62: error: no member named 'gregs' in '__mcontext' ...*X64REG(context, reg - X64R_RAX) = value & 0xff | *X64REG(context, reg - X64R_RAX) & 0xffffff... ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:886:12: error: no member named 'gregs' in '__mcontext' case 2: *X64REG(context, reg - X64R_RAX) = value & 0xffff | *X64REG(context, ... ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:886:64: error: no member named 'gregs' in '__mcontext' ...reg - X64R_RAX) = value & 0xffff | *X64REG(context, reg - X64R_RAX) & 0xffff0000; return true; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:887:12: error: no member named 'gregs' in '__mcontext' case 4: *X64REG(context, reg - X64R_RAX) = value & 0xffffffff; return true; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:888:12: error: no member named 'gregs' in '__mcontext' case 8: *X64REG(context, reg - X64R_RAX) = value; return true; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:913:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) |= 0x1; // set CF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:913:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:917:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) &= ~0x1; // clear CF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:917:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:922:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) |= 0x40; // set ZF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:922:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:926:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) &= ~0x40; // clear ZF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:926:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:931:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) |= 0x80; // set SF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:931:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:935:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) &= ~0x80; // clear SF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:935:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:940:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) |= 0x800; // set OF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:940:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:944:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) &= ~0x800; // clear OF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:944:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:953:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) |= 0x4; // set PF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:953:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:957:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) &= ~0x4; // clear PF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:957:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:962:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) |= 0x10; // set AF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:962:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:966:3: error: no member named 'gregs' in '__mcontext' EFLAGS(context) &= ~0x10; // clear AF ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:966:3: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:976:7: error: no member named 'gregs' in '__mcontext' if (EFLAGS(context) & 0x400 /* direction flag */) ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:769:49: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:976:7: error: use of undeclared identifier 'REG_EFL' Utilities/Thread.cpp:769:55: note: expanded from macro 'EFLAGS' #define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) ^ Utilities/Thread.cpp:1020:25: error: no member named 'gregs' in '__mcontext' auto code = (const u8*)RIP(context); ^~~~~~~~~~~~ Utilities/Thread.cpp:784:18: note: expanded from macro 'RIP' #define RIP(c) (*X64REG((c), 16)) ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:1146:3: error: no member named 'gregs' in '__mcontext' RIP(context) += i_size; ^~~~~~~~~~~~ Utilities/Thread.cpp:784:18: note: expanded from macro 'RIP' #define RIP(c) (*X64REG((c), 16)) ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:1368:47: error: no member named 'gregs' in '__mcontext' const bool is_writing = context->uc_mcontext.gregs[REG_ERR] & 0x2; ~~~~~~~~~~~~~~~~~~~~ ^ Utilities/Thread.cpp:1368:53: error: use of undeclared identifier 'REG_ERR' const bool is_writing = context->uc_mcontext.gregs[REG_ERR] & 0x2; ^ Utilities/Thread.cpp:1393:89: error: no member named 'gregs' in '__mcontext' ...%s location %p at %p.", cause, info->si_addr, RIP(context))); ^~~~~~~~~~~~ Utilities/Thread.cpp:784:18: note: expanded from macro 'RIP' #define RIP(c) (*X64REG((c), 16)) ^~~~~~~~~~~~~~~ Utilities/Thread.cpp:767:55: note: expanded from macro 'X64REG' #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) ~~~~~~~~~~~~~~~~~~~~~~ ^ * Thread: add explict casts for incomplete pthread_t on some platforms Utilities/Thread.cpp:1467:17: error: no viable overloaded '=' ctrl->m_thread = thread; ~~~~~~~~~~~~~~ ^ ~~~~~~ Utilities/Atomic.h:776:12: note: candidate function not viable: cannot convert argument of incomplete type 'pthread_t' (aka 'pthread *') to 'const atomic_t<unsigned long>' for 1st argument atomic_t& operator =(const atomic_t&) = delete; ^ Utilities/Atomic.h:902:7: note: candidate function not viable: cannot convert argument of incomplete type 'pthread_t' (aka 'pthread *') to 'const type' (aka 'const unsigned long') for 1st argument type operator =(const type& rhs) ^ Utilities/Thread.cpp:1656:3: error: no matching function for call to 'pthread_detach' pthread_detach(m_thread.raw()); ^~~~~~~~~~~~~~ /usr/include/pthread.h:218:6: note: candidate function not viable: no known conversion from 'type' (aka 'unsigned long') to 'pthread_t' (aka 'pthread *') for 1st argument int pthread_detach(pthread_t); ^ * build: dlopen() maybe in libc /usr/bin/ld: cannot find -ldl c++: error: linker command failed with exit code 1 (use -v to see invocation) * build: iconv() maybe available on some BSDs in libc /usr/bin/ld: cannot find -liconv c++: error: linker command failed with exit code 1 (use -v to see invocation) * build: hidapi-hidraw is only built on Linux /usr/bin/ld: cannot find -lhidapi-hidraw c++: error: linker command failed with exit code 1 (use -v to see invocation) * Thread: use getrusage() on more POSIX-like systems * Qt: don't return NULL handle on other platforms rpcs3/rpcs3qt/gs_frame.cpp:120:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ * build: properly disable Vulkan on other platforms In file included from rpcs3/rpcs3_app.cpp:40: In file included from rpcs3/Emu/RSX/VK/VKGSRender.h:3: rpcs3/Emu/RSX/VK/VKHelpers.h:1209:42: error: unknown type name 'device_queues' std::vector<VkBool32> supportsPresent(device_queues); ^ rpcs3/Emu/RSX/VK/VKHelpers.h:1211:4: error: expected member name or ';' after declaration specifiers for (u32 index = 0; index < device_queues; index++) ^ rpcs3/Emu/RSX/VK/VKHelpers.h:1221:4: error: expected member name or ';' after declaration specifiers for (u32 i = 0; i < device_queues; i++) ^ rpcs3/Emu/RSX/VK/VKHelpers.h:1256:4: error: expected member name or ';' after declaration specifiers if (graphicsQueueNodeIndex != presentQueueNodeIndex) ^ rpcs3/Emu/RSX/VK/VKHelpers.h:1261:4: error: expected member name or ';' after declaration specifiers CHECK_RESULT(vkGetPhysicalDeviceSurfaceFormatsKHR(dev, surface, &formatCount, nullptr)); ^ [...] /usr/bin/ld: cannot find -lvulkan c++: error: linker command failed with exit code 1 (use -v to see invocation) * build: make install/strip work by moving commands * Qt: create surface for GL context if it wasn't ready #0 strlen (str=0x0) at /usr/src/lib/libc/string/strlen.c:100 #1 0x000000000090f02e in std::__1::char_traits<char>::length (__s=0x0) at /usr/include/c++/v1/__string:215 #2 std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string (__s=0x0, this=<optimized out>) at /usr/include/c++/v1/string:1547 #3 gl::capabilities::initialize (this=0x2ba32a0 <gl::g_driver_caps>) at rpcs3/Emu/RSX/GL/GLHelpers.h:133 #4 0x000000000090d3dd in gl::get_driver_caps () at rpcs3/Emu/RSX/GL/GLHelpers.cpp:56 #5 0x00000000008fa511 in GLGSRender::on_init_thread (this=0x838d30018) at rpcs3/Emu/RSX/GL/GLGSRender.cpp:484 #6 0x0000000000938f9e in rsx::thread::on_task (this=0x838d30018) at rpcs3/Emu/RSX/RSXThread.cpp:334 #7 0x0000000000abc329 in task_stack::task_type<named_thread::start_thread(std::__1::shared_ptr<void> const&)::$_10>::invoke() () #8 0x0000000000abc114 in thread_ctrl::start(std::__1::shared_ptr<thread_ctrl> const&, task_stack)::$_7::__invoke(void*) () #9 0x0000000801e60c35 in thread_start (curthread=0x843650a00) at /usr/src/lib/libthr/thread/thr_create.c:289 #10 0x0000000000000000 in ?? () * build: don't abort without git metadata -- Found Git: /usr/local/bin/git (found version "2.13.1") fatal: Not a git repository (or any parent up to mount point /) Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set). CMake Warning at git-version.cmake:12 (message): git rev-list failed, unable to include version. * build: non-parallel needs git-version.h earlier rpcs3/rpcs3_version.cpp:3:10: fatal error: 'git-version.h' file not found #include "git-version.h" ^~~~~~~~~~~~~~~ 1 error generated.
2017-06-22 20:03:41 +02:00
#else
2017-03-27 00:11:08 +02:00
std::string command = "xdg-open " + spath;
#endif
wxExecute(fmt::FromUTF8(command));
}
void GameViewer::OpenGameFolder(wxCommandEvent& event)
{
long i = GetFirstSelected();
if (i < 0) return;
open_dir(Emu.GetGameDir() + m_game_data[i].root);
2017-03-27 00:11:08 +02:00
}
2017-03-27 12:08:00 +02:00
void GameViewer::OpenConfigFolder(wxCommandEvent& event)
{
long i = GetFirstSelected();
if (i < 0) return;
open_dir(fs::get_config_dir() + "data/" + m_game_data[i].serial);
}
2016-02-01 22:46:27 +01:00
ColumnsArr::ColumnsArr()
{
Init();
}
std::vector<Column*> ColumnsArr::GetSortedColumnsByPos()
{
std::vector<Column*> arr;
for (u32 pos = 0; pos<m_columns.size(); pos++)
{
for (u32 c = 0; c<m_columns.size(); ++c)
{
if (m_columns[c].pos != pos) continue;
arr.push_back(&m_columns[c]);
}
}
return arr;
}
Column* ColumnsArr::GetColumnByPos(u32 pos)
{
std::vector<Column *> columns = GetSortedColumnsByPos();
for (u32 c = 0; c<columns.size(); ++c)
{
if (!columns[c]->shown)
{
pos++;
continue;
}
if (columns[c]->pos != pos) continue;
return columns[c];
}
return NULL;
}
void ColumnsArr::Init()
{
m_img_list = new wxImageList(80, 44);
m_columns.clear();
m_columns.emplace_back(0, 90, "Icon");
m_columns.emplace_back(1, 160, "Name");
m_columns.emplace_back(2, 85, "Serial");
m_columns.emplace_back(3, 55, "FW");
m_columns.emplace_back(4, 55, "App version");
m_columns.emplace_back(5, 75, "Category");
m_columns.emplace_back(6, 160, "Path");
m_col_icon = &m_columns[0];
m_col_name = &m_columns[1];
m_col_serial = &m_columns[2];
m_col_fw = &m_columns[3];
m_col_app_ver = &m_columns[4];
m_col_category = &m_columns[5];
m_col_path = &m_columns[6];
}
void ColumnsArr::Update(const std::vector<GameInfo>& game_data)
{
m_col_icon->data.clear();
m_col_name->data.clear();
m_col_serial->data.clear();
m_col_fw->data.clear();
m_col_app_ver->data.clear();
m_col_category->data.clear();
m_col_path->data.clear();
m_icon_indexes.clear();
if (m_columns.size() == 0) return;
for (const auto& game : game_data)
{
m_col_icon->data.push_back(game.icon_path);
m_col_name->data.push_back(game.name);
m_col_serial->data.push_back(game.serial);
m_col_fw->data.push_back(game.fw);
m_col_app_ver->data.push_back(game.app_ver);
m_col_category->data.push_back(game.category);
m_col_path->data.push_back(game.root);
}
// load icons
for (const auto& path : m_col_icon->data)
{
wxImage game_icon(80, 44);
2016-08-06 12:38:30 +02:00
if (!path.empty())
2016-02-01 22:46:27 +01:00
{
wxLogNull logNo; // temporary disable wx warnings ("iCCP: known incorrect sRGB profile" spamming)
if (game_icon.LoadFile(fmt::FromUTF8(path), wxBITMAP_TYPE_PNG))
{
2016-02-01 22:46:27 +01:00
game_icon.Rescale(80, 44, wxIMAGE_QUALITY_HIGH);
m_icon_indexes.push_back(m_img_list->Add(game_icon));
2016-08-06 12:38:30 +02:00
continue;
}
else
{
LOG_ERROR(GENERAL, "Error loading image %s", path);
}
2016-02-01 22:46:27 +01:00
}
2016-08-06 12:38:30 +02:00
m_icon_indexes.push_back(-1);
2016-02-01 22:46:27 +01:00
}
}
void ColumnsArr::Show(wxListView* list)
{
list->DeleteAllColumns();
list->SetImageList(m_img_list, wxIMAGE_LIST_SMALL);
std::vector<Column *> c_col = GetSortedColumnsByPos();
for (u32 i = 0, c = 0; i<c_col.size(); ++i)
{
if (!c_col[i]->shown) continue;
list->InsertColumn(c++, fmt::FromUTF8(c_col[i]->name), 0, c_col[i]->width);
}
}
void ColumnsArr::ShowData(wxListView* list)
{
list->DeleteAllItems();
list->SetImageList(m_img_list, wxIMAGE_LIST_SMALL);
for (int c = 1; c<list->GetColumnCount(); ++c)
{
Column* col = GetColumnByPos(c);
if (!col)
{
LOG_ERROR(HLE, "Columns loaded with error!");
return;
}
for (u32 i = 0; i<col->data.size(); ++i)
{
if (list->GetItemCount() <= (int)i)
{
list->InsertItem(i, wxEmptyString);
list->SetItemData(i, i);
}
list->SetItem(i, c, fmt::FromUTF8(col->data[i]));
if (m_icon_indexes[i] >= 0)
list->SetItemColumnImage(i, 0, m_icon_indexes[i]);
2016-02-01 22:46:27 +01:00
}
}
}
void ColumnsArr::LoadSave(bool isLoad, const std::string& path, wxListView* list)
{
if (isLoad)
{
Init();
}
else if (list)
{
for (int c = 0; c < list->GetColumnCount(); ++c)
{
Column* col = GetColumnByPos(c);
if (col)
col->width = list->GetColumnWidth(c);
}
}
auto&& cfg = g_gui_cfg["GameViewer"];
for (auto& column : m_columns)
{
auto&& c_cfg = cfg[column.name];
if (isLoad)
{
std::tie(column.pos, column.width) = c_cfg.as<std::pair<u32, u32>>(std::make_pair(column.def_pos, column.def_width));
column.shown = true;
}
else //if (column.shown)
{
c_cfg = std::make_pair(column.pos, column.width);
}
}
if (isLoad)
{
//check for errors
for (u32 c1 = 0; c1 < m_columns.size(); ++c1)
{
for (u32 c2 = c1 + 1; c2 < m_columns.size(); ++c2)
{
if (m_columns[c1].pos == m_columns[c2].pos)
{
LOG_ERROR(HLE, "Columns loaded with error!");
Init();
return;
}
}
}
for (u32 p = 0; p < m_columns.size(); ++p)
{
bool ishas = false;
for (u32 c = 0; c < m_columns.size(); ++c)
{
if (m_columns[c].pos != p)
continue;
ishas = true;
break;
}
if (!ishas)
{
LOG_ERROR(HLE, "Columns loaded with error!");
Init();
return;
}
}
}
else
{
save_gui_cfg();
}
}