mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-09-26 08:51:05 -04:00
75d729ce40
* refactor: from guest threads to EE scheduler * feat: bad wip mpeg fix for code veronica * feat: cheap copy from host feat: small perf o vsync tick * feat: added EE clock Hz fix: fix MPEG out of sync with new EE refactor * fix: fix lotr tests * fix: fix cri dtx loading fix: fix wrong mmi instruction translation fix: fix thread info params feat: added EE timers decoder and consumer feat: split SFI and IOP memory to prevent collision and overrides * feat: revert wrong changes * refactor: change GS architecture * feat: IOP emulator refactor: codegen to catch callbacks on mips code feat: added a lot of entries or IOP emulator * feat: analyzer resolve the complete constant-producing sequence with five-instruction backward scan stopped at LUI and therefore * feat: remove recompiled version of GetRomName refactor: split IOP emulator logic feat: added more HLE IOP modules feat: added ps2_path * eat: enhance ELF parser with improved callable entry detection and control flow analysis * feat: update memory hint handling and enhance entry point discovery logic * feat: add SET_GPR_ZE32 macro for zero-extending loads with unsigned semantics * refactor: Refactor PS2 IOP Host Adapter and Memory Management feat: Added PS2Vfs for virtual file system operations, including file opening, reading, writing, and path resolution. feat: Improve VIF1 data processing to handle GIF image packets more efficiently. * feat: added a lot of tests * fix: fix texture caching feat: wip multi version on dbcman * feat: remove LLE IOPs
124 lines
3.9 KiB
C++
124 lines
3.9 KiB
C++
#include "ps2x/iop/ps2_path.h"
|
|
|
|
#include <algorithm>
|
|
#include <cctype>
|
|
|
|
namespace ps2x::iop
|
|
{
|
|
namespace
|
|
{
|
|
std::string lowerAscii(std::string_view value)
|
|
{
|
|
std::string result(value);
|
|
std::transform(result.begin(), result.end(), result.begin(), [](unsigned char ch)
|
|
{ return static_cast<char>(std::tolower(ch)); });
|
|
return result;
|
|
}
|
|
|
|
void normalizeSuffix(std::string &suffix)
|
|
{
|
|
std::replace(suffix.begin(), suffix.end(), '\\', '/');
|
|
while (!suffix.empty() && suffix.front() == '/')
|
|
suffix.erase(suffix.begin());
|
|
|
|
const size_t semicolon = suffix.rfind(';');
|
|
if (semicolon == std::string::npos || semicolon + 1u == suffix.size())
|
|
return;
|
|
|
|
const bool numeric = std::all_of(suffix.begin() + static_cast<std::ptrdiff_t>(semicolon + 1u),
|
|
suffix.end(),
|
|
[](unsigned char ch)
|
|
{ return std::isdigit(ch) != 0; });
|
|
if (numeric)
|
|
suffix.erase(semicolon);
|
|
}
|
|
}
|
|
|
|
ParsedPs2Path parsePs2Path(std::string_view value)
|
|
{
|
|
ParsedPs2Path result;
|
|
if (value.empty())
|
|
return result;
|
|
|
|
const std::string lower = lowerAscii(value);
|
|
size_t prefixLength = 0u;
|
|
if (lower.rfind("host0:", 0u) == 0u)
|
|
{
|
|
result.device = Ps2PathDevice::Host;
|
|
result.deviceName = "host0";
|
|
prefixLength = 6u;
|
|
}
|
|
else if (lower.rfind("host:", 0u) == 0u)
|
|
{
|
|
result.device = Ps2PathDevice::Host;
|
|
result.deviceName = "host";
|
|
prefixLength = 5u;
|
|
}
|
|
else if (lower.rfind("cdrom0:", 0u) == 0u)
|
|
{
|
|
result.device = Ps2PathDevice::Cdrom;
|
|
result.deviceName = "cdrom0";
|
|
prefixLength = 7u;
|
|
}
|
|
else if (lower.rfind("cdrom:", 0u) == 0u)
|
|
{
|
|
result.device = Ps2PathDevice::Cdrom;
|
|
result.deviceName = "cdrom";
|
|
prefixLength = 6u;
|
|
}
|
|
else if (lower.rfind("mc0:", 0u) == 0u)
|
|
{
|
|
result.device = Ps2PathDevice::MemoryCard0;
|
|
result.deviceName = "mc0";
|
|
prefixLength = 4u;
|
|
}
|
|
else if (lower.rfind("rom0:", 0u) == 0u)
|
|
{
|
|
result.device = Ps2PathDevice::Rom0;
|
|
result.deviceName = "rom0";
|
|
prefixLength = 5u;
|
|
}
|
|
else if (value.size() > 2u && std::isalpha(static_cast<unsigned char>(value[0])) &&
|
|
value[1] == ':' && (value[2] == '/' || value[2] == '\\'))
|
|
{
|
|
result.device = Ps2PathDevice::NativeHost;
|
|
result.deviceName = "native";
|
|
}
|
|
else if (value.find(':') != std::string_view::npos)
|
|
{
|
|
// TODO maybe log an error here, but don't fail the parse. This is a non-standard device name.
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
result.device = Ps2PathDevice::Cdrom;
|
|
result.deviceName = "cdrom0";
|
|
}
|
|
|
|
result.path.assign(value.substr(prefixLength));
|
|
if (result.device != Ps2PathDevice::NativeHost)
|
|
normalizeSuffix(result.path);
|
|
return result;
|
|
}
|
|
|
|
std::string ps2PathLeafKey(const ParsedPs2Path &parsed)
|
|
{
|
|
if (!parsed)
|
|
return {};
|
|
std::string path = parsed.path;
|
|
std::replace(path.begin(), path.end(), '\\', '/');
|
|
const size_t slash = path.find_last_of('/');
|
|
if (slash != std::string::npos)
|
|
path.erase(0u, slash + 1u);
|
|
path = lowerAscii(path);
|
|
if (path.size() > 4u && path.ends_with(".irx"))
|
|
path.resize(path.size() - 4u);
|
|
return path;
|
|
}
|
|
|
|
std::string ps2PathLeafKey(std::string_view path)
|
|
{
|
|
return ps2PathLeafKey(parsePs2Path(path));
|
|
}
|
|
}
|