mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-04-12 04:21:31 -06:00
Merge branch 'master' into feature/reorderable-game-list-columns
This commit is contained in:
commit
b4111e3390
@ -166,6 +166,7 @@ static fs::error to_error(int e)
|
||||
case ENOTEMPTY: return fs::error::notempty;
|
||||
case EROFS: return fs::error::readonly;
|
||||
case EISDIR: return fs::error::isdir;
|
||||
case ENOTDIR: return fs::error::notdir;
|
||||
case ENOSPC: return fs::error::nospace;
|
||||
case EXDEV: return fs::error::xdev;
|
||||
default: return fs::error::unknown;
|
||||
@ -2833,6 +2834,7 @@ void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
|
||||
case fs::error::notempty: return "Not empty";
|
||||
case fs::error::readonly: return "Read only";
|
||||
case fs::error::isdir: return "Is a directory";
|
||||
case fs::error::notdir: return "Not a directory";
|
||||
case fs::error::toolong: return "Path too long";
|
||||
case fs::error::nospace: return "Not enough space on the device";
|
||||
case fs::error::xdev: return "Device mismatch";
|
||||
|
||||
@ -683,6 +683,7 @@ namespace fs
|
||||
notempty,
|
||||
readonly,
|
||||
isdir,
|
||||
notdir,
|
||||
toolong,
|
||||
nospace,
|
||||
xdev,
|
||||
|
||||
@ -2957,7 +2957,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
if (g_cfg.core.spu_block_size == spu_block_size_type::safe)
|
||||
{
|
||||
// Stop on special instructions (TODO)
|
||||
m_targets[pos];
|
||||
m_targets[pos].push_back(SPU_LS_SIZE);
|
||||
next_block();
|
||||
break;
|
||||
}
|
||||
@ -2978,7 +2978,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
spu_log.error("[0x%x] Invalid interrupt flags (DE)", pos);
|
||||
}
|
||||
|
||||
m_targets[pos];
|
||||
m_targets[pos].push_back(SPU_LS_SIZE);
|
||||
next_block();
|
||||
break;
|
||||
}
|
||||
@ -3011,7 +3011,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
|
||||
bool is_no_return = false;
|
||||
|
||||
if (pos_next >= lsa && pos_next < limit)
|
||||
if (sl && pos_next >= lsa && pos_next < limit)
|
||||
{
|
||||
const u32 data_next = ls[pos_next / 4];
|
||||
const auto type_next = g_spu_itype.decode(data_next);
|
||||
@ -3274,6 +3274,12 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
spu_log.notice("[0x%x] At 0x%x: ignoring indirect branch (SYNC)", entry_point, pos);
|
||||
}
|
||||
|
||||
if (!(af & vf::is_const))
|
||||
{
|
||||
// Possible unknown target
|
||||
m_targets[pos].emplace_back(SPU_LS_SIZE);
|
||||
}
|
||||
|
||||
if (type == spu_itype::BI || sl || is_no_return)
|
||||
{
|
||||
if (type == spu_itype::BI || g_cfg.core.spu_block_size == spu_block_size_type::safe || is_no_return)
|
||||
@ -3883,6 +3889,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
it->second.emplace_back(SPU_LS_SIZE);
|
||||
}
|
||||
|
||||
std::sort(it->second.begin(), it->second.end());
|
||||
it++;
|
||||
}
|
||||
|
||||
@ -6087,17 +6094,17 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
|
||||
u32 ra = s_reg_max, rb = s_reg_max, rc = s_reg_max;
|
||||
|
||||
if (m_use_ra.test(pos / 4))
|
||||
if (::at32(m_use_ra, pos / 4))
|
||||
{
|
||||
ra = op.ra;
|
||||
}
|
||||
|
||||
if (m_use_rb.test(pos / 4))
|
||||
if (::at32(m_use_rb, pos / 4))
|
||||
{
|
||||
rb = op.rb;
|
||||
}
|
||||
|
||||
if (m_use_rc.test(pos / 4))
|
||||
if (::at32(m_use_rc, pos / 4))
|
||||
{
|
||||
rc = op.rc;
|
||||
}
|
||||
@ -6312,10 +6319,6 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
case spu_itype::BI:
|
||||
case spu_itype::BISL:
|
||||
case spu_itype::BISLED:
|
||||
case spu_itype::BIZ:
|
||||
case spu_itype::BINZ:
|
||||
case spu_itype::BIHZ:
|
||||
case spu_itype::BIHNZ:
|
||||
{
|
||||
if (op.e || op.d)
|
||||
{
|
||||
@ -6361,11 +6364,11 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
const auto& b = ::at32(m_bbs, reduced_loop->loop_pc);
|
||||
const auto& b2 = ::at32(m_bbs, bpc);
|
||||
|
||||
if (!reduced_loop->loop_dicts.test(i))
|
||||
if (!::at32(reduced_loop->loop_dicts, i))
|
||||
{
|
||||
if (b.reg_use[i] || (!b.reg_mod.test(i) && b2.reg_use[i]))
|
||||
if (b.reg_use[i] || (!::at32(b.reg_mod, i) && b2.reg_use[i]))
|
||||
{
|
||||
if ((b.reg_use[i] && b.reg_mod.test(i)) || b2.reg_mod.test(i))
|
||||
if ((b.reg_use[i] && ::at32(b.reg_mod, i)) || ::at32(b2.reg_mod, i))
|
||||
{
|
||||
reduced_loop->is_constant_expression = false;
|
||||
reduced_loop->loop_writes.set(i);
|
||||
@ -6416,12 +6419,23 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
}
|
||||
case spu_itype::BRHZ:
|
||||
case spu_itype::BRHNZ:
|
||||
{
|
||||
const u32 next_pc = spu_branch_target(pos, 1);
|
||||
const u32 target = spu_branch_target(pos, op.i16);
|
||||
|
||||
const bool is_u16_jump = type == spu_itype::BRHZ || type == spu_itype::BRHNZ;
|
||||
const bool is_jump_zero = (type == spu_itype::BRZ || type == spu_itype::BRHZ) ^ reduced_loop->is_two_block_loop;
|
||||
case spu_itype::BIZ:
|
||||
case spu_itype::BINZ:
|
||||
case spu_itype::BIHZ:
|
||||
case spu_itype::BIHNZ:
|
||||
{
|
||||
if (type == spu_itype::spu_itype::BIZ || type == spu_itype::BINZ || type == spu_itype::BIHZ || type == spu_itype::BIHNZ)
|
||||
{
|
||||
if (op.e || op.d)
|
||||
{
|
||||
break_all_patterns(27);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const bool is_u16_jump = type == spu_itype::BRHZ || type == spu_itype::BRHNZ || type == spu_itype::BIHZ || type == spu_itype::BIHNZ;
|
||||
const bool is_jump_zero = (type == spu_itype::BRZ || type == spu_itype::BRHZ || type == spu_itype::BIZ || type == spu_itype::BIHZ) ^ reduced_loop->is_two_block_loop;
|
||||
|
||||
while (reduced_loop->active)
|
||||
{
|
||||
@ -6598,7 +6612,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
|
||||
for (u32 i = 0; i < reg->regs.size() && reduced_loop->active; i++)
|
||||
{
|
||||
if (reg->regs.test(i))
|
||||
if (::at32(reg->regs, i))
|
||||
{
|
||||
if (0) if (i == op_rt || reg->modified == 0)
|
||||
{
|
||||
@ -6644,11 +6658,11 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
auto reg_org = reduced_loop->find_reg(i);
|
||||
u32 reg_index = i;
|
||||
|
||||
if (reg_org && !cond_val_incr_before_cond && reg_org->modified == 0 && reg_org->regs.count() - 1u <= 1u && !reg_org->regs.test(i))
|
||||
if (reg_org && !cond_val_incr_before_cond && reg_org->modified == 0 && reg_org->regs.count() - 1u <= 1u && !::at32(reg_org->regs, i))
|
||||
{
|
||||
for (u32 j = 0; j <= s_reg_127; j++)
|
||||
{
|
||||
if (reg_org->regs.test(j))
|
||||
if (::at32(reg_org->regs, j))
|
||||
{
|
||||
if (const auto reg_found = reduced_loop->find_reg(j))
|
||||
{
|
||||
@ -6728,8 +6742,8 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
{
|
||||
reduced_loop->cond_val_incr_is_immediate = false;
|
||||
|
||||
const u32 op_ra = spu_opcode_t{reg->IMM}.ra;
|
||||
const u32 op_rb = spu_opcode_t{reg->IMM}.rb;
|
||||
const u32 op_ra = spu_opcode_t{reg_org->IMM}.ra;
|
||||
const u32 op_rb = spu_opcode_t{reg_org->IMM}.rb;
|
||||
|
||||
if (!(op_ra == reg_index || op_rb == reg_index))
|
||||
{
|
||||
@ -7040,11 +7054,11 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
const auto& b = ::at32(m_bbs, reduced_loop->loop_pc);
|
||||
const auto& b2 = ::at32(m_bbs, bpc);
|
||||
|
||||
if (!reduced_loop->loop_dicts.test(i))
|
||||
if (!::at32(reduced_loop->loop_dicts, i))
|
||||
{
|
||||
if (b.reg_use[i] || (!b.reg_mod.test(i) && b2.reg_use[i]))
|
||||
if (b.reg_use[i] || (!::at32(b.reg_mod, i) && b2.reg_use[i]))
|
||||
{
|
||||
if ((b.reg_use[i] && b.reg_mod.test(i)) || b2.reg_mod.test(i))
|
||||
if ((b.reg_use[i] && ::at32(b.reg_mod, i)) || ::at32(b2.reg_mod, i))
|
||||
{
|
||||
reduced_loop->is_constant_expression = false;
|
||||
reduced_loop->loop_writes.set(i);
|
||||
@ -8298,17 +8312,17 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
|
||||
u32 ra = s_reg_max, rb = s_reg_max, rc = s_reg_max;
|
||||
|
||||
if (m_use_ra.test(pos / 4))
|
||||
if (::at32(m_use_ra, pos / 4))
|
||||
{
|
||||
ra = op.ra;
|
||||
}
|
||||
|
||||
if (m_use_rb.test(pos / 4))
|
||||
if (::at32(m_use_rb, pos / 4))
|
||||
{
|
||||
rb = op.rb;
|
||||
}
|
||||
|
||||
if (m_use_rc.test(pos / 4))
|
||||
if (::at32(m_use_rc, pos / 4))
|
||||
{
|
||||
rc = op.rc;
|
||||
}
|
||||
@ -8575,7 +8589,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
|
||||
for (u32 i = 0; i < s_reg_max; i++)
|
||||
{
|
||||
if (pattern.loop_writes.test(i))
|
||||
if (::at32(pattern.loop_writes, i))
|
||||
{
|
||||
if (regs.size() != 1)
|
||||
{
|
||||
@ -8585,7 +8599,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
|
||||
fmt::append(regs, " r%u-w", i);
|
||||
}
|
||||
|
||||
if (pattern.loop_args.test(i))
|
||||
if (::at32(pattern.loop_args, i))
|
||||
{
|
||||
if (regs.size() != 1)
|
||||
{
|
||||
|
||||
@ -180,7 +180,7 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
|
||||
|
||||
bool is_gpr_not_NaN_hint(u32 i) const noexcept
|
||||
{
|
||||
return block_wide_reg_store_elimination && bb->reg_maybe_float[i] && bb->reg_use[i] >= 3 && !bb->reg_mod[i];
|
||||
return block_wide_reg_store_elimination && ::at32(bb->reg_maybe_float, i) && ::at32(bb->reg_use, i) >= 3 && !::at32(bb->reg_mod, i);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2536,6 +2536,11 @@ public:
|
||||
condition = m_ir->CreateAnd(cond_nans, condition);
|
||||
prev_i = umax;
|
||||
}
|
||||
|
||||
if (is_last)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,17 @@
|
||||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
// std::bitset
|
||||
template <typename CT, typename T>
|
||||
requires requires(std::remove_cvref_t<CT>& x, T&& y) { x.count(); x.test(y); x.flip(y); }
|
||||
[[nodiscard]] constexpr bool at32(CT&& container, T&& index, std::source_location src_loc = std::source_location::current())
|
||||
{
|
||||
const usz csv = container.size();
|
||||
if (csv <= std::forward<T>(index)) [[unlikely]]
|
||||
fmt::raw_range_error(src_loc, format_object_simplified(index), csv);
|
||||
return container[std::forward<T>(index)];
|
||||
}
|
||||
|
||||
// Helper class
|
||||
class spu_cache
|
||||
{
|
||||
@ -421,7 +432,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
return regs.count() == 1 && regs.test(reg_val);
|
||||
return regs.count() == 1 && ::at32(regs, reg_val);
|
||||
}
|
||||
|
||||
bool is_loop_dictator(u32 reg_val, bool test_predictable = false, bool should_predictable = true) const
|
||||
@ -431,7 +442,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (regs.count() >= 1 && regs.test(reg_val))
|
||||
if (regs.count() >= 1 && ::at32(regs, reg_val))
|
||||
{
|
||||
if (!test_predictable)
|
||||
{
|
||||
@ -490,7 +501,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (regs.count() - (regs.test(reg_val) ? 1 : 0))
|
||||
if (regs.count() - (::at32(regs, reg_val) ? 1 : 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -140,6 +140,32 @@ bool verify_mself(const fs::file& mself_file)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: May not be thread-safe (or even, process-safe)
|
||||
bool has_non_directory_components(std::string_view path)
|
||||
{
|
||||
std::string path0{path};
|
||||
|
||||
while (true)
|
||||
{
|
||||
const std::string sub_path = fs::get_parent_dir(path0);
|
||||
|
||||
if (sub_path.size() >= path0.size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
fs::stat_t stat{};
|
||||
if (fs::get_stat(sub_path, stat))
|
||||
{
|
||||
return !stat.is_directory;
|
||||
}
|
||||
|
||||
path0 = std::move(sub_path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
lv2_fs_mount_info_map::lv2_fs_mount_info_map()
|
||||
{
|
||||
for (auto mp = &g_mp_sys_dev_root; mp; mp = mp->next) // Scan and keep track of pre-mounted devices
|
||||
@ -899,8 +925,17 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir: return {CELL_ENOTDIR};
|
||||
case fs::error::noent: return {CELL_ENOENT};
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return {CELL_ENOTDIR};
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1372,6 +1407,11 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> fd)
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
@ -1555,6 +1595,10 @@ error_code sys_fs_stat(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<CellFsStat>
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
// Try to analyse split file (TODO)
|
||||
@ -1594,6 +1638,11 @@ error_code sys_fs_stat(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<CellFsStat>
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
@ -1720,6 +1769,10 @@ error_code sys_fs_mkdir(ppu_thread& ppu, vm::cptr<char> path, s32 mode)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
|
||||
@ -1728,7 +1781,15 @@ error_code sys_fs_mkdir(ppu_thread& ppu, vm::cptr<char> path, s32 mode)
|
||||
{
|
||||
return {sys_fs.warning, CELL_EEXIST, path};
|
||||
}
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1789,9 +1850,18 @@ error_code sys_fs_rename(ppu_thread& ppu, vm::cptr<char> from, vm::cptr<char> to
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir: return {CELL_ENOTDIR, from};
|
||||
case fs::error::noent: return {CELL_ENOENT, from};
|
||||
case fs::error::exist: return {CELL_EEXIST, to};
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_from))
|
||||
{
|
||||
return {CELL_ENOTDIR, from};
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1842,9 +1912,18 @@ error_code sys_fs_rmdir(ppu_thread& ppu, vm::cptr<char> path)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir: return {CELL_ENOTDIR, path};
|
||||
case fs::error::noent: return {CELL_ENOENT, path};
|
||||
case fs::error::notempty: return {CELL_ENOTEMPTY, path};
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1896,11 +1975,23 @@ error_code sys_fs_unlink(ppu_thread& ppu, vm::cptr<char> path)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
|
||||
}
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2737,7 +2828,15 @@ error_code sys_fs_get_block_size(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u
|
||||
{
|
||||
case fs::error::exist: return {CELL_EISDIR, path};
|
||||
case fs::error::noent: return {CELL_ENOENT, path};
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2789,11 +2888,23 @@ error_code sys_fs_truncate(ppu_thread& ppu, vm::cptr<char> path, u64 size)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
|
||||
}
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2840,7 +2951,10 @@ error_code sys_fs_ftruncate(ppu_thread& ppu, u32 fd, u64 size)
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::ok:
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2887,6 +3001,10 @@ error_code sys_fs_chmod(ppu_thread&, vm::cptr<char> path, s32 mode)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
// Try to locate split files
|
||||
@ -2900,8 +3018,12 @@ error_code sys_fs_chmod(ppu_thread&, vm::cptr<char> path, s32 mode)
|
||||
}
|
||||
default:
|
||||
{
|
||||
sys_fs.error("sys_fs_chmod(): unknown error %s", error);
|
||||
return {CELL_EIO, path};
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3033,11 +3155,23 @@ error_code sys_fs_utime(ppu_thread& ppu, vm::cptr<char> path, vm::cptr<CellFsUti
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
|
||||
}
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -221,6 +221,7 @@ namespace rsx
|
||||
home_menu_settings_overlays::home_menu_settings_overlays(s16 x, s16 y, u16 width, u16 height, bool use_separators, home_menu_page* parent)
|
||||
: home_menu_settings_page(x, y, width, height, use_separators, parent, get_localized_string(localized_string_id::HOME_MENU_SETTINGS_OVERLAYS))
|
||||
{
|
||||
add_checkbox(&g_cfg.misc.play_music_during_boot, localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_PLAY_MUSIC_DURING_BOOT);
|
||||
add_checkbox(&g_cfg.misc.show_trophy_popups, localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_TROPHY_POPUPS);
|
||||
add_checkbox(&g_cfg.misc.show_rpcn_popups, localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_RPCN_POPUPS);
|
||||
add_checkbox(&g_cfg.misc.show_shader_compilation_hint, localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_SHADER_COMPILATION_HINT);
|
||||
@ -229,6 +230,7 @@ namespace rsx
|
||||
add_checkbox(&g_cfg.misc.show_pressure_intensity_toggle_hint, localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_PRESSURE_INTENSITY_TOGGLE_HINT);
|
||||
add_checkbox(&g_cfg.misc.show_analog_limiter_toggle_hint, localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_ANALOG_LIMITER_TOGGLE_HINT);
|
||||
add_checkbox(&g_cfg.misc.show_mouse_and_keyboard_toggle_hint, localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_MOUSE_AND_KB_TOGGLE_HINT);
|
||||
add_checkbox(&g_cfg.misc.show_fatal_error_hints, localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_FATAL_ERROR_HINTS);
|
||||
add_checkbox(&g_cfg.video.record_with_overlays, localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_RECORD_WITH_OVERLAYS);
|
||||
|
||||
apply_layout();
|
||||
|
||||
@ -343,7 +343,8 @@ namespace rsx::assembler::FP
|
||||
std::unordered_set<u32> inputs;
|
||||
SRC_Common src { .HEX = instruction->bytecode[operand + 1] };
|
||||
|
||||
if (src.reg_type != RSX_FP_REGISTER_TYPE_TEMP)
|
||||
if (src.reg_type != RSX_FP_REGISTER_TYPE_TEMP &&
|
||||
src.reg_type != RSX_FP_REGISTER_TYPE_INPUT)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -418,6 +418,11 @@ namespace glsl
|
||||
enabled_options.push_back("_ENABLE_DEPTH_FORMAT_RECONSTRUCTION");
|
||||
}
|
||||
|
||||
if (props.require_msaa_ops)
|
||||
{
|
||||
enabled_options.push_back("_ENABLE_TEXTURE_MULTISAMPLE");
|
||||
}
|
||||
|
||||
program_common::define_glsl_switches(OS, enabled_options);
|
||||
enabled_options.clear();
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ R"(
|
||||
_texture_bx2_active = false; \
|
||||
} while (false)
|
||||
#define TEX_FLAGS(index) ((TEX_PARAM(index).flags & ~(_texture_flag_erase)) | _texture_flag_override)
|
||||
#elif defined(_ENABLE_TEXTURE_ALPHA_KILL) || defined(_ENABLE_FORMAT_CONVERSION) || defined(_ENABLE_DEPTH_FORMAT_RECONSTRUCTION)
|
||||
#elif defined(_ENABLE_TEXTURE_ALPHA_KILL) || defined(_ENABLE_FORMAT_CONVERSION) || defined(_ENABLE_DEPTH_FORMAT_RECONSTRUCTION) || defined(_ENABLE_TEXTURE_MULTISAMPLE)
|
||||
#define TEX_FLAGS(index) (TEX_PARAM(index).flags)
|
||||
#else
|
||||
#define TEX_FLAGS(index) 0
|
||||
|
||||
@ -712,9 +712,12 @@ namespace rsx
|
||||
{
|
||||
m_overlay_manager = g_fxo->init<rsx::overlays::display_manager>(0);
|
||||
|
||||
if (const std::string audio_path = Emu.GetSfoDir(true) + "/SND0.AT3"; fs::is_file(audio_path))
|
||||
if (g_cfg.misc.play_music_during_boot)
|
||||
{
|
||||
m_overlay_manager->start_audio(audio_path);
|
||||
if (const std::string audio_path = Emu.GetSfoDir(true) + "/SND0.AT3"; fs::is_file(audio_path))
|
||||
{
|
||||
m_overlay_manager->start_audio(audio_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -254,7 +254,9 @@ enum class localized_string_id
|
||||
HOME_MENU_SETTINGS_OVERLAYS_SHOW_PRESSURE_INTENSITY_TOGGLE_HINT,
|
||||
HOME_MENU_SETTINGS_OVERLAYS_SHOW_ANALOG_LIMITER_TOGGLE_HINT,
|
||||
HOME_MENU_SETTINGS_OVERLAYS_SHOW_MOUSE_AND_KB_TOGGLE_HINT,
|
||||
HOME_MENU_SETTINGS_OVERLAYS_SHOW_FATAL_ERROR_HINTS,
|
||||
HOME_MENU_SETTINGS_OVERLAYS_RECORD_WITH_OVERLAYS,
|
||||
HOME_MENU_SETTINGS_OVERLAYS_PLAY_MUSIC_DURING_BOOT,
|
||||
HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY,
|
||||
HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY_ENABLE,
|
||||
HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY_ENABLE_FRAMERATE_GRAPH,
|
||||
|
||||
@ -357,12 +357,14 @@ struct cfg_root : cfg::node
|
||||
cfg::_bool show_pressure_intensity_toggle_hint{ this, "Show pressure intensity toggle hint", true, true };
|
||||
cfg::_bool show_analog_limiter_toggle_hint{ this, "Show analog limiter toggle hint", true, true };
|
||||
cfg::_bool show_mouse_and_keyboard_toggle_hint{ this, "Show mouse and keyboard toggle hint", true, true };
|
||||
cfg::_bool show_fatal_error_hints{ this, "Show fatal error hints", false, true };
|
||||
cfg::_bool show_capture_hints{ this, "Show capture hints", true, true };
|
||||
cfg::_bool use_native_interface{ this, "Use native user interface", true };
|
||||
cfg::string gdb_server{ this, "GDB Server", "127.0.0.1:2345" };
|
||||
cfg::_bool silence_all_logs{ this, "Silence All Logs", false, true };
|
||||
cfg::string title_format{ this, "Window Title Format", "FPS: %F | %R | %V | %T [%t]", true };
|
||||
cfg::_bool pause_during_home_menu{this, "Pause Emulation During Home Menu", false, false };
|
||||
cfg::_bool play_music_during_boot{this, "Play music during boot sequence", true, true };
|
||||
cfg::_bool enable_gamemode{ this, "Enable GameMode", false, false };
|
||||
|
||||
} misc{ this };
|
||||
|
||||
@ -585,10 +585,8 @@ std::unique_ptr<fs::dir_base> iso_device::open_dir(const std::string& path)
|
||||
|
||||
if (!node->metadata.is_directory)
|
||||
{
|
||||
// fs::dir::open -> ::readdir should return ENOTDIR when path is
|
||||
// pointing to a file instead of a folder, which translates to error::unknown.
|
||||
// doing the same here.
|
||||
fs::g_tls_error = fs::error::unknown;
|
||||
// fs::dir::open -> ::readdir should return ENOTDIR when path is pointing to a file instead of a folder.
|
||||
fs::g_tls_error = fs::error::notdir;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -68,6 +68,7 @@ DYNAMIC_IMPORT("ntdll.dll", NtSetTimerResolution, NTSTATUS(ULONG DesiredResoluti
|
||||
#include "util/media_utils.h"
|
||||
#include "rpcs3_version.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/system_utils.hpp"
|
||||
#include "Emu/RSX/Overlays/overlay_message.h"
|
||||
#include <thread>
|
||||
@ -353,11 +354,14 @@ public:
|
||||
#endif
|
||||
if (msg == logs::level::fatal)
|
||||
{
|
||||
std::string overlay_msg = "Fatal error: " + _msg.substr(rpcs3_prefix.size());
|
||||
fmt::trim_back(overlay_msg, " \t\n");
|
||||
if (g_cfg.misc.show_fatal_error_hints)
|
||||
{
|
||||
std::string overlay_msg = "Fatal error: " + _msg.substr(rpcs3_prefix.size());
|
||||
fmt::trim_back(overlay_msg, " \t\n");
|
||||
rsx::overlays::queue_message(overlay_msg, umax);
|
||||
}
|
||||
|
||||
// Pause emulation if fatal error encountered
|
||||
rsx::overlays::queue_message(overlay_msg, umax);
|
||||
Emu.Pause(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ debugger_frame::debugger_frame(std::shared_ptr<gui_settings> gui_settings, QWidg
|
||||
: custom_dock_widget(tr("Debugger [Press F1 for Help]"), parent)
|
||||
, m_gui_settings(std::move(gui_settings))
|
||||
{
|
||||
setObjectName("debugger");
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_update = new QTimer(this);
|
||||
|
||||
@ -189,9 +189,11 @@ enum class emu_settings_type
|
||||
ShowPressureIntensityToggleHint,
|
||||
ShowAnalogLimiterToggleHint,
|
||||
ShowMouseAndKeyboardToggleHint,
|
||||
ShowFatalErrorHints,
|
||||
ShowCaptureHints,
|
||||
WindowTitleFormat,
|
||||
PauseDuringHomeMenu,
|
||||
PlayMusicDuringBoot,
|
||||
EnableGamemode,
|
||||
|
||||
// Network
|
||||
@ -405,10 +407,12 @@ inline static const std::map<emu_settings_type, cfg_location> settings_location
|
||||
{ emu_settings_type::ShowPressureIntensityToggleHint, { "Miscellaneous", "Show pressure intensity toggle hint"}},
|
||||
{ emu_settings_type::ShowAnalogLimiterToggleHint, { "Miscellaneous", "Show analog limiter toggle hint"}},
|
||||
{ emu_settings_type::ShowMouseAndKeyboardToggleHint, { "Miscellaneous", "Show mouse and keyboard toggle hint"}},
|
||||
{ emu_settings_type::ShowFatalErrorHints, { "Miscellaneous", "Show fatal error hints"}},
|
||||
{ emu_settings_type::ShowCaptureHints, { "Miscellaneous", "Show capture hints" }},
|
||||
{ emu_settings_type::SilenceAllLogs, { "Miscellaneous", "Silence All Logs" }},
|
||||
{ emu_settings_type::WindowTitleFormat, { "Miscellaneous", "Window Title Format" }},
|
||||
{ emu_settings_type::PauseDuringHomeMenu, { "Miscellaneous", "Pause Emulation During Home Menu" }},
|
||||
{ emu_settings_type::PlayMusicDuringBoot, { "Miscellaneous", "Play music during boot sequence" }},
|
||||
{ emu_settings_type::EnableGamemode, { "Miscellaneous", "Enable GameMode" }},
|
||||
|
||||
// Networking
|
||||
|
||||
@ -40,6 +40,8 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> gui_settings, std
|
||||
, m_emu_settings(std::move(emu_settings))
|
||||
, m_persistent_settings(std::move(persistent_settings))
|
||||
{
|
||||
setObjectName("gamelist");
|
||||
|
||||
m_game_list_actions = std::make_shared<game_list_actions>(this, m_gui_settings);
|
||||
|
||||
m_icon_size = gui::gl_icon_size_min; // ensure a valid size
|
||||
|
||||
@ -173,7 +173,7 @@ namespace gui
|
||||
const gui_save fd_save_log = gui_save(main_window, "lastExplorePathSaveLog", "");
|
||||
|
||||
const gui_save mw_debugger = gui_save(main_window, "debuggerVisible", false);
|
||||
const gui_save mw_logger = gui_save(main_window, "loggerVisible", true);
|
||||
const gui_save mw_logger = gui_save(main_window, "loggerVisible", false);
|
||||
const gui_save mw_gamelist = gui_save(main_window, "gamelistVisible", true);
|
||||
const gui_save mw_toolBarVisible = gui_save(main_window, "toolBarVisible", true);
|
||||
const gui_save mw_titleBarsVisible = gui_save(main_window, "titleBarsVisible", true);
|
||||
|
||||
@ -274,7 +274,9 @@ private:
|
||||
case localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_PRESSURE_INTENSITY_TOGGLE_HINT: return tr("Show Pressure Intensity Toggle Hint", "Overlays");
|
||||
case localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_ANALOG_LIMITER_TOGGLE_HINT: return tr( "Show Analog Limiter Toggle Hint", "Overlays");
|
||||
case localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_MOUSE_AND_KB_TOGGLE_HINT: return tr("Show Mouse And Keyboard Toggle Hint", "Overlays");
|
||||
case localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_SHOW_FATAL_ERROR_HINTS: return tr("Show Fatal Error Hints", "Overlays");
|
||||
case localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_RECORD_WITH_OVERLAYS: return tr("Record With Overlays", "Overlays");
|
||||
case localized_string_id::HOME_MENU_SETTINGS_OVERLAYS_PLAY_MUSIC_DURING_BOOT: return tr("Play music during boot sequence.", "Overlays");
|
||||
case localized_string_id::HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY: return tr("Performance Overlay");
|
||||
case localized_string_id::HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY_ENABLE: return tr("Enable Performance Overlay", "Performance Overlay");
|
||||
case localized_string_id::HOME_MENU_SETTINGS_PERFORMANCE_OVERLAY_ENABLE_FRAMERATE_GRAPH: return tr("Enable Framerate Graph", "Performance Overlay");
|
||||
|
||||
@ -113,6 +113,8 @@ static gui_listener s_gui_listener;
|
||||
log_frame::log_frame(std::shared_ptr<gui_settings> _gui_settings, QWidget* parent)
|
||||
: custom_dock_widget(tr("Log"), parent), m_gui_settings(std::move(_gui_settings))
|
||||
{
|
||||
setObjectName("logger");
|
||||
|
||||
const int max_block_count_log = m_gui_settings->GetValue(gui::l_limit).toInt();
|
||||
const int max_block_count_tty = m_gui_settings->GetValue(gui::l_limit_tty).toInt();
|
||||
|
||||
|
||||
@ -3512,11 +3512,8 @@ void main_window::CreateDockWindows()
|
||||
m_mw->setContextMenuPolicy(Qt::PreventContextMenu);
|
||||
|
||||
m_game_list_frame = new game_list_frame(m_gui_settings, m_emu_settings, m_persistent_settings, m_mw);
|
||||
m_game_list_frame->setObjectName("gamelist");
|
||||
m_debugger_frame = new debugger_frame(m_gui_settings, m_mw);
|
||||
m_debugger_frame->setObjectName("debugger");
|
||||
m_log_frame = new log_frame(m_gui_settings, m_mw);
|
||||
m_log_frame->setObjectName("logger");
|
||||
|
||||
m_mw->addDockWidget(Qt::LeftDockWidgetArea, m_game_list_frame);
|
||||
m_mw->addDockWidget(Qt::LeftDockWidgetArea, m_log_frame);
|
||||
|
||||
@ -1829,6 +1829,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
ui->enableGamemode->setVisible(false);
|
||||
#endif
|
||||
|
||||
m_emu_settings->EnhanceCheckBox(ui->playMusicDuringBoot, emu_settings_type::PlayMusicDuringBoot);
|
||||
SubscribeTooltip(ui->playMusicDuringBoot, tooltips.settings.play_music_during_boot);
|
||||
|
||||
m_emu_settings->EnhanceCheckBox(ui->showShaderCompilationHint, emu_settings_type::ShowShaderCompilationHint);
|
||||
SubscribeTooltip(ui->showShaderCompilationHint, tooltips.settings.show_shader_compilation_hint);
|
||||
|
||||
@ -1847,6 +1850,9 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
m_emu_settings->EnhanceCheckBox(ui->showMouseAndKeyboardToggleHint, emu_settings_type::ShowMouseAndKeyboardToggleHint);
|
||||
SubscribeTooltip(ui->showMouseAndKeyboardToggleHint, tooltips.settings.show_mouse_and_keyboard_toggle_hint);
|
||||
|
||||
m_emu_settings->EnhanceCheckBox(ui->showFatalErrorHints, emu_settings_type::ShowFatalErrorHints);
|
||||
SubscribeTooltip(ui->showFatalErrorHints, tooltips.settings.show_fatal_error_hints);
|
||||
|
||||
m_emu_settings->EnhanceCheckBox(ui->showCaptureHints, emu_settings_type::ShowCaptureHints);
|
||||
SubscribeTooltip(ui->showCaptureHints, tooltips.settings.show_capture_hints);
|
||||
|
||||
|
||||
@ -3009,6 +3009,13 @@
|
||||
<string>Overlay Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="gb_overlay_settings_layout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="playMusicDuringBoot">
|
||||
<property name="text">
|
||||
<string>Play music during boot sequence</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="recordWithOverlays">
|
||||
<property name="text">
|
||||
@ -3037,6 +3044,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showFatalErrorHints">
|
||||
<property name="text">
|
||||
<string>Show fatal error hints</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="showMouseAndKeyboardToggleHint">
|
||||
<property name="text">
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <set>
|
||||
|
||||
struct gui_game_info;
|
||||
class iso_archive;
|
||||
|
||||
@ -154,10 +154,12 @@ public:
|
||||
const QString show_pressure_intensity_toggle_hint = tr("Shows pressure intensity toggle hint using the native overlay.");
|
||||
const QString show_analog_limiter_toggle_hint = tr("Shows analog limiter toggle hint using the native overlay.");
|
||||
const QString show_mouse_and_keyboard_toggle_hint = tr("Shows mouse and keyboard toggle hint using the native overlay.");
|
||||
const QString show_fatal_error_hints = tr("Shows fatal error hints using the native overlay.");
|
||||
const QString show_capture_hints = tr("Shows screenshot and recording hints using the native overlay.");
|
||||
const QString use_native_interface = tr("Enables use of native HUD within the game window that can interact with game controllers.\nWhen disabled, regular Qt dialogs are used instead.\nCurrently, the on-screen keyboard only supports the English key layout.");
|
||||
const QString record_with_overlays = tr("Enables recording with overlays.\nThis also affects screenshots.");
|
||||
const QString pause_during_home_menu = tr("When enabled, opening the home menu will also pause emulation.\nWhile most games pause themselves while the home menu is shown, some do not.\nIn that case it can be helpful to pause the emulation whenever the home menu is open.");
|
||||
const QString play_music_during_boot = tr("Play music during boot sequence if available.");
|
||||
|
||||
const QString perf_overlay_enabled = tr("Enables or disables the performance overlay.");
|
||||
const QString perf_overlay_framerate_graph_enabled = tr("Enables or disables the framerate graph.");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user