rpcsx/rpcs3/Gui/GameViewer.cpp

261 lines
6.2 KiB
C++
Raw Normal View History

#include "stdafx_gui.h"
#include "Utilities/AutoPause.h"
#include "Utilities/Log.h"
2015-04-24 23:38:11 +02:00
//#include "Utilities/File.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
2014-08-26 01:55:37 +02:00
#include "Emu/FS/VFS.h"
#include "Emu/FS/vfsDir.h"
#include "Emu/FS/vfsFile.h"
#include "GameViewer.h"
#include "Loader/PSF.h"
2014-07-11 19:06:59 +02:00
#include <wx/dir.h>
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;
}
}
};
class WxDirDeleteTraverser : public wxDirTraverser
{
public:
virtual wxDirTraverseResult OnFile(const wxString& filename)
{
if (!wxRemoveFile(filename)){
LOG_ERROR(HLE, "Couldn't delete File: %s", fmt::ToUTF8(filename).c_str());
}
return wxDIR_CONTINUE;
}
virtual wxDirTraverseResult OnDir(const wxString& dirname)
{
wxDir dir(dirname);
dir.Traverse(*this);
if (!wxRmDir(dirname)){
//this get triggered a few times while clearing folders
//but if this gets reimplented we should probably warn
//if directories can't be removed
}
return wxDIR_CONTINUE;
}
};
// 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_path = "/dev_hdd0/game/";
m_popup = new wxMenu();
m_popup->Append(0, _T("Remove Game"));
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::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();
2015-04-25 23:26:54 +02:00
for (const auto info : vfsDir(m_path))
{
if(info->flags & DirEntry_TypeDir)
{
m_games.push_back(info->name);
}
}
}
void GameViewer::LoadPSF()
{
m_game_data.clear();
for(uint i=0; i<m_games.size(); ++i)
{
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");
2015-04-20 03:54:19 +02:00
if (!Emu.GetVFS().ExistsFile(sfo))
{
continue;
}
2015-04-20 03:54:19 +02:00
vfsFile f;
2015-04-20 03:54:19 +02:00
if (!f.Open(sfo))
{
continue;
2015-04-20 03:54:19 +02:00
}
2015-04-16 01:17:42 +02:00
const PSFLoader psf(f);
2015-04-20 03:54:19 +02:00
if (!psf)
{
continue;
2015-04-20 03:54:19 +02: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);
GameInfo game;
game.root = m_games[i];
game.serial = psf.GetString("TITLE_ID");
game.name = psf.GetString("TITLE");
game.app_ver = psf.GetString("APP_VER");
game.category = psf.GetString("CATEGORY");
game.fw = psf.GetString("PS3_SYSTEM_VER");
game.parental_lvl = psf.GetInteger("PARENTAL_LEVEL");
game.resolution = psf.GetInteger("RESOLUTION");
game.sound_format = psf.GetInteger("SOUND_FORMAT");
2014-12-14 08:04:29 +01:00
if (game.serial.length() == 9)
{
game.serial = game.serial.substr(0, 4) + "-" + game.serial.substr(4, 5);
2014-12-14 08:04:29 +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
{
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
{
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
}
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()
{
Emu.GetVFS().Init("/");
LoadGames();
LoadPSF();
ShowData();
Emu.GetVFS().UnMountAll();
}
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;
const std::string& path = m_path + m_game_data[i].root;
Emu.Stop();
Debug::AutoPause::getInstance().Reload();
Emu.GetVFS().Init("/");
std::string local_path;
if (Emu.GetVFS().GetDevice(path, local_path) && !Emu.BootGame(local_path)) {
LOG_ERROR(HLE, "Boot error: elf not found! [%s]", path.c_str());
return;
}
if (Ini.HLEAlwaysStart.GetValue() && Emu.IsReady()) {
Emu.Run();
}
2013-11-19 11:30:58 +01:00
}
void GameViewer::RightClick(wxListEvent& event)
{
m_popup->Destroy(m_popup->FindItemByPosition(0));
wxMenuItem *pMenuItemA = m_popup->Append(event.GetIndex(), _T("Remove Game"));
Bind(wxEVT_MENU, &GameViewer::RemoveGame, this, event.GetIndex());
PopupMenu(m_popup, event.GetPoint());
}
void GameViewer::RemoveGame(wxCommandEvent& event)
{
Emu.GetVFS().Init("/");
// get local path from VFS
std::string local_path;
Emu.GetVFS().GetDevice(m_path, local_path);
std::string del_path = local_path + "/" + this->GetItemText(event.GetId(), 6).ToStdString();
Emu.GetVFS().UnMountAll();
2014-07-11 19:06:59 +02:00
//TODO: Replace wxWidgetsSpecific filesystem stuff?
WxDirDeleteTraverser deleter;
wxDir localDir(del_path);
localDir.Traverse(deleter);
wxRmdir(del_path); // delete empty directory
Refresh();
}