mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-06-12 01:27:06 -04:00
150 lines
3.7 KiB
C++
150 lines
3.7 KiB
C++
#include "stdafx.h"
|
|
#include "disc.h"
|
|
#include "PSF.h"
|
|
#include "util/logs.hpp"
|
|
#include "Utilities/StrUtil.h"
|
|
#include "Emu/System.h"
|
|
#include "Emu/system_utils.hpp"
|
|
|
|
LOG_CHANNEL(disc_log, "DISC");
|
|
|
|
namespace disc
|
|
{
|
|
disc_type get_disc_type(std::string path, std::string& disc_root, std::string& ps3_game_dir)
|
|
{
|
|
disc_type type = disc_type::unknown;
|
|
|
|
disc_root.clear();
|
|
ps3_game_dir.clear();
|
|
|
|
if (path.empty())
|
|
{
|
|
disc_log.error("Can not determine disc type. Path is empty.");
|
|
return disc_type::invalid;
|
|
}
|
|
|
|
if (!fs::is_dir(path))
|
|
{
|
|
disc_log.error("Can not determine disc type. Path not a directory: '%s'", path);
|
|
return disc_type::invalid;
|
|
}
|
|
|
|
// Check for PS3 game first.
|
|
std::string elf_path;
|
|
if (const game_boot_result result = Emulator::GetElfPathFromDir(elf_path, path);
|
|
result == game_boot_result::no_errors)
|
|
{
|
|
// Every error past this point is considered a corrupt disc.
|
|
|
|
std::string sfb_dir;
|
|
const std::string elf_dir = fs::get_parent_dir(elf_path);
|
|
|
|
Emulator::GetBdvdDir(disc_root, sfb_dir, ps3_game_dir, elf_dir);
|
|
|
|
if (!fs::is_dir(disc_root) || !fs::is_dir(sfb_dir) || ps3_game_dir.empty())
|
|
{
|
|
disc_log.error("Not a PS3 disc: invalid folder (bdvd_dir='%s', sfb_dir='%s', game_dir='%s')", disc_root, sfb_dir, ps3_game_dir);
|
|
return disc_type::invalid;
|
|
}
|
|
|
|
// Load PARAM.SFO
|
|
const std::string sfo_dir = rpcs3::utils::get_sfo_dir_from_game_path(elf_dir + "/../", "");
|
|
const psf::registry _psf = psf::load_object(sfo_dir + "/PARAM.SFO");
|
|
|
|
if (_psf.empty())
|
|
{
|
|
disc_log.error("Not a PS3 disc: Corrupted PARAM.SFO found! (path='%s/PARAM.SFO')", sfo_dir);
|
|
return disc_type::invalid;
|
|
}
|
|
|
|
const std::string cat = std::string(psf::get_string(_psf, "CATEGORY"));
|
|
|
|
if (cat != "DG")
|
|
{
|
|
disc_log.error("Not a PS3 disc: Wrong category '%s'.", cat);
|
|
return disc_type::invalid;
|
|
}
|
|
|
|
return disc_type::ps3;
|
|
}
|
|
|
|
disc_log.notice("Not a PS3 disc: Elf not found. Looking for SYSTEM.CNF... (path='%s')", path);
|
|
|
|
std::vector<std::string> lines;
|
|
|
|
// Try to find SYSTEM.CNF
|
|
for (std::string search_dir = path;;)
|
|
{
|
|
if (fs::file file(search_dir + "/SYSTEM.CNF"); file)
|
|
{
|
|
disc_root = search_dir + "/";
|
|
lines = fmt::split(file.to_string(), {"\n"});
|
|
break;
|
|
}
|
|
|
|
std::string parent_dir = fs::get_parent_dir(search_dir);
|
|
|
|
if (parent_dir.size() == search_dir.size())
|
|
{
|
|
// Keep looking until root directory is reached
|
|
disc_log.error("SYSTEM.CNF not found in path: '%s'", path);
|
|
return disc_type::invalid;
|
|
}
|
|
|
|
search_dir = std::move(parent_dir);
|
|
}
|
|
|
|
for (usz i = 0; i < lines.size(); i++)
|
|
{
|
|
const std::string& line = lines[i];
|
|
const usz pos = line.find('=');
|
|
|
|
if (pos == umax)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const std::string key = fmt::trim(line.substr(0, pos));
|
|
std::string value;
|
|
|
|
if (pos != (line.size() - 1))
|
|
{
|
|
value = fmt::trim(line.substr(pos + 1));
|
|
}
|
|
|
|
if (value.empty() && i != (lines.size() - 1) && line.size() != 1)
|
|
{
|
|
// Some games have a character on the last line of the file, don't print the error in those cases.
|
|
disc_log.warning("Unusual or malformed entry in SYSTEM.CNF ignored: %s", line);
|
|
continue;
|
|
}
|
|
|
|
if (key == "BOOT2")
|
|
{
|
|
disc_log.notice("SYSTEM.CNF - Detected PS2 Disc = %s", value);
|
|
type = disc_type::ps2;
|
|
}
|
|
else if (key == "BOOT")
|
|
{
|
|
disc_log.notice("SYSTEM.CNF - Detected PSX/PSone Disc = %s", value);
|
|
type = disc_type::ps1;
|
|
}
|
|
else if (key == "VMODE")
|
|
{
|
|
disc_log.notice("SYSTEM.CNF - Disc region type = %s", value);
|
|
}
|
|
else if (key == "VER")
|
|
{
|
|
disc_log.notice("SYSTEM.CNF - Software version = %s", value);
|
|
}
|
|
}
|
|
|
|
if (type == disc_type::unknown)
|
|
{
|
|
disc_log.error("SYSTEM.CNF - Disc is not a PSX/PSone or PS2 game!");
|
|
}
|
|
|
|
return type;
|
|
}
|
|
}
|