mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
Implement read_from_ptr<>() util
Doing std::bit_cast on a "span". Should be usable in constexpr.
This commit is contained in:
parent
bf388e5428
commit
7c15001042
9 changed files with 71 additions and 38 deletions
|
@ -1698,7 +1698,7 @@ error_code cellDiscGameGetBootDiscInfo(vm::ptr<CellDiscGameSystemFileParam> getP
|
|||
}
|
||||
|
||||
// Always sets 0 at first dword
|
||||
*utils::bless<nse_t<u32, 1>>(getParam->titleId + 0) = 0;
|
||||
write_to_ptr<u32>(getParam->titleId, 0);
|
||||
|
||||
// This is also called by non-disc games, see NPUB90029
|
||||
static const std::string dir = "/dev_bdvd/PS3_GAME"s;
|
||||
|
|
|
@ -296,8 +296,8 @@ error_code cellGifDecReadHeader(vm::ptr<GifDecoder> mainHandle, vm::ptr<GifStrea
|
|||
default: break; // TODO
|
||||
}
|
||||
|
||||
if (*utils::bless<be_t<u32>>(buffer + 0) != 0x47494638u ||
|
||||
(*utils::bless<le_t<u16>>(buffer + 4) != 0x6139u && *utils::bless<le_t<u16>>(buffer + 4) != 0x6137u)) // Error: The first 6 bytes are not a valid GIF signature
|
||||
if (read_from_ptr<be_t<u32>>(buffer + 0) != 0x47494638u ||
|
||||
(read_from_ptr<le_t<u16>>(buffer + 4) != 0x6139u && read_from_ptr<le_t<u16>>(buffer + 4) != 0x6137u)) // Error: The first 6 bytes are not a valid GIF signature
|
||||
{
|
||||
return CELL_GIFDEC_ERROR_STREAM_FORMAT; // Surprisingly there is no error code related with headerss
|
||||
}
|
||||
|
|
|
@ -150,8 +150,8 @@ error_code cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellJpgDe
|
|||
default: break; // TODO
|
||||
}
|
||||
|
||||
if (*utils::bless<le_t<u32>>(buffer.get() + 0) != 0xE0FFD8FF || // Error: Not a valid SOI header
|
||||
*utils::bless<u32>(buffer.get() + 6) != "JFIF"_u32) // Error: Not a valid JFIF string
|
||||
if (read_from_ptr<le_t<u32>>(buffer.get() + 0) != 0xE0FFD8FF || // Error: Not a valid SOI header
|
||||
read_from_ptr<u32>(buffer.get() + 6) != "JFIF"_u32) // Error: Not a valid JFIF string
|
||||
{
|
||||
return CELL_JPGDEC_ERROR_HEADER;
|
||||
}
|
||||
|
|
|
@ -92,10 +92,10 @@ void sky_portal::get_status(u8* reply_buf)
|
|||
}
|
||||
|
||||
std::memset(reply_buf, 0, 0x20);
|
||||
reply_buf[0] = 0x53;
|
||||
*utils::bless<le_t<u16>>(reply_buf + 1) = status;
|
||||
reply_buf[5] = interrupt_counter++;
|
||||
reply_buf[6] = 0x01;
|
||||
reply_buf[0] = 0x53;
|
||||
write_to_ptr<le_t<u16>>(reply_buf, 1, status);
|
||||
reply_buf[5] = interrupt_counter++;
|
||||
reply_buf[6] = 0x01;
|
||||
}
|
||||
|
||||
void sky_portal::query_block(u8 sky_num, u8 block, u8* reply_buf)
|
||||
|
@ -159,7 +159,7 @@ u8 sky_portal::load_skylander(u8* buf, fs::file in_file)
|
|||
{
|
||||
std::lock_guard lock(sky_mutex);
|
||||
|
||||
u32 sky_serial = *utils::bless<le_t<u32>>(buf);
|
||||
u32 sky_serial = read_from_ptr<le_t<u32>>(buf);
|
||||
u8 found_slot = 0xFF;
|
||||
|
||||
// mimics spot retaining on the portal
|
||||
|
|
|
@ -192,9 +192,9 @@ namespace np
|
|||
}
|
||||
|
||||
ticket_data tdata{};
|
||||
const auto* ptr = data() + index;
|
||||
tdata.id = *reinterpret_cast<const be_t<u16>*>(ptr);
|
||||
tdata.len = *reinterpret_cast<const be_t<u16>*>(ptr + 2);
|
||||
const auto* ptr = data() + index;
|
||||
tdata.id = read_from_ptr<be_t<u16>>(ptr);
|
||||
tdata.len = read_from_ptr<be_t<u16>>(ptr + 2);
|
||||
const auto* data_ptr = data() + index + 4;
|
||||
|
||||
auto check_size = [&](std::size_t expected) -> bool
|
||||
|
@ -219,7 +219,7 @@ namespace np
|
|||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
tdata.data.data_u32 = *reinterpret_cast<const be_t<u32>*>(data_ptr);
|
||||
tdata.data.data_u32 = read_from_ptr<be_t<u32>>(data_ptr);
|
||||
break;
|
||||
case 2:
|
||||
case 7:
|
||||
|
@ -227,7 +227,7 @@ namespace np
|
|||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
tdata.data.data_u64 = *reinterpret_cast<const be_t<u64>*>(data_ptr);
|
||||
tdata.data.data_u64 = read_from_ptr<be_t<u64>>(data_ptr);
|
||||
break;
|
||||
case 4:
|
||||
case 8:
|
||||
|
@ -277,14 +277,14 @@ namespace np
|
|||
return;
|
||||
}
|
||||
|
||||
version = *reinterpret_cast<const be_t<u32>*>(data());
|
||||
version = read_from_ptr<be_t<u32>>(data());
|
||||
if (version != 0x21010000)
|
||||
{
|
||||
ticket_log.error("Invalid version: 0x%08x", version);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 given_size = *reinterpret_cast<const be_t<u32>*>(data() + 4);
|
||||
u32 given_size = read_from_ptr<be_t<u32>>(data() + 4);
|
||||
if ((given_size + 8) != size())
|
||||
{
|
||||
ticket_log.error("Size mismatch (gs: %d vs s: %d)", given_size, size());
|
||||
|
@ -471,7 +471,7 @@ namespace np
|
|||
return;
|
||||
}
|
||||
|
||||
local_ip_addr = *reinterpret_cast<u32*>(host->h_addr_list[0]);
|
||||
local_ip_addr = read_from_ptr<u32>(host->h_addr_list[0]);
|
||||
|
||||
// Set public address to local discovered address for now, may be updated later from RPCN socket
|
||||
public_ip_addr = local_ip_addr;
|
||||
|
|
|
@ -206,10 +206,10 @@ namespace np
|
|||
return;
|
||||
}
|
||||
|
||||
const u64 room_id = reinterpret_cast<le_t<u64>&>(data[0]);
|
||||
const u16 member_id = reinterpret_cast<le_t<u16>&>(data[8]);
|
||||
const u16 port_p2p = reinterpret_cast<be_t<u16>&>(data[10]);
|
||||
const u32 addr_p2p = reinterpret_cast<le_t<u32>&>(data[12]);
|
||||
const u64 room_id = read_from_ptr<le_t<u64>>(data);
|
||||
const u16 member_id = read_from_ptr<le_t<u16>>(data, 8);
|
||||
const u16 port_p2p = read_from_ptr<be_t<u16>>(data, 10);
|
||||
const u32 addr_p2p = read_from_ptr<le_t<u32>>(data, 12);
|
||||
|
||||
rpcn_log.notice("Received notification to connect to member(%d) of room(%d): %s:%d", member_id, room_id, ip_to_string(addr_p2p), port_p2p);
|
||||
|
||||
|
|
|
@ -705,8 +705,7 @@ namespace rsx
|
|||
std::vector<u8> marker(range.length() + sizeof(overrun_cookie_value), 0);
|
||||
|
||||
// Tag end
|
||||
u32* overrun_test_ptr = utils::bless<u32>(marker.data() + range.length());
|
||||
*overrun_test_ptr = overrun_cookie_value;
|
||||
write_to_ptr(marker, range.length(), overrun_cookie_value);
|
||||
|
||||
u32 removed_count = 0;
|
||||
|
||||
|
@ -717,10 +716,10 @@ namespace rsx
|
|||
|
||||
while (length >= 8)
|
||||
{
|
||||
auto& value = *utils::bless<u64>(dst_ptr);
|
||||
const u64 value = read_from_ptr<u64>(dst_ptr);
|
||||
const u64 block_mask = ~value; // If the value is not all 1s, set valid to true
|
||||
mask |= block_mask;
|
||||
value = umax;
|
||||
write_to_ptr<u64>(dst_ptr, umax);
|
||||
|
||||
dst_ptr += 8;
|
||||
length -= 8;
|
||||
|
@ -728,10 +727,10 @@ namespace rsx
|
|||
|
||||
if (length >= 4)
|
||||
{
|
||||
auto& value = *utils::bless<u32>(dst_ptr);
|
||||
const u32 value = read_from_ptr<u32>(dst_ptr);
|
||||
const u32 block_mask = ~value;
|
||||
mask |= block_mask;
|
||||
value = umax;
|
||||
write_to_ptr<u32>(dst_ptr, umax);
|
||||
|
||||
dst_ptr += 4;
|
||||
length -= 4;
|
||||
|
@ -739,10 +738,10 @@ namespace rsx
|
|||
|
||||
if (length >= 2)
|
||||
{
|
||||
auto& value = *utils::bless<u16>(dst_ptr);
|
||||
const u16 value = read_from_ptr<u16>(dst_ptr);
|
||||
const u16 block_mask = ~value;
|
||||
mask |= block_mask;
|
||||
value = umax;
|
||||
write_to_ptr<u16>(dst_ptr, umax);
|
||||
|
||||
dst_ptr += 2;
|
||||
length -= 2;
|
||||
|
@ -750,10 +749,10 @@ namespace rsx
|
|||
|
||||
if (length)
|
||||
{
|
||||
auto& value = *dst_ptr;
|
||||
const u8 value = *dst_ptr;
|
||||
const u8 block_mask = ~value;
|
||||
mask |= block_mask;
|
||||
value = umax;
|
||||
*dst_ptr = umax;
|
||||
}
|
||||
|
||||
return !!mask;
|
||||
|
@ -824,7 +823,7 @@ namespace rsx
|
|||
rsx_log.notice("rsx::surface_cache::check_for_duplicates_fallback analysed %u overlapping sections and removed %u", ::size32(sections), removed_count);
|
||||
|
||||
// Verify no OOB
|
||||
ensure(*overrun_test_ptr == overrun_cookie_value);
|
||||
ensure(read_from_ptr<u32>(marker, range.length()) == overrun_cookie_value);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -468,14 +468,14 @@ void ds3_pad_handler::get_extended_info(const pad_ensemble& binding)
|
|||
|
||||
#ifdef _WIN32
|
||||
// Official Sony Windows DS3 driver seems to do the same modification of this value as the ps3
|
||||
pad->m_sensors[0].m_value = *utils::bless<le_t<u16, 1>>(&ds3dev->padData[41 + DS3_HID_OFFSET]);
|
||||
pad->m_sensors[0].m_value = read_from_ptr<le_t<u16>>(ds3dev->padData, 41 + DS3_HID_OFFSET);
|
||||
#else
|
||||
// When getting raw values from the device this adjustement is needed
|
||||
pad->m_sensors[0].m_value = 512 - (*utils::bless<le_t<u16, 1>>(&ds3dev->padData[41]) - 512);
|
||||
pad->m_sensors[0].m_value = 512 - (read_from_ptr<le_t<u16>>(ds3dev->padData, 41 + DS3_HID_OFFSET) - 512);
|
||||
#endif
|
||||
pad->m_sensors[1].m_value = *utils::bless<le_t<u16, 1>>(&ds3dev->padData[45 + DS3_HID_OFFSET]);
|
||||
pad->m_sensors[2].m_value = *utils::bless<le_t<u16, 1>>(&ds3dev->padData[43 + DS3_HID_OFFSET]);
|
||||
pad->m_sensors[3].m_value = *utils::bless<le_t<u16, 1>>(&ds3dev->padData[47 + DS3_HID_OFFSET]);
|
||||
pad->m_sensors[1].m_value = read_from_ptr<le_t<u16>>(ds3dev->padData, 45 + DS3_HID_OFFSET);
|
||||
pad->m_sensors[2].m_value = read_from_ptr<le_t<u16>>(ds3dev->padData, 43 + DS3_HID_OFFSET);
|
||||
pad->m_sensors[3].m_value = read_from_ptr<le_t<u16>>(ds3dev->padData, 47 + DS3_HID_OFFSET);
|
||||
|
||||
// Those are formulas used to adjust sensor values in sys_hid code but I couldn't find all the vars.
|
||||
//auto polish_value = [](s32 value, s32 dword_0x0, s32 dword_0x4, s32 dword_0x8, s32 dword_0xC, s32 dword_0x18, s32 dword_0x1C) -> u16
|
||||
|
|
|
@ -1184,6 +1184,40 @@ namespace stx
|
|||
};
|
||||
}
|
||||
|
||||
// Read object of type T from raw pointer, array, string, vector, or any contiguous container
|
||||
template <typename T, typename U>
|
||||
constexpr T read_from_ptr(U&& array, usz pos = 0)
|
||||
{
|
||||
// TODO: ensure array element types are trivial
|
||||
static_assert(sizeof(T) % sizeof(array[0]) == 0);
|
||||
std::decay_t<decltype(array[0])> buf[sizeof(T) / sizeof(array[0])];
|
||||
if (!std::is_constant_evaluated())
|
||||
std::memcpy(+buf, &array[pos], sizeof(buf));
|
||||
else
|
||||
for (usz i = 0; i < pos; buf[i] = array[pos + i], i++);
|
||||
return std::bit_cast<T>(buf);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
constexpr void write_to_ptr(U&& array, usz pos, const T& value)
|
||||
{
|
||||
static_assert(sizeof(T) % sizeof(array[0]) == 0);
|
||||
if (!std::is_constant_evaluated())
|
||||
std::memcpy(&array[pos], &value, sizeof(value));
|
||||
else
|
||||
ensure(!"Unimplemented");
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
constexpr void write_to_ptr(U&& array, const T& value)
|
||||
{
|
||||
static_assert(sizeof(T) % sizeof(array[0]) == 0);
|
||||
if (!std::is_constant_evaluated())
|
||||
std::memcpy(&array[0], &value, sizeof(value));
|
||||
else
|
||||
ensure(!"Unimplemented");
|
||||
}
|
||||
|
||||
namespace utils
|
||||
{
|
||||
struct serial;
|
||||
|
|
Loading…
Add table
Reference in a new issue