2015-12-02 17:12:48 +01:00
|
|
|
#include "stdafx.h"
|
2014-08-29 00:49:26 +02:00
|
|
|
#include "stdafx_gui.h"
|
2014-08-13 14:54:27 +02:00
|
|
|
#include "Utilities/AutoPause.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
#include "Emu/Memory/Memory.h"
|
|
|
|
|
#include "Emu/System.h"
|
2014-08-26 01:55:37 +02:00
|
|
|
#include "Emu/FS/VFS.h"
|
2014-06-02 19:27:24 +02:00
|
|
|
#include "Emu/FS/vfsDir.h"
|
|
|
|
|
#include "Emu/FS/vfsFile.h"
|
2012-11-15 00:39:56 +01:00
|
|
|
#include "GameViewer.h"
|
|
|
|
|
#include "Loader/PSF.h"
|
2015-10-24 12:38:24 +02:00
|
|
|
#include "SettingsDialog.h"
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-04-01 02:33:55 +02:00
|
|
|
static const std::string m_class_name = "GameViewer";
|
2014-06-02 16:59:50 +02:00
|
|
|
|
|
|
|
|
// 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
|
2014-06-02 16:59:50 +02:00
|
|
|
{
|
|
|
|
|
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
|
2013-06-30 10:46:29 +02:00
|
|
|
GameViewer::GameViewer(wxWindow* parent) : wxListView(parent)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
|
|
|
|
LoadSettings();
|
2013-06-30 10:46:29 +02:00
|
|
|
m_columns.Show(this);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-12-14 07:54:26 +01:00
|
|
|
m_sortColumn = 1;
|
2014-06-02 16:59:50 +02:00
|
|
|
m_sortAscending = true;
|
2014-02-22 03:53:06 +01:00
|
|
|
m_path = "/dev_hdd0/game/";
|
2014-06-01 20:36:08 +02:00
|
|
|
m_popup = new wxMenu();
|
|
|
|
|
|
2014-04-13 03:31:59 +02:00
|
|
|
Bind(wxEVT_LIST_ITEM_ACTIVATED, &GameViewer::DClick, this);
|
2014-05-25 20:45:44 +02:00
|
|
|
Bind(wxEVT_LIST_COL_CLICK, &GameViewer::OnColClick, this);
|
2014-06-01 20:36:08 +02:00
|
|
|
Bind(wxEVT_LIST_ITEM_RIGHT_CLICK, &GameViewer::RightClick, this);
|
2012-11-15 00:39:56 +01:00
|
|
|
|
|
|
|
|
Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GameViewer::~GameViewer()
|
|
|
|
|
{
|
|
|
|
|
SaveSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameViewer::DoResize(wxSize size)
|
|
|
|
|
{
|
|
|
|
|
SetSize(size);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-25 20:45:44 +02:00
|
|
|
void GameViewer::OnColClick(wxListEvent& event)
|
|
|
|
|
{
|
2014-06-02 16:59:50 +02:00
|
|
|
if (event.GetColumn() == m_sortColumn)
|
|
|
|
|
m_sortAscending ^= true;
|
|
|
|
|
else
|
|
|
|
|
m_sortAscending = true;
|
|
|
|
|
m_sortColumn = event.GetColumn();
|
2014-05-25 22:59:26 +02:00
|
|
|
|
2014-06-02 16:59:50 +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();
|
2014-05-25 20:45:44 +02:00
|
|
|
}
|
|
|
|
|
|
2012-11-15 00:39:56 +01:00
|
|
|
void GameViewer::LoadGames()
|
|
|
|
|
{
|
2014-04-01 02:33:55 +02:00
|
|
|
m_games.clear();
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2015-04-25 23:26:54 +02:00
|
|
|
for (const auto info : vfsDir(m_path))
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-02-22 03:53:06 +01:00
|
|
|
if(info->flags & DirEntry_TypeDir)
|
|
|
|
|
{
|
2014-04-01 02:33:55 +02:00
|
|
|
m_games.push_back(info->name);
|
2014-02-22 03:53:06 +01:00
|
|
|
}
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameViewer::LoadPSF()
|
|
|
|
|
{
|
2014-03-28 05:20:13 +01:00
|
|
|
m_game_data.clear();
|
2015-09-13 09:26:01 +02:00
|
|
|
for (u32 i = 0; i < m_games.size(); ++i)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2015-04-20 03:54:19 +02:00
|
|
|
const std::string sfb = m_path + m_games[i] + "/PS3_DISC.SFB";
|
|
|
|
|
const std::string sfo = m_path + m_games[i] + (Emu.GetVFS().ExistsFile(sfb) ? "/PS3_GAME/PARAM.SFO" : "/PARAM.SFO");
|
2014-06-11 23:24:37 +02:00
|
|
|
|
2015-04-20 03:54:19 +02:00
|
|
|
if (!Emu.GetVFS().ExistsFile(sfo))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2014-06-11 23:24:37 +02:00
|
|
|
|
2015-04-20 03:54:19 +02:00
|
|
|
vfsFile f;
|
2014-06-11 23:24:37 +02:00
|
|
|
|
2015-04-20 03:54:19 +02:00
|
|
|
if (!f.Open(sfo))
|
|
|
|
|
{
|
2014-02-16 16:19:06 +01:00
|
|
|
continue;
|
2015-04-20 03:54:19 +02:00
|
|
|
}
|
2014-02-16 16:19:06 +01:00
|
|
|
|
2016-01-07 23:12:33 +01:00
|
|
|
const psf::object psf(f);
|
2015-04-20 03:54:19 +02:00
|
|
|
|
|
|
|
|
if (!psf)
|
|
|
|
|
{
|
2014-03-28 05:20:13 +01:00
|
|
|
continue;
|
2015-04-20 03:54:19 +02:00
|
|
|
}
|
2014-03-28 05:20:13 +01:00
|
|
|
|
2014-12-14 10:36:32 +01:00
|
|
|
// get local path from VFS...
|
|
|
|
|
std::string local_path;
|
|
|
|
|
Emu.GetVFS().GetDevice(m_path, local_path);
|
|
|
|
|
|
2014-03-28 05:20:13 +01:00
|
|
|
GameInfo game;
|
|
|
|
|
game.root = m_games[i];
|
2016-01-07 23:12:33 +01:00
|
|
|
game.serial = psf["TITLE_ID"].as_string();
|
|
|
|
|
game.name = psf["TITLE"].as_string();
|
|
|
|
|
game.app_ver = psf["APP_VER"].as_string();
|
|
|
|
|
game.category = psf["CATEGORY"].as_string();
|
|
|
|
|
game.fw = psf["PS3_SYSTEM_VER"].as_string();
|
|
|
|
|
game.parental_lvl = psf["PARENTAL_LEVEL"].as_integer();
|
|
|
|
|
game.resolution = psf["RESOLUTION"].as_integer();
|
|
|
|
|
game.sound_format = psf["SOUND_FORMAT"].as_integer();
|
2014-06-14 08:16:23 +02:00
|
|
|
|
2014-12-14 08:04:29 +01:00
|
|
|
if (game.serial.length() == 9)
|
|
|
|
|
{
|
2014-04-01 02:33:55 +02:00
|
|
|
game.serial = game.serial.substr(0, 4) + "-" + game.serial.substr(4, 5);
|
2014-12-14 08:04:29 +01:00
|
|
|
}
|
2014-03-28 05:20:13 +01:00
|
|
|
|
2014-06-24 17:03:27 +02:00
|
|
|
if (game.category.substr(0, 2) == "HG")
|
2014-12-14 08:04:29 +01:00
|
|
|
{
|
2014-06-14 08:16:23 +02:00
|
|
|
game.category = "HDD Game";
|
2014-12-14 10:36:32 +01:00
|
|
|
game.icon_path = local_path + "/" + m_games[i] + "/ICON0.PNG";
|
2014-12-14 08:04:29 +01:00
|
|
|
}
|
2014-06-24 17:03:27 +02:00
|
|
|
else if (game.category.substr(0, 2) == "DG")
|
2014-12-14 08:04:29 +01:00
|
|
|
{
|
2014-06-14 08:16:23 +02:00
|
|
|
game.category = "Disc Game";
|
2014-12-14 10:36:32 +01:00
|
|
|
game.icon_path = local_path + "/" + m_games[i] + "/PS3_GAME/ICON0.PNG";
|
2014-12-14 08:04:29 +01:00
|
|
|
}
|
2015-09-13 09:26:01 +02:00
|
|
|
else if (game.category.substr(0, 2) == "HM")
|
|
|
|
|
{
|
|
|
|
|
game.category = "Home";
|
|
|
|
|
game.icon_path = local_path + "/" + m_games[i] + "/ICON0.PNG";
|
|
|
|
|
}
|
|
|
|
|
else if (game.category.substr(0, 2) == "AV")
|
|
|
|
|
{
|
|
|
|
|
game.category = "Audio/Video";
|
|
|
|
|
game.icon_path = local_path + "/" + m_games[i] + "/ICON0.PNG";
|
|
|
|
|
}
|
|
|
|
|
else if (game.category.substr(0, 2) == "GD")
|
|
|
|
|
{
|
|
|
|
|
game.category = "Game Data";
|
2015-09-28 16:37:50 +02:00
|
|
|
game.icon_path = local_path + "/" + m_games[i] + "/ICON0.PNG";
|
2015-09-13 09:26:01 +02:00
|
|
|
}
|
2014-06-14 08:16:23 +02:00
|
|
|
|
2014-03-28 05:20:13 +01:00
|
|
|
m_game_data.push_back(game);
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
2014-06-02 16:59:50 +02:00
|
|
|
// Sort entries and update columns
|
|
|
|
|
std::sort(m_game_data.begin(), m_game_data.end(), sortGameData(m_sortColumn, m_sortAscending));
|
2012-11-15 00:39:56 +01:00
|
|
|
m_columns.Update(m_game_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameViewer::ShowData()
|
|
|
|
|
{
|
2013-06-30 10:46:29 +02:00
|
|
|
m_columns.ShowData(this);
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameViewer::Refresh()
|
|
|
|
|
{
|
2014-11-29 15:16:48 +01:00
|
|
|
Emu.GetVFS().Init("/");
|
2012-11-15 00:39:56 +01:00
|
|
|
LoadGames();
|
|
|
|
|
LoadPSF();
|
|
|
|
|
ShowData();
|
2014-02-22 03:53:06 +01:00
|
|
|
Emu.GetVFS().UnMountAll();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameViewer::SaveSettings()
|
|
|
|
|
{
|
2013-06-30 10:46:29 +02:00
|
|
|
m_columns.LoadSave(false, m_class_name, this);
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameViewer::LoadSettings()
|
|
|
|
|
{
|
|
|
|
|
m_columns.LoadSave(true, m_class_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GameViewer::DClick(wxListEvent& event)
|
|
|
|
|
{
|
2013-06-30 10:46:29 +02:00
|
|
|
long i = GetFirstSelected();
|
2015-09-13 09:26:01 +02:00
|
|
|
if (i < 0) return;
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-04-01 02:33:55 +02:00
|
|
|
const std::string& path = m_path + m_game_data[i].root;
|
2013-12-08 17:54:45 +01:00
|
|
|
|
2014-02-22 13:06:23 +01:00
|
|
|
Emu.Stop();
|
2014-08-13 14:54:27 +02:00
|
|
|
|
|
|
|
|
Debug::AutoPause::getInstance().Reload();
|
|
|
|
|
|
2014-11-29 15:16:48 +01:00
|
|
|
Emu.GetVFS().Init("/");
|
2014-04-01 02:33:55 +02:00
|
|
|
std::string local_path;
|
2015-09-13 09:26:01 +02:00
|
|
|
if (Emu.GetVFS().GetDevice(path, local_path) && !Emu.BootGame(local_path))
|
|
|
|
|
{
|
2014-06-27 15:26:46 +02:00
|
|
|
LOG_ERROR(HLE, "Boot error: elf not found! [%s]", path.c_str());
|
2012-11-15 00:39:56 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2014-07-23 12:38:08 +02:00
|
|
|
|
2015-10-26 22:09:31 +01:00
|
|
|
if (rpcs3::config.misc.always_start.value() && Emu.IsReady())
|
2015-09-13 09:26:01 +02:00
|
|
|
{
|
2014-07-23 12:38:08 +02:00
|
|
|
Emu.Run();
|
|
|
|
|
}
|
2013-11-19 11:30:58 +01:00
|
|
|
}
|
2014-06-01 20:36:08 +02:00
|
|
|
|
|
|
|
|
void GameViewer::RightClick(wxListEvent& event)
|
|
|
|
|
{
|
2015-12-05 17:40:30 +01:00
|
|
|
for (wxMenuItem *item : m_popup->GetMenuItems()) {
|
|
|
|
|
m_popup->Destroy(item);
|
|
|
|
|
}
|
2014-06-01 20:36:08 +02:00
|
|
|
|
2015-10-24 14:18:40 +02:00
|
|
|
wxMenuItem* boot_item = new wxMenuItem(m_popup, 0, _T("Boot"));
|
|
|
|
|
#if defined (_WIN32)
|
|
|
|
|
// wxMenuItem::Set(Get)Font only available for the wxMSW port
|
2015-10-24 12:38:24 +02:00
|
|
|
wxFont font = GetFont();
|
|
|
|
|
font.SetWeight(wxFONTWEIGHT_BOLD);
|
|
|
|
|
boot_item->SetFont(font);
|
2015-10-24 14:18:40 +02:00
|
|
|
#endif
|
2015-10-24 12:38:24 +02:00
|
|
|
m_popup->Append(boot_item);
|
|
|
|
|
m_popup->Append(1, _T("Configure"));
|
|
|
|
|
m_popup->Append(2, _T("Remove Game"));
|
|
|
|
|
|
|
|
|
|
Bind(wxEVT_MENU, &GameViewer::BootGame, this, 0);
|
|
|
|
|
Bind(wxEVT_MENU, &GameViewer::ConfigureGame, this, 1);
|
|
|
|
|
Bind(wxEVT_MENU, &GameViewer::RemoveGame, this, 2);
|
|
|
|
|
|
2014-06-01 20:36:08 +02:00
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
Emu.CreateConfig(m_game_data[i].serial);
|
2015-12-16 20:50:45 +01:00
|
|
|
rpcs3::config_t custom_config { fs::get_config_dir() + "data/" + m_game_data[i].serial + "/settings.ini" };
|
2015-10-24 20:48:07 +02:00
|
|
|
custom_config.load();
|
|
|
|
|
LOG_NOTICE(LOADER, "Configure: '%s'", custom_config.path().c_str());
|
|
|
|
|
SettingsDialog(this, &custom_config);
|
2015-10-24 12:38:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-06-01 20:36:08 +02:00
|
|
|
void GameViewer::RemoveGame(wxCommandEvent& event)
|
|
|
|
|
{
|
2015-12-05 16:13:16 +01:00
|
|
|
long i = GetFirstSelected();
|
|
|
|
|
if (i < 0) return;
|
|
|
|
|
|
2014-12-15 18:38:12 +01:00
|
|
|
Emu.GetVFS().Init("/");
|
2015-12-05 16:13:16 +01:00
|
|
|
Emu.GetVFS().DeleteAll(m_path + "/" + this->GetItemText(i, 6).ToStdString());
|
2014-06-01 20:36:08 +02:00
|
|
|
Emu.GetVFS().UnMountAll();
|
|
|
|
|
|
|
|
|
|
Refresh();
|
|
|
|
|
}
|