Merge pull request #4182 from wwylele/std-size-t
Prefix all size_t with std::
This commit is contained in:
commit
ca701e2610
158 changed files with 669 additions and 634 deletions
|
@ -26,7 +26,7 @@ using QuadFrame32 = std::array<std::array<s32, 4>, samples_per_frame>;
|
||||||
/// A variable length buffer of signed PCM16 stereo samples.
|
/// A variable length buffer of signed PCM16 stereo samples.
|
||||||
using StereoBuffer16 = std::deque<std::array<s16, 2>>;
|
using StereoBuffer16 = std::deque<std::array<s16, 2>>;
|
||||||
|
|
||||||
constexpr size_t num_dsp_pipe = 8;
|
constexpr std::size_t num_dsp_pipe = 8;
|
||||||
enum class DspPipe {
|
enum class DspPipe {
|
||||||
Debug = 0,
|
Debug = 0,
|
||||||
Dma = 1,
|
Dma = 1,
|
||||||
|
|
|
@ -14,26 +14,26 @@
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
namespace Codec {
|
namespace Codec {
|
||||||
|
|
||||||
StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count,
|
StereoBuffer16 DecodeADPCM(const u8* const data, const std::size_t sample_count,
|
||||||
const std::array<s16, 16>& adpcm_coeff, ADPCMState& state) {
|
const std::array<s16, 16>& adpcm_coeff, ADPCMState& state) {
|
||||||
// GC-ADPCM with scale factor and variable coefficients.
|
// GC-ADPCM with scale factor and variable coefficients.
|
||||||
// Frames are 8 bytes long containing 14 samples each.
|
// Frames are 8 bytes long containing 14 samples each.
|
||||||
// Samples are 4 bits (one nibble) long.
|
// Samples are 4 bits (one nibble) long.
|
||||||
|
|
||||||
constexpr size_t FRAME_LEN = 8;
|
constexpr std::size_t FRAME_LEN = 8;
|
||||||
constexpr size_t SAMPLES_PER_FRAME = 14;
|
constexpr std::size_t SAMPLES_PER_FRAME = 14;
|
||||||
constexpr std::array<int, 16> SIGNED_NIBBLES = {
|
constexpr std::array<int, 16> SIGNED_NIBBLES = {
|
||||||
{0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
|
{0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}};
|
||||||
|
|
||||||
const size_t ret_size =
|
const std::size_t ret_size =
|
||||||
sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two.
|
sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two.
|
||||||
StereoBuffer16 ret(ret_size);
|
StereoBuffer16 ret(ret_size);
|
||||||
|
|
||||||
int yn1 = state.yn1, yn2 = state.yn2;
|
int yn1 = state.yn1, yn2 = state.yn2;
|
||||||
|
|
||||||
const size_t NUM_FRAMES =
|
const std::size_t NUM_FRAMES =
|
||||||
(sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up.
|
(sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up.
|
||||||
for (size_t framei = 0; framei < NUM_FRAMES; framei++) {
|
for (std::size_t framei = 0; framei < NUM_FRAMES; framei++) {
|
||||||
const int frame_header = data[framei * FRAME_LEN];
|
const int frame_header = data[framei * FRAME_LEN];
|
||||||
const int scale = 1 << (frame_header & 0xF);
|
const int scale = 1 << (frame_header & 0xF);
|
||||||
const int idx = (frame_header >> 4) & 0x7;
|
const int idx = (frame_header >> 4) & 0x7;
|
||||||
|
@ -58,9 +58,9 @@ StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count,
|
||||||
return (s16)val;
|
return (s16)val;
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t outputi = framei * SAMPLES_PER_FRAME;
|
std::size_t outputi = framei * SAMPLES_PER_FRAME;
|
||||||
size_t datai = framei * FRAME_LEN + 1;
|
std::size_t datai = framei * FRAME_LEN + 1;
|
||||||
for (size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) {
|
for (std::size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) {
|
||||||
const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]);
|
const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]);
|
||||||
ret[outputi].fill(sample1);
|
ret[outputi].fill(sample1);
|
||||||
outputi++;
|
outputi++;
|
||||||
|
@ -80,7 +80,7 @@ StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data,
|
StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data,
|
||||||
const size_t sample_count) {
|
const std::size_t sample_count) {
|
||||||
ASSERT(num_channels == 1 || num_channels == 2);
|
ASSERT(num_channels == 1 || num_channels == 2);
|
||||||
|
|
||||||
const auto decode_sample = [](u8 sample) {
|
const auto decode_sample = [](u8 sample) {
|
||||||
|
@ -90,11 +90,11 @@ StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data,
|
||||||
StereoBuffer16 ret(sample_count);
|
StereoBuffer16 ret(sample_count);
|
||||||
|
|
||||||
if (num_channels == 1) {
|
if (num_channels == 1) {
|
||||||
for (size_t i = 0; i < sample_count; i++) {
|
for (std::size_t i = 0; i < sample_count; i++) {
|
||||||
ret[i].fill(decode_sample(data[i]));
|
ret[i].fill(decode_sample(data[i]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < sample_count; i++) {
|
for (std::size_t i = 0; i < sample_count; i++) {
|
||||||
ret[i][0] = decode_sample(data[i * 2 + 0]);
|
ret[i][0] = decode_sample(data[i * 2 + 0]);
|
||||||
ret[i][1] = decode_sample(data[i * 2 + 1]);
|
ret[i][1] = decode_sample(data[i * 2 + 1]);
|
||||||
}
|
}
|
||||||
|
@ -104,19 +104,19 @@ StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data,
|
||||||
}
|
}
|
||||||
|
|
||||||
StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data,
|
StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data,
|
||||||
const size_t sample_count) {
|
const std::size_t sample_count) {
|
||||||
ASSERT(num_channels == 1 || num_channels == 2);
|
ASSERT(num_channels == 1 || num_channels == 2);
|
||||||
|
|
||||||
StereoBuffer16 ret(sample_count);
|
StereoBuffer16 ret(sample_count);
|
||||||
|
|
||||||
if (num_channels == 1) {
|
if (num_channels == 1) {
|
||||||
for (size_t i = 0; i < sample_count; i++) {
|
for (std::size_t i = 0; i < sample_count; i++) {
|
||||||
s16 sample;
|
s16 sample;
|
||||||
std::memcpy(&sample, data + i * sizeof(s16), sizeof(s16));
|
std::memcpy(&sample, data + i * sizeof(s16), sizeof(s16));
|
||||||
ret[i].fill(sample);
|
ret[i].fill(sample);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < sample_count; ++i) {
|
for (std::size_t i = 0; i < sample_count; ++i) {
|
||||||
std::memcpy(&ret[i], data + i * sizeof(s16) * 2, 2 * sizeof(s16));
|
std::memcpy(&ret[i], data + i * sizeof(s16) * 2, 2 * sizeof(s16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ struct ADPCMState {
|
||||||
* @param state ADPCM state, this is updated with new state
|
* @param state ADPCM state, this is updated with new state
|
||||||
* @return Decoded stereo signed PCM16 data, sample_count in length
|
* @return Decoded stereo signed PCM16 data, sample_count in length
|
||||||
*/
|
*/
|
||||||
StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count,
|
StereoBuffer16 DecodeADPCM(const u8* const data, const std::size_t sample_count,
|
||||||
const std::array<s16, 16>& adpcm_coeff, ADPCMState& state);
|
const std::array<s16, 16>& adpcm_coeff, ADPCMState& state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,7 +36,7 @@ StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count,
|
||||||
* @return Decoded stereo signed PCM16 data, sample_count in length
|
* @return Decoded stereo signed PCM16 data, sample_count in length
|
||||||
*/
|
*/
|
||||||
StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data,
|
StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data,
|
||||||
const size_t sample_count);
|
const std::size_t sample_count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param num_channels Number of channels
|
* @param num_channels Number of channels
|
||||||
|
@ -45,6 +45,6 @@ StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data,
|
||||||
* @return Decoded stereo signed PCM16 data, sample_count in length
|
* @return Decoded stereo signed PCM16 data, sample_count in length
|
||||||
*/
|
*/
|
||||||
StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data,
|
StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data,
|
||||||
const size_t sample_count);
|
const std::size_t sample_count);
|
||||||
} // namespace Codec
|
} // namespace Codec
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -95,7 +95,7 @@ unsigned int CubebSink::GetNativeSampleRate() const {
|
||||||
return impl->sample_rate;
|
return impl->sample_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CubebSink::EnqueueSamples(const s16* samples, size_t sample_count) {
|
void CubebSink::EnqueueSamples(const s16* samples, std::size_t sample_count) {
|
||||||
if (!impl->ctx)
|
if (!impl->ctx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -123,7 +123,8 @@ long CubebSink::Impl::DataCallback(cubeb_stream* stream, void* user_data, const
|
||||||
|
|
||||||
std::lock_guard lock{impl->queue_mutex};
|
std::lock_guard lock{impl->queue_mutex};
|
||||||
|
|
||||||
size_t frames_to_write = std::min(impl->queue.size() / 2, static_cast<size_t>(num_frames));
|
std::size_t frames_to_write =
|
||||||
|
std::min(impl->queue.size() / 2, static_cast<std::size_t>(num_frames));
|
||||||
|
|
||||||
memcpy(buffer, impl->queue.data(), frames_to_write * sizeof(s16) * 2);
|
memcpy(buffer, impl->queue.data(), frames_to_write * sizeof(s16) * 2);
|
||||||
impl->queue.erase(impl->queue.begin(), impl->queue.begin() + frames_to_write * 2);
|
impl->queue.erase(impl->queue.begin(), impl->queue.begin() + frames_to_write * 2);
|
||||||
|
@ -152,7 +153,7 @@ std::vector<std::string> ListCubebSinkDevices() {
|
||||||
if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
|
if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
|
||||||
LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
|
LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < collection.count; i++) {
|
for (std::size_t i = 0; i < collection.count; i++) {
|
||||||
const cubeb_device_info& device = collection.device[i];
|
const cubeb_device_info& device = collection.device[i];
|
||||||
if (device.friendly_name) {
|
if (device.friendly_name) {
|
||||||
device_list.emplace_back(device.friendly_name);
|
device_list.emplace_back(device.friendly_name);
|
||||||
|
|
|
@ -17,9 +17,9 @@ public:
|
||||||
|
|
||||||
unsigned int GetNativeSampleRate() const override;
|
unsigned int GetNativeSampleRate() const override;
|
||||||
|
|
||||||
void EnqueueSamples(const s16* samples, size_t sample_count) override;
|
void EnqueueSamples(const s16* samples, std::size_t sample_count) override;
|
||||||
|
|
||||||
size_t SamplesInQueue() const override;
|
std::size_t SamplesInQueue() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|
|
@ -46,7 +46,7 @@ void DspInterface::OutputFrame(StereoFrame16& frame) {
|
||||||
|
|
||||||
// Implementation of the hardware volume slider with a dynamic range of 60 dB
|
// Implementation of the hardware volume slider with a dynamic range of 60 dB
|
||||||
double volume_scale_factor = std::exp(6.90775 * Settings::values.volume) * 0.001;
|
double volume_scale_factor = std::exp(6.90775 * Settings::values.volume) * 0.001;
|
||||||
for (size_t i = 0; i < frame.size(); i++) {
|
for (std::size_t i = 0; i < frame.size(); i++) {
|
||||||
frame[i][0] = static_cast<s16>(frame[i][0] * volume_scale_factor);
|
frame[i][0] = static_cast<s16>(frame[i][0] * volume_scale_factor);
|
||||||
frame[i][1] = static_cast<s16>(frame[i][1] * volume_scale_factor);
|
frame[i][1] = static_cast<s16>(frame[i][1] * volume_scale_factor);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ void DspInterface::OutputFrame(StereoFrame16& frame) {
|
||||||
std::vector<s16> stretched_samples = time_stretcher.Process(sink->SamplesInQueue());
|
std::vector<s16> stretched_samples = time_stretcher.Process(sink->SamplesInQueue());
|
||||||
sink->EnqueueSamples(stretched_samples.data(), stretched_samples.size() / 2);
|
sink->EnqueueSamples(stretched_samples.data(), stretched_samples.size() / 2);
|
||||||
} else {
|
} else {
|
||||||
constexpr size_t maximum_sample_latency = 2048; // about 64 miliseconds
|
constexpr std::size_t maximum_sample_latency = 2048; // about 64 miliseconds
|
||||||
if (sink->SamplesInQueue() > maximum_sample_latency) {
|
if (sink->SamplesInQueue() > maximum_sample_latency) {
|
||||||
// This can occur if we're running too fast and samples are starting to back up.
|
// This can occur if we're running too fast and samples are starting to back up.
|
||||||
// Just drop the samples.
|
// Just drop the samples.
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
* @return The amount of data remaning in the pipe. This is the maximum length PipeRead will
|
* @return The amount of data remaning in the pipe. This is the maximum length PipeRead will
|
||||||
* return.
|
* return.
|
||||||
*/
|
*/
|
||||||
virtual size_t GetPipeReadableSize(DspPipe pipe_number) const = 0;
|
virtual std::size_t GetPipeReadableSize(DspPipe pipe_number) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write to a DSP pipe.
|
* Write to a DSP pipe.
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
namespace HLE {
|
namespace HLE {
|
||||||
|
|
||||||
constexpr size_t num_sources = 24;
|
constexpr std::size_t num_sources = 24;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This performs the filter operation defined by FilterT::ProcessSample on the frame in-place.
|
* This performs the filter operation defined by FilterT::ProcessSample on the frame in-place.
|
||||||
|
|
|
@ -66,7 +66,7 @@ void SourceFilters::SimpleFilter::Configure(
|
||||||
|
|
||||||
std::array<s16, 2> SourceFilters::SimpleFilter::ProcessSample(const std::array<s16, 2>& x0) {
|
std::array<s16, 2> SourceFilters::SimpleFilter::ProcessSample(const std::array<s16, 2>& x0) {
|
||||||
std::array<s16, 2> y0;
|
std::array<s16, 2> y0;
|
||||||
for (size_t i = 0; i < 2; i++) {
|
for (std::size_t i = 0; i < 2; i++) {
|
||||||
const s32 tmp = (b0 * x0[i] + a1 * y1[i]) >> 15;
|
const s32 tmp = (b0 * x0[i] + a1 * y1[i]) >> 15;
|
||||||
y0[i] = std::clamp(tmp, -32768, 32767);
|
y0[i] = std::clamp(tmp, -32768, 32767);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ void SourceFilters::BiquadFilter::Configure(
|
||||||
|
|
||||||
std::array<s16, 2> SourceFilters::BiquadFilter::ProcessSample(const std::array<s16, 2>& x0) {
|
std::array<s16, 2> SourceFilters::BiquadFilter::ProcessSample(const std::array<s16, 2>& x0) {
|
||||||
std::array<s16, 2> y0;
|
std::array<s16, 2> y0;
|
||||||
for (size_t i = 0; i < 2; i++) {
|
for (std::size_t i = 0; i < 2; i++) {
|
||||||
const s32 tmp = (b0 * x0[i] + b1 * x1[i] + b2 * x2[i] + a1 * y1[i] + a2 * y2[i]) >> 14;
|
const s32 tmp = (b0 * x0[i] + b1 * x1[i] + b2 * x2[i] + a1 * y1[i] + a2 * y2[i]) >> 14;
|
||||||
y0[i] = std::clamp(tmp, -32768, 32767);
|
y0[i] = std::clamp(tmp, -32768, 32767);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
DspState GetDspState() const;
|
DspState GetDspState() const;
|
||||||
|
|
||||||
std::vector<u8> PipeRead(DspPipe pipe_number, u32 length);
|
std::vector<u8> PipeRead(DspPipe pipe_number, u32 length);
|
||||||
size_t GetPipeReadableSize(DspPipe pipe_number) const;
|
std::size_t GetPipeReadableSize(DspPipe pipe_number) const;
|
||||||
void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer);
|
void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer);
|
||||||
|
|
||||||
std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory();
|
std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory();
|
||||||
|
@ -41,7 +41,7 @@ private:
|
||||||
void WriteU16(DspPipe pipe_number, u16 value);
|
void WriteU16(DspPipe pipe_number, u16 value);
|
||||||
void AudioPipeWriteStructAddresses();
|
void AudioPipeWriteStructAddresses();
|
||||||
|
|
||||||
size_t CurrentRegionIndex() const;
|
std::size_t CurrentRegionIndex() const;
|
||||||
HLE::SharedMemory& ReadRegion();
|
HLE::SharedMemory& ReadRegion();
|
||||||
HLE::SharedMemory& WriteRegion();
|
HLE::SharedMemory& WriteRegion();
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ DspState DspHle::Impl::GetDspState() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> DspHle::Impl::PipeRead(DspPipe pipe_number, u32 length) {
|
std::vector<u8> DspHle::Impl::PipeRead(DspPipe pipe_number, u32 length) {
|
||||||
const size_t pipe_index = static_cast<size_t>(pipe_number);
|
const std::size_t pipe_index = static_cast<std::size_t>(pipe_number);
|
||||||
|
|
||||||
if (pipe_index >= num_dsp_pipe) {
|
if (pipe_index >= num_dsp_pipe) {
|
||||||
LOG_ERROR(Audio_DSP, "pipe_number = {} invalid", pipe_index);
|
LOG_ERROR(Audio_DSP, "pipe_number = {} invalid", pipe_index);
|
||||||
|
@ -118,7 +118,7 @@ std::vector<u8> DspHle::Impl::PipeRead(DspPipe pipe_number, u32 length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DspHle::Impl::GetPipeReadableSize(DspPipe pipe_number) const {
|
size_t DspHle::Impl::GetPipeReadableSize(DspPipe pipe_number) const {
|
||||||
const size_t pipe_index = static_cast<size_t>(pipe_number);
|
const std::size_t pipe_index = static_cast<std::size_t>(pipe_number);
|
||||||
|
|
||||||
if (pipe_index >= num_dsp_pipe) {
|
if (pipe_index >= num_dsp_pipe) {
|
||||||
LOG_ERROR(Audio_DSP, "pipe_number = {} invalid", pipe_index);
|
LOG_ERROR(Audio_DSP, "pipe_number = {} invalid", pipe_index);
|
||||||
|
@ -183,7 +183,8 @@ void DspHle::Impl::PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LOG_CRITICAL(Audio_DSP, "pipe_number = {} unimplemented", static_cast<size_t>(pipe_number));
|
LOG_CRITICAL(Audio_DSP, "pipe_number = {} unimplemented",
|
||||||
|
static_cast<std::size_t>(pipe_number));
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -205,7 +206,7 @@ void DspHle::Impl::ResetPipes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DspHle::Impl::WriteU16(DspPipe pipe_number, u16 value) {
|
void DspHle::Impl::WriteU16(DspPipe pipe_number, u16 value) {
|
||||||
const size_t pipe_index = static_cast<size_t>(pipe_number);
|
const std::size_t pipe_index = static_cast<std::size_t>(pipe_number);
|
||||||
|
|
||||||
std::vector<u8>& data = pipe_data.at(pipe_index);
|
std::vector<u8>& data = pipe_data.at(pipe_index);
|
||||||
// Little endian
|
// Little endian
|
||||||
|
@ -280,10 +281,10 @@ StereoFrame16 DspHle::Impl::GenerateCurrentFrame() {
|
||||||
std::array<QuadFrame32, 3> intermediate_mixes = {};
|
std::array<QuadFrame32, 3> intermediate_mixes = {};
|
||||||
|
|
||||||
// Generate intermediate mixes
|
// Generate intermediate mixes
|
||||||
for (size_t i = 0; i < HLE::num_sources; i++) {
|
for (std::size_t i = 0; i < HLE::num_sources; i++) {
|
||||||
write.source_statuses.status[i] =
|
write.source_statuses.status[i] =
|
||||||
sources[i].Tick(read.source_configurations.config[i], read.adpcm_coefficients.coeff[i]);
|
sources[i].Tick(read.source_configurations.config[i], read.adpcm_coefficients.coeff[i]);
|
||||||
for (size_t mix = 0; mix < 3; mix++) {
|
for (std::size_t mix = 0; mix < 3; mix++) {
|
||||||
sources[i].MixInto(intermediate_mixes[mix], mix);
|
sources[i].MixInto(intermediate_mixes[mix], mix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,8 +296,8 @@ StereoFrame16 DspHle::Impl::GenerateCurrentFrame() {
|
||||||
StereoFrame16 output_frame = mixers.GetOutput();
|
StereoFrame16 output_frame = mixers.GetOutput();
|
||||||
|
|
||||||
// Write current output frame to the shared memory region
|
// Write current output frame to the shared memory region
|
||||||
for (size_t samplei = 0; samplei < output_frame.size(); samplei++) {
|
for (std::size_t samplei = 0; samplei < output_frame.size(); samplei++) {
|
||||||
for (size_t channeli = 0; channeli < output_frame[0].size(); channeli++) {
|
for (std::size_t channeli = 0; channeli < output_frame[0].size(); channeli++) {
|
||||||
write.final_samples.pcm16[samplei][channeli] = s16_le(output_frame[samplei][channeli]);
|
write.final_samples.pcm16[samplei][channeli] = s16_le(output_frame[samplei][channeli]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ public:
|
||||||
DspState GetDspState() const override;
|
DspState GetDspState() const override;
|
||||||
|
|
||||||
std::vector<u8> PipeRead(DspPipe pipe_number, u32 length) override;
|
std::vector<u8> PipeRead(DspPipe pipe_number, u32 length) override;
|
||||||
size_t GetPipeReadableSize(DspPipe pipe_number) const override;
|
std::size_t GetPipeReadableSize(DspPipe pipe_number) const override;
|
||||||
void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) override;
|
void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) override;
|
||||||
|
|
||||||
std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory() override;
|
std::array<u8, Memory::DSP_RAM_SIZE>& GetDspMemory() override;
|
||||||
|
|
|
@ -68,7 +68,7 @@ void Mixers::ParseConfig(DspConfiguration& config) {
|
||||||
config.output_format_dirty.Assign(0);
|
config.output_format_dirty.Assign(0);
|
||||||
state.output_format = config.output_format;
|
state.output_format = config.output_format;
|
||||||
LOG_TRACE(Audio_DSP, "mixers output_format = {}",
|
LOG_TRACE(Audio_DSP, "mixers output_format = {}",
|
||||||
static_cast<size_t>(config.output_format));
|
static_cast<std::size_t>(config.output_format));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.headphones_connected_dirty) {
|
if (config.headphones_connected_dirty) {
|
||||||
|
@ -131,7 +131,7 @@ void Mixers::DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& sample
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNREACHABLE_MSG("Invalid output_format {}", static_cast<size_t>(state.output_format));
|
UNREACHABLE_MSG("Invalid output_format {}", static_cast<std::size_t>(state.output_format));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mixers::AuxReturn(const IntermediateMixSamples& read_samples) {
|
void Mixers::AuxReturn(const IntermediateMixSamples& read_samples) {
|
||||||
|
@ -139,8 +139,8 @@ void Mixers::AuxReturn(const IntermediateMixSamples& read_samples) {
|
||||||
// QuadFrame32.
|
// QuadFrame32.
|
||||||
|
|
||||||
if (state.mixer1_enabled) {
|
if (state.mixer1_enabled) {
|
||||||
for (size_t sample = 0; sample < samples_per_frame; sample++) {
|
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
||||||
for (size_t channel = 0; channel < 4; channel++) {
|
for (std::size_t channel = 0; channel < 4; channel++) {
|
||||||
state.intermediate_mix_buffer[1][sample][channel] =
|
state.intermediate_mix_buffer[1][sample][channel] =
|
||||||
read_samples.mix1.pcm32[channel][sample];
|
read_samples.mix1.pcm32[channel][sample];
|
||||||
}
|
}
|
||||||
|
@ -148,8 +148,8 @@ void Mixers::AuxReturn(const IntermediateMixSamples& read_samples) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.mixer2_enabled) {
|
if (state.mixer2_enabled) {
|
||||||
for (size_t sample = 0; sample < samples_per_frame; sample++) {
|
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
||||||
for (size_t channel = 0; channel < 4; channel++) {
|
for (std::size_t channel = 0; channel < 4; channel++) {
|
||||||
state.intermediate_mix_buffer[2][sample][channel] =
|
state.intermediate_mix_buffer[2][sample][channel] =
|
||||||
read_samples.mix2.pcm32[channel][sample];
|
read_samples.mix2.pcm32[channel][sample];
|
||||||
}
|
}
|
||||||
|
@ -165,8 +165,8 @@ void Mixers::AuxSend(IntermediateMixSamples& write_samples,
|
||||||
state.intermediate_mix_buffer[0] = input[0];
|
state.intermediate_mix_buffer[0] = input[0];
|
||||||
|
|
||||||
if (state.mixer1_enabled) {
|
if (state.mixer1_enabled) {
|
||||||
for (size_t sample = 0; sample < samples_per_frame; sample++) {
|
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
||||||
for (size_t channel = 0; channel < 4; channel++) {
|
for (std::size_t channel = 0; channel < 4; channel++) {
|
||||||
write_samples.mix1.pcm32[channel][sample] = input[1][sample][channel];
|
write_samples.mix1.pcm32[channel][sample] = input[1][sample][channel];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,8 +175,8 @@ void Mixers::AuxSend(IntermediateMixSamples& write_samples,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.mixer2_enabled) {
|
if (state.mixer2_enabled) {
|
||||||
for (size_t sample = 0; sample < samples_per_frame; sample++) {
|
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
||||||
for (size_t channel = 0; channel < 4; channel++) {
|
for (std::size_t channel = 0; channel < 4; channel++) {
|
||||||
write_samples.mix2.pcm32[channel][sample] = input[2][sample][channel];
|
write_samples.mix2.pcm32[channel][sample] = input[2][sample][channel];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ void Mixers::AuxSend(IntermediateMixSamples& write_samples,
|
||||||
void Mixers::MixCurrentFrame() {
|
void Mixers::MixCurrentFrame() {
|
||||||
current_frame.fill({});
|
current_frame.fill({});
|
||||||
|
|
||||||
for (size_t mix = 0; mix < 3; mix++) {
|
for (std::size_t mix = 0; mix < 3; mix++) {
|
||||||
DownmixAndMixIntoCurrentFrame(state.intermediate_mixer_volume[mix],
|
DownmixAndMixIntoCurrentFrame(state.intermediate_mixer_volume[mix],
|
||||||
state.intermediate_mix_buffer[mix]);
|
state.intermediate_mix_buffer[mix]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,12 @@ SourceStatus::Status Source::Tick(SourceConfiguration::Configuration& config,
|
||||||
return GetCurrentStatus();
|
return GetCurrentStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Source::MixInto(QuadFrame32& dest, size_t intermediate_mix_id) const {
|
void Source::MixInto(QuadFrame32& dest, std::size_t intermediate_mix_id) const {
|
||||||
if (!state.enabled)
|
if (!state.enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::array<float, 4>& gains = state.gain.at(intermediate_mix_id);
|
const std::array<float, 4>& gains = state.gain.at(intermediate_mix_id);
|
||||||
for (size_t samplei = 0; samplei < samples_per_frame; samplei++) {
|
for (std::size_t samplei = 0; samplei < samples_per_frame; samplei++) {
|
||||||
// Conversion from stereo (current_frame) to quadraphonic (dest) occurs here.
|
// Conversion from stereo (current_frame) to quadraphonic (dest) occurs here.
|
||||||
dest[samplei][0] += static_cast<s32>(gains[0] * current_frame[samplei][0]);
|
dest[samplei][0] += static_cast<s32>(gains[0] * current_frame[samplei][0]);
|
||||||
dest[samplei][1] += static_cast<s32>(gains[1] * current_frame[samplei][1]);
|
dest[samplei][1] += static_cast<s32>(gains[1] * current_frame[samplei][1]);
|
||||||
|
@ -141,21 +141,21 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config,
|
||||||
config.interpolation_dirty.Assign(0);
|
config.interpolation_dirty.Assign(0);
|
||||||
state.interpolation_mode = config.interpolation_mode;
|
state.interpolation_mode = config.interpolation_mode;
|
||||||
LOG_TRACE(Audio_DSP, "source_id={} interpolation_mode={}", source_id,
|
LOG_TRACE(Audio_DSP, "source_id={} interpolation_mode={}", source_id,
|
||||||
static_cast<size_t>(state.interpolation_mode));
|
static_cast<std::size_t>(state.interpolation_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.format_dirty || config.embedded_buffer_dirty) {
|
if (config.format_dirty || config.embedded_buffer_dirty) {
|
||||||
config.format_dirty.Assign(0);
|
config.format_dirty.Assign(0);
|
||||||
state.format = config.format;
|
state.format = config.format;
|
||||||
LOG_TRACE(Audio_DSP, "source_id={} format={}", source_id,
|
LOG_TRACE(Audio_DSP, "source_id={} format={}", source_id,
|
||||||
static_cast<size_t>(state.format));
|
static_cast<std::size_t>(state.format));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.mono_or_stereo_dirty || config.embedded_buffer_dirty) {
|
if (config.mono_or_stereo_dirty || config.embedded_buffer_dirty) {
|
||||||
config.mono_or_stereo_dirty.Assign(0);
|
config.mono_or_stereo_dirty.Assign(0);
|
||||||
state.mono_or_stereo = config.mono_or_stereo;
|
state.mono_or_stereo = config.mono_or_stereo;
|
||||||
LOG_TRACE(Audio_DSP, "source_id={} mono_or_stereo={}", source_id,
|
LOG_TRACE(Audio_DSP, "source_id={} mono_or_stereo={}", source_id,
|
||||||
static_cast<size_t>(state.mono_or_stereo));
|
static_cast<std::size_t>(state.mono_or_stereo));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32_dsp play_position = {};
|
u32_dsp play_position = {};
|
||||||
|
@ -195,7 +195,7 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config,
|
||||||
|
|
||||||
if (config.buffer_queue_dirty) {
|
if (config.buffer_queue_dirty) {
|
||||||
config.buffer_queue_dirty.Assign(0);
|
config.buffer_queue_dirty.Assign(0);
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (std::size_t i = 0; i < 4; i++) {
|
||||||
if (config.buffers_dirty & (1 << i)) {
|
if (config.buffers_dirty & (1 << i)) {
|
||||||
const auto& b = config.buffers[i];
|
const auto& b = config.buffers[i];
|
||||||
state.input_queue.emplace(Buffer{
|
state.input_queue.emplace(Buffer{
|
||||||
|
@ -236,7 +236,7 @@ void Source::GenerateFrame() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t frame_position = 0;
|
std::size_t frame_position = 0;
|
||||||
|
|
||||||
state.current_sample_number = state.next_sample_number;
|
state.current_sample_number = state.next_sample_number;
|
||||||
while (frame_position < current_frame.size()) {
|
while (frame_position < current_frame.size()) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace HLE {
|
||||||
*/
|
*/
|
||||||
class Source final {
|
class Source final {
|
||||||
public:
|
public:
|
||||||
explicit Source(size_t source_id_) : source_id(source_id_) {
|
explicit Source(std::size_t source_id_) : source_id(source_id_) {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +52,10 @@ public:
|
||||||
* @param dest The QuadFrame32 to mix into.
|
* @param dest The QuadFrame32 to mix into.
|
||||||
* @param intermediate_mix_id The id of the intermediate mix whose gains we are using.
|
* @param intermediate_mix_id The id of the intermediate mix whose gains we are using.
|
||||||
*/
|
*/
|
||||||
void MixInto(QuadFrame32& dest, size_t intermediate_mix_id) const;
|
void MixInto(QuadFrame32& dest, std::size_t intermediate_mix_id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const size_t source_id;
|
const std::size_t source_id;
|
||||||
StereoFrame16 current_frame;
|
StereoFrame16 current_frame;
|
||||||
|
|
||||||
using Format = SourceConfiguration::Configuration::Format;
|
using Format = SourceConfiguration::Configuration::Format;
|
||||||
|
|
|
@ -18,7 +18,7 @@ constexpr u64 scale_mask = scale_factor - 1;
|
||||||
/// Three adjacent samples are passed to fn each step.
|
/// Three adjacent samples are passed to fn each step.
|
||||||
template <typename Function>
|
template <typename Function>
|
||||||
static void StepOverSamples(State& state, StereoBuffer16& input, float rate, StereoFrame16& output,
|
static void StepOverSamples(State& state, StereoBuffer16& input, float rate, StereoFrame16& output,
|
||||||
size_t& outputi, Function fn) {
|
std::size_t& outputi, Function fn) {
|
||||||
ASSERT(rate > 0);
|
ASSERT(rate > 0);
|
||||||
|
|
||||||
if (input.empty())
|
if (input.empty())
|
||||||
|
@ -28,10 +28,10 @@ static void StepOverSamples(State& state, StereoBuffer16& input, float rate, Ste
|
||||||
|
|
||||||
const u64 step_size = static_cast<u64>(rate * scale_factor);
|
const u64 step_size = static_cast<u64>(rate * scale_factor);
|
||||||
u64 fposition = state.fposition;
|
u64 fposition = state.fposition;
|
||||||
size_t inputi = 0;
|
std::size_t inputi = 0;
|
||||||
|
|
||||||
while (outputi < output.size()) {
|
while (outputi < output.size()) {
|
||||||
inputi = static_cast<size_t>(fposition / scale_factor);
|
inputi = static_cast<std::size_t>(fposition / scale_factor);
|
||||||
|
|
||||||
if (inputi + 2 >= input.size()) {
|
if (inputi + 2 >= input.size()) {
|
||||||
inputi = input.size() - 2;
|
inputi = input.size() - 2;
|
||||||
|
@ -51,14 +51,15 @@ static void StepOverSamples(State& state, StereoBuffer16& input, float rate, Ste
|
||||||
input.erase(input.begin(), std::next(input.begin(), inputi + 2));
|
input.erase(input.begin(), std::next(input.begin(), inputi + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void None(State& state, StereoBuffer16& input, float rate, StereoFrame16& output, size_t& outputi) {
|
void None(State& state, StereoBuffer16& input, float rate, StereoFrame16& output,
|
||||||
|
std::size_t& outputi) {
|
||||||
StepOverSamples(
|
StepOverSamples(
|
||||||
state, input, rate, output, outputi,
|
state, input, rate, output, outputi,
|
||||||
[](u64 fraction, const auto& x0, const auto& x1, const auto& x2) { return x0; });
|
[](u64 fraction, const auto& x0, const auto& x1, const auto& x2) { return x0; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Linear(State& state, StereoBuffer16& input, float rate, StereoFrame16& output,
|
void Linear(State& state, StereoBuffer16& input, float rate, StereoFrame16& output,
|
||||||
size_t& outputi) {
|
std::size_t& outputi) {
|
||||||
// Note on accuracy: Some values that this produces are +/- 1 from the actual firmware.
|
// Note on accuracy: Some values that this produces are +/- 1 from the actual firmware.
|
||||||
StepOverSamples(state, input, rate, output, outputi,
|
StepOverSamples(state, input, rate, output, outputi,
|
||||||
[](u64 fraction, const auto& x0, const auto& x1, const auto& x2) {
|
[](u64 fraction, const auto& x0, const auto& x1, const auto& x2) {
|
||||||
|
|
|
@ -32,7 +32,8 @@ struct State {
|
||||||
* @param output The resampled audio buffer.
|
* @param output The resampled audio buffer.
|
||||||
* @param outputi The index of output to start writing to.
|
* @param outputi The index of output to start writing to.
|
||||||
*/
|
*/
|
||||||
void None(State& state, StereoBuffer16& input, float rate, StereoFrame16& output, size_t& outputi);
|
void None(State& state, StereoBuffer16& input, float rate, StereoFrame16& output,
|
||||||
|
std::size_t& outputi);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linear interpolation. This is equivalent to a first-order hold. There is a two-sample predelay.
|
* Linear interpolation. This is equivalent to a first-order hold. There is a two-sample predelay.
|
||||||
|
@ -44,7 +45,7 @@ void None(State& state, StereoBuffer16& input, float rate, StereoFrame16& output
|
||||||
* @param outputi The index of output to start writing to.
|
* @param outputi The index of output to start writing to.
|
||||||
*/
|
*/
|
||||||
void Linear(State& state, StereoBuffer16& input, float rate, StereoFrame16& output,
|
void Linear(State& state, StereoBuffer16& input, float rate, StereoFrame16& output,
|
||||||
size_t& outputi);
|
std::size_t& outputi);
|
||||||
|
|
||||||
} // namespace AudioInterp
|
} // namespace AudioInterp
|
||||||
} // namespace AudioCore
|
} // namespace AudioCore
|
||||||
|
|
|
@ -19,9 +19,9 @@ public:
|
||||||
return native_sample_rate;
|
return native_sample_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnqueueSamples(const s16*, size_t) override {}
|
void EnqueueSamples(const s16*, std::size_t) override {}
|
||||||
|
|
||||||
size_t SamplesInQueue() const override {
|
std::size_t SamplesInQueue() const override {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -74,7 +74,7 @@ unsigned int SDL2Sink::GetNativeSampleRate() const {
|
||||||
return impl->sample_rate;
|
return impl->sample_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL2Sink::EnqueueSamples(const s16* samples, size_t sample_count) {
|
void SDL2Sink::EnqueueSamples(const s16* samples, std::size_t sample_count) {
|
||||||
if (impl->audio_device_id <= 0)
|
if (impl->audio_device_id <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -89,8 +89,9 @@ size_t SDL2Sink::SamplesInQueue() const {
|
||||||
|
|
||||||
SDL_LockAudioDevice(impl->audio_device_id);
|
SDL_LockAudioDevice(impl->audio_device_id);
|
||||||
|
|
||||||
size_t total_size = std::accumulate(impl->queue.begin(), impl->queue.end(),
|
std::size_t total_size =
|
||||||
static_cast<size_t>(0), [](size_t sum, const auto& buffer) {
|
std::accumulate(impl->queue.begin(), impl->queue.end(), static_cast<std::size_t>(0),
|
||||||
|
[](std::size_t sum, const auto& buffer) {
|
||||||
// Division by two because each stereo sample is made of
|
// Division by two because each stereo sample is made of
|
||||||
// two s16.
|
// two s16.
|
||||||
return sum + buffer.size() / 2;
|
return sum + buffer.size() / 2;
|
||||||
|
@ -104,7 +105,7 @@ size_t SDL2Sink::SamplesInQueue() const {
|
||||||
void SDL2Sink::Impl::Callback(void* impl_, u8* buffer, int buffer_size_in_bytes) {
|
void SDL2Sink::Impl::Callback(void* impl_, u8* buffer, int buffer_size_in_bytes) {
|
||||||
Impl* impl = reinterpret_cast<Impl*>(impl_);
|
Impl* impl = reinterpret_cast<Impl*>(impl_);
|
||||||
|
|
||||||
size_t remaining_size = static_cast<size_t>(buffer_size_in_bytes) /
|
std::size_t remaining_size = static_cast<std::size_t>(buffer_size_in_bytes) /
|
||||||
sizeof(s16); // Keep track of size in 16-bit increments.
|
sizeof(s16); // Keep track of size in 16-bit increments.
|
||||||
|
|
||||||
while (remaining_size > 0 && !impl->queue.empty()) {
|
while (remaining_size > 0 && !impl->queue.empty()) {
|
||||||
|
|
|
@ -17,9 +17,9 @@ public:
|
||||||
|
|
||||||
unsigned int GetNativeSampleRate() const override;
|
unsigned int GetNativeSampleRate() const override;
|
||||||
|
|
||||||
void EnqueueSamples(const s16* samples, size_t sample_count) override;
|
void EnqueueSamples(const s16* samples, std::size_t sample_count) override;
|
||||||
|
|
||||||
size_t SamplesInQueue() const override;
|
std::size_t SamplesInQueue() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
* @param samples Samples in interleaved stereo PCM16 format.
|
* @param samples Samples in interleaved stereo PCM16 format.
|
||||||
* @param sample_count Number of samples.
|
* @param sample_count Number of samples.
|
||||||
*/
|
*/
|
||||||
virtual void EnqueueSamples(const s16* samples, size_t sample_count) = 0;
|
virtual void EnqueueSamples(const s16* samples, std::size_t sample_count) = 0;
|
||||||
|
|
||||||
/// Samples enqueued that have not been played yet.
|
/// Samples enqueued that have not been played yet.
|
||||||
virtual std::size_t SamplesInQueue() const = 0;
|
virtual std::size_t SamplesInQueue() const = 0;
|
||||||
|
|
|
@ -25,7 +25,7 @@ static double ClampRatio(double ratio) {
|
||||||
|
|
||||||
constexpr double MIN_DELAY_TIME = 0.05; // Units: seconds
|
constexpr double MIN_DELAY_TIME = 0.05; // Units: seconds
|
||||||
constexpr double MAX_DELAY_TIME = 0.25; // Units: seconds
|
constexpr double MAX_DELAY_TIME = 0.25; // Units: seconds
|
||||||
constexpr size_t DROP_FRAMES_SAMPLE_DELAY = 16000; // Units: samples
|
constexpr std::size_t DROP_FRAMES_SAMPLE_DELAY = 16000; // Units: samples
|
||||||
|
|
||||||
constexpr double SMOOTHING_FACTOR = 0.007;
|
constexpr double SMOOTHING_FACTOR = 0.007;
|
||||||
|
|
||||||
|
@ -33,14 +33,14 @@ struct TimeStretcher::Impl {
|
||||||
soundtouch::SoundTouch soundtouch;
|
soundtouch::SoundTouch soundtouch;
|
||||||
|
|
||||||
steady_clock::time_point frame_timer = steady_clock::now();
|
steady_clock::time_point frame_timer = steady_clock::now();
|
||||||
size_t samples_queued = 0;
|
std::size_t samples_queued = 0;
|
||||||
|
|
||||||
double smoothed_ratio = 1.0;
|
double smoothed_ratio = 1.0;
|
||||||
|
|
||||||
double sample_rate = static_cast<double>(native_sample_rate);
|
double sample_rate = static_cast<double>(native_sample_rate);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<s16> TimeStretcher::Process(size_t samples_in_queue) {
|
std::vector<s16> TimeStretcher::Process(std::size_t samples_in_queue) {
|
||||||
// This is a very simple algorithm without any fancy control theory. It works and is stable.
|
// This is a very simple algorithm without any fancy control theory. It works and is stable.
|
||||||
|
|
||||||
double ratio = CalculateCurrentRatio();
|
double ratio = CalculateCurrentRatio();
|
||||||
|
@ -76,7 +76,7 @@ void TimeStretcher::SetOutputSampleRate(unsigned int sample_rate) {
|
||||||
impl->soundtouch.setRate(static_cast<double>(native_sample_rate) / impl->sample_rate);
|
impl->soundtouch.setRate(static_cast<double>(native_sample_rate) / impl->sample_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeStretcher::AddSamples(const s16* buffer, size_t num_samples) {
|
void TimeStretcher::AddSamples(const s16* buffer, std::size_t num_samples) {
|
||||||
impl->soundtouch.putSamples(buffer, static_cast<uint>(num_samples));
|
impl->soundtouch.putSamples(buffer, static_cast<uint>(num_samples));
|
||||||
impl->samples_queued += num_samples;
|
impl->samples_queued += num_samples;
|
||||||
}
|
}
|
||||||
|
@ -115,9 +115,11 @@ double TimeStretcher::CalculateCurrentRatio() {
|
||||||
return ratio;
|
return ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
double TimeStretcher::CorrectForUnderAndOverflow(double ratio, size_t sample_delay) const {
|
double TimeStretcher::CorrectForUnderAndOverflow(double ratio, std::size_t sample_delay) const {
|
||||||
const size_t min_sample_delay = static_cast<size_t>(MIN_DELAY_TIME * impl->sample_rate);
|
const std::size_t min_sample_delay =
|
||||||
const size_t max_sample_delay = static_cast<size_t>(MAX_DELAY_TIME * impl->sample_rate);
|
static_cast<std::size_t>(MIN_DELAY_TIME * impl->sample_rate);
|
||||||
|
const std::size_t max_sample_delay =
|
||||||
|
static_cast<std::size_t>(MAX_DELAY_TIME * impl->sample_rate);
|
||||||
|
|
||||||
if (sample_delay < min_sample_delay) {
|
if (sample_delay < min_sample_delay) {
|
||||||
// Make the ratio bigger.
|
// Make the ratio bigger.
|
||||||
|
@ -133,7 +135,7 @@ double TimeStretcher::CorrectForUnderAndOverflow(double ratio, size_t sample_del
|
||||||
std::vector<s16> TimeStretcher::GetSamples() {
|
std::vector<s16> TimeStretcher::GetSamples() {
|
||||||
uint available = impl->soundtouch.numSamples();
|
uint available = impl->soundtouch.numSamples();
|
||||||
|
|
||||||
std::vector<s16> output(static_cast<size_t>(available) * 2);
|
std::vector<s16> output(static_cast<std::size_t>(available) * 2);
|
||||||
|
|
||||||
impl->soundtouch.receiveSamples(output.data(), available);
|
impl->soundtouch.receiveSamples(output.data(), available);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
* @param sample_buffer Buffer of samples in interleaved stereo PCM16 format.
|
* @param sample_buffer Buffer of samples in interleaved stereo PCM16 format.
|
||||||
* @param num_samples Number of samples.
|
* @param num_samples Number of samples.
|
||||||
*/
|
*/
|
||||||
void AddSamples(const s16* sample_buffer, size_t num_samples);
|
void AddSamples(const s16* sample_buffer, std::size_t num_samples);
|
||||||
|
|
||||||
/// Flush audio remaining in internal buffers.
|
/// Flush audio remaining in internal buffers.
|
||||||
void Flush();
|
void Flush();
|
||||||
|
@ -42,7 +42,7 @@ public:
|
||||||
* played yet.
|
* played yet.
|
||||||
* @return Samples to play in interleaved stereo PCM16 format.
|
* @return Samples to play in interleaved stereo PCM16 format.
|
||||||
*/
|
*/
|
||||||
std::vector<s16> Process(size_t sample_delay);
|
std::vector<s16> Process(std::size_t sample_delay);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
@ -52,7 +52,7 @@ private:
|
||||||
double CalculateCurrentRatio();
|
double CalculateCurrentRatio();
|
||||||
/// INTERNAL: If we have too many or too few samples downstream, nudge ratio in the appropriate
|
/// INTERNAL: If we have too many or too few samples downstream, nudge ratio in the appropriate
|
||||||
/// direction.
|
/// direction.
|
||||||
double CorrectForUnderAndOverflow(double ratio, size_t sample_delay) const;
|
double CorrectForUnderAndOverflow(double ratio, std::size_t sample_delay) const;
|
||||||
/// INTERNAL: Gets the time-stretched samples from SoundTouch.
|
/// INTERNAL: Gets the time-stretched samples from SoundTouch.
|
||||||
std::vector<s16> GetSamples();
|
std::vector<s16> GetSamples();
|
||||||
};
|
};
|
||||||
|
|
|
@ -171,7 +171,7 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'i': {
|
case 'i': {
|
||||||
const auto cia_progress = [](size_t written, size_t total) {
|
const auto cia_progress = [](std::size_t written, std::size_t total) {
|
||||||
LOG_INFO(Frontend, "{:02d}%", (written * 100 / total));
|
LOG_INFO(Frontend, "{:02d}%", (written * 100 / total));
|
||||||
};
|
};
|
||||||
if (Service::AM::InstallCIA(std::string(optarg), cia_progress) !=
|
if (Service::AM::InstallCIA(std::string(optarg), cia_progress) !=
|
||||||
|
|
|
@ -42,7 +42,8 @@ QVariant BreakPointModel::data(const QModelIndex& index, int role) const {
|
||||||
{Pica::DebugContext::Event::BufferSwapped, tr("Buffers swapped")},
|
{Pica::DebugContext::Event::BufferSwapped, tr("Buffers swapped")},
|
||||||
};
|
};
|
||||||
|
|
||||||
DEBUG_ASSERT(map.size() == static_cast<size_t>(Pica::DebugContext::Event::NumEvents));
|
DEBUG_ASSERT(map.size() ==
|
||||||
|
static_cast<std::size_t>(Pica::DebugContext::Event::NumEvents));
|
||||||
return (map.find(event) != map.end()) ? map.at(event) : QString();
|
return (map.find(event) != map.end()) ? map.at(event) : QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
|
||||||
Settings::LogSettings();
|
Settings::LogSettings();
|
||||||
|
|
||||||
// register types to use in slots and signals
|
// register types to use in slots and signals
|
||||||
qRegisterMetaType<size_t>("size_t");
|
qRegisterMetaType<std::size_t>("std::size_t");
|
||||||
qRegisterMetaType<Service::AM::InstallStatus>("Service::AM::InstallStatus");
|
qRegisterMetaType<Service::AM::InstallStatus>("Service::AM::InstallStatus");
|
||||||
|
|
||||||
LoadTranslation();
|
LoadTranslation();
|
||||||
|
@ -1000,7 +1000,7 @@ void GMainWindow::OnMenuInstallCIA() {
|
||||||
QtConcurrent::run([&, filepaths] {
|
QtConcurrent::run([&, filepaths] {
|
||||||
QString current_path;
|
QString current_path;
|
||||||
Service::AM::InstallStatus status;
|
Service::AM::InstallStatus status;
|
||||||
const auto cia_progress = [&](size_t written, size_t total) {
|
const auto cia_progress = [&](std::size_t written, std::size_t total) {
|
||||||
emit UpdateProgress(written, total);
|
emit UpdateProgress(written, total);
|
||||||
};
|
};
|
||||||
for (const auto current_path : filepaths) {
|
for (const auto current_path : filepaths) {
|
||||||
|
@ -1011,7 +1011,7 @@ void GMainWindow::OnMenuInstallCIA() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnUpdateProgress(size_t written, size_t total) {
|
void GMainWindow::OnUpdateProgress(std::size_t written, std::size_t total) {
|
||||||
progress_bar->setValue(
|
progress_bar->setValue(
|
||||||
static_cast<int>(INT_MAX * (static_cast<double>(written) / static_cast<double>(total))));
|
static_cast<int>(INT_MAX * (static_cast<double>(written) / static_cast<double>(total))));
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ signals:
|
||||||
*/
|
*/
|
||||||
void EmulationStopping();
|
void EmulationStopping();
|
||||||
|
|
||||||
void UpdateProgress(size_t written, size_t total);
|
void UpdateProgress(std::size_t written, std::size_t total);
|
||||||
void CIAInstallReport(Service::AM::InstallStatus status, QString filepath);
|
void CIAInstallReport(Service::AM::InstallStatus status, QString filepath);
|
||||||
void CIAInstallFinished();
|
void CIAInstallFinished();
|
||||||
// Signal that tells widgets to update icons to use the current theme
|
// Signal that tells widgets to update icons to use the current theme
|
||||||
|
@ -161,7 +161,7 @@ private slots:
|
||||||
void OnGameListShowList(bool show);
|
void OnGameListShowList(bool show);
|
||||||
void OnMenuLoadFile();
|
void OnMenuLoadFile();
|
||||||
void OnMenuInstallCIA();
|
void OnMenuInstallCIA();
|
||||||
void OnUpdateProgress(size_t written, size_t total);
|
void OnUpdateProgress(std::size_t written, std::size_t total);
|
||||||
void OnCIAInstallReport(Service::AM::InstallStatus status, QString filepath);
|
void OnCIAInstallReport(Service::AM::InstallStatus status, QString filepath);
|
||||||
void OnCIAInstallFinished();
|
void OnCIAInstallFinished();
|
||||||
void OnMenuRecentFile();
|
void OnMenuRecentFile();
|
||||||
|
@ -255,5 +255,5 @@ protected:
|
||||||
void dragMoveEvent(QDragMoveEvent* event) override;
|
void dragMoveEvent(QDragMoveEvent* event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(size_t);
|
Q_DECLARE_METATYPE(std::size_t);
|
||||||
Q_DECLARE_METATYPE(Service::AM::InstallStatus);
|
Q_DECLARE_METATYPE(Service::AM::InstallStatus);
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr T AlignUp(T value, size_t size) {
|
constexpr T AlignUp(T value, std::size_t size) {
|
||||||
static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
|
static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
|
||||||
return static_cast<T>(value + (size - value % size) % size);
|
return static_cast<T>(value + (size - value % size) % size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr T AlignDown(T value, size_t size) {
|
constexpr T AlignDown(T value, std::size_t size) {
|
||||||
static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
|
static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
|
||||||
return static_cast<T>(value - value % size);
|
return static_cast<T>(value - value % size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,8 +125,8 @@ public:
|
||||||
BitField& operator=(const BitField&) = default;
|
BitField& operator=(const BitField&) = default;
|
||||||
|
|
||||||
/// Constants to allow limited introspection of fields if needed
|
/// Constants to allow limited introspection of fields if needed
|
||||||
static constexpr size_t position = Position;
|
static constexpr std::size_t position = Position;
|
||||||
static constexpr size_t bits = Bits;
|
static constexpr std::size_t bits = Bits;
|
||||||
static constexpr StorageType mask = (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position;
|
static constexpr StorageType mask = (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -155,14 +155,14 @@ public:
|
||||||
m_val |= (IntTy)1 << bit;
|
m_val |= (IntTy)1 << bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BitSet AllTrue(size_t count) {
|
static BitSet AllTrue(std::size_t count) {
|
||||||
return BitSet(count == sizeof(IntTy) * 8 ? ~(IntTy)0 : (((IntTy)1 << count) - 1));
|
return BitSet(count == sizeof(IntTy) * 8 ? ~(IntTy)0 : (((IntTy)1 << count) - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref operator[](size_t bit) {
|
Ref operator[](std::size_t bit) {
|
||||||
return Ref(this, (IntTy)1 << bit);
|
return Ref(this, (IntTy)1 << bit);
|
||||||
}
|
}
|
||||||
const Ref operator[](size_t bit) const {
|
const Ref operator[](std::size_t bit) const {
|
||||||
return (*const_cast<BitSet*>(this))[bit];
|
return (*const_cast<BitSet*>(this))[bit];
|
||||||
}
|
}
|
||||||
bool operator==(BitSet other) const {
|
bool operator==(BitSet other) const {
|
||||||
|
|
|
@ -114,7 +114,7 @@ static uint64 HashLen16(uint64 u, uint64 v, uint64 mul) {
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64 HashLen0to16(const char* s, size_t len) {
|
static uint64 HashLen0to16(const char* s, std::size_t len) {
|
||||||
if (len >= 8) {
|
if (len >= 8) {
|
||||||
uint64 mul = k2 + len * 2;
|
uint64 mul = k2 + len * 2;
|
||||||
uint64 a = Fetch64(s) + k2;
|
uint64 a = Fetch64(s) + k2;
|
||||||
|
@ -141,7 +141,7 @@ static uint64 HashLen0to16(const char* s, size_t len) {
|
||||||
|
|
||||||
// This probably works well for 16-byte strings as well, but it may be overkill
|
// This probably works well for 16-byte strings as well, but it may be overkill
|
||||||
// in that case.
|
// in that case.
|
||||||
static uint64 HashLen17to32(const char* s, size_t len) {
|
static uint64 HashLen17to32(const char* s, std::size_t len) {
|
||||||
uint64 mul = k2 + len * 2;
|
uint64 mul = k2 + len * 2;
|
||||||
uint64 a = Fetch64(s) * k1;
|
uint64 a = Fetch64(s) * k1;
|
||||||
uint64 b = Fetch64(s + 8);
|
uint64 b = Fetch64(s + 8);
|
||||||
|
@ -170,7 +170,7 @@ static pair<uint64, uint64> WeakHashLen32WithSeeds(const char* s, uint64 a, uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an 8-byte hash for 33 to 64 bytes.
|
// Return an 8-byte hash for 33 to 64 bytes.
|
||||||
static uint64 HashLen33to64(const char* s, size_t len) {
|
static uint64 HashLen33to64(const char* s, std::size_t len) {
|
||||||
uint64 mul = k2 + len * 2;
|
uint64 mul = k2 + len * 2;
|
||||||
uint64 a = Fetch64(s) * k2;
|
uint64 a = Fetch64(s) * k2;
|
||||||
uint64 b = Fetch64(s + 8);
|
uint64 b = Fetch64(s + 8);
|
||||||
|
@ -191,7 +191,7 @@ static uint64 HashLen33to64(const char* s, size_t len) {
|
||||||
return b + x;
|
return b + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 CityHash64(const char* s, size_t len) {
|
uint64 CityHash64(const char* s, std::size_t len) {
|
||||||
if (len <= 32) {
|
if (len <= 32) {
|
||||||
if (len <= 16) {
|
if (len <= 16) {
|
||||||
return HashLen0to16(s, len);
|
return HashLen0to16(s, len);
|
||||||
|
@ -212,7 +212,7 @@ uint64 CityHash64(const char* s, size_t len) {
|
||||||
x = x * k1 + Fetch64(s);
|
x = x * k1 + Fetch64(s);
|
||||||
|
|
||||||
// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
|
// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
|
||||||
len = (len - 1) & ~static_cast<size_t>(63);
|
len = (len - 1) & ~static_cast<std::size_t>(63);
|
||||||
do {
|
do {
|
||||||
x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
|
x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
|
||||||
y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
|
y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
|
||||||
|
@ -229,17 +229,17 @@ uint64 CityHash64(const char* s, size_t len) {
|
||||||
HashLen16(v.second, w.second) + x);
|
HashLen16(v.second, w.second) + x);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 CityHash64WithSeed(const char* s, size_t len, uint64 seed) {
|
uint64 CityHash64WithSeed(const char* s, std::size_t len, uint64 seed) {
|
||||||
return CityHash64WithSeeds(s, len, k2, seed);
|
return CityHash64WithSeeds(s, len, k2, seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 CityHash64WithSeeds(const char* s, size_t len, uint64 seed0, uint64 seed1) {
|
uint64 CityHash64WithSeeds(const char* s, std::size_t len, uint64 seed0, uint64 seed1) {
|
||||||
return HashLen16(CityHash64(s, len) - seed0, seed1);
|
return HashLen16(CityHash64(s, len) - seed0, seed1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
|
// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
|
||||||
// of any length representable in signed long. Based on City and Murmur.
|
// of any length representable in signed long. Based on City and Murmur.
|
||||||
static uint128 CityMurmur(const char* s, size_t len, uint128 seed) {
|
static uint128 CityMurmur(const char* s, std::size_t len, uint128 seed) {
|
||||||
uint64 a = Uint128Low64(seed);
|
uint64 a = Uint128Low64(seed);
|
||||||
uint64 b = Uint128High64(seed);
|
uint64 b = Uint128High64(seed);
|
||||||
uint64 c = 0;
|
uint64 c = 0;
|
||||||
|
@ -269,7 +269,7 @@ static uint128 CityMurmur(const char* s, size_t len, uint128 seed) {
|
||||||
return uint128(a ^ b, HashLen16(b, a));
|
return uint128(a ^ b, HashLen16(b, a));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed) {
|
uint128 CityHash128WithSeed(const char* s, std::size_t len, uint128 seed) {
|
||||||
if (len < 128) {
|
if (len < 128) {
|
||||||
return CityMurmur(s, len, seed);
|
return CityMurmur(s, len, seed);
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,7 @@ uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed) {
|
||||||
w.first *= 9;
|
w.first *= 9;
|
||||||
v.first *= k0;
|
v.first *= k0;
|
||||||
// If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
|
// If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
|
||||||
for (size_t tail_done = 0; tail_done < len;) {
|
for (std::size_t tail_done = 0; tail_done < len;) {
|
||||||
tail_done += 32;
|
tail_done += 32;
|
||||||
y = Rotate(x + y, 42) * k0 + v.second;
|
y = Rotate(x + y, 42) * k0 + v.second;
|
||||||
w.first += Fetch64(s + len - tail_done + 16);
|
w.first += Fetch64(s + len - tail_done + 16);
|
||||||
|
@ -331,7 +331,7 @@ uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed) {
|
||||||
return uint128(HashLen16(x + v.second, w.second) + y, HashLen16(x + w.second, y + v.second));
|
return uint128(HashLen16(x + v.second, w.second) + y, HashLen16(x + w.second, y + v.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint128 CityHash128(const char* s, size_t len) {
|
uint128 CityHash128(const char* s, std::size_t len) {
|
||||||
return len >= 16
|
return len >= 16
|
||||||
? CityHash128WithSeed(s + 16, len - 16, uint128(Fetch64(s), Fetch64(s + 8) + k0))
|
? CityHash128WithSeed(s + 16, len - 16, uint128(Fetch64(s), Fetch64(s + 8) + k0))
|
||||||
: CityHash128WithSeed(s, len, uint128(k0, k1));
|
: CityHash128WithSeed(s, len, uint128(k0, k1));
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h> // for size_t.
|
#include <stdlib.h> // for std::size_t.
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
@ -77,22 +77,22 @@ inline uint64_t Uint128High64(const uint128& x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash function for a byte array.
|
// Hash function for a byte array.
|
||||||
uint64_t CityHash64(const char* buf, size_t len);
|
uint64_t CityHash64(const char* buf, std::size_t len);
|
||||||
|
|
||||||
// Hash function for a byte array. For convenience, a 64-bit seed is also
|
// Hash function for a byte array. For convenience, a 64-bit seed is also
|
||||||
// hashed into the result.
|
// hashed into the result.
|
||||||
uint64_t CityHash64WithSeed(const char* buf, size_t len, uint64_t seed);
|
uint64_t CityHash64WithSeed(const char* buf, std::size_t len, uint64_t seed);
|
||||||
|
|
||||||
// Hash function for a byte array. For convenience, two seeds are also
|
// Hash function for a byte array. For convenience, two seeds are also
|
||||||
// hashed into the result.
|
// hashed into the result.
|
||||||
uint64_t CityHash64WithSeeds(const char* buf, size_t len, uint64_t seed0, uint64_t seed1);
|
uint64_t CityHash64WithSeeds(const char* buf, std::size_t len, uint64_t seed0, uint64_t seed1);
|
||||||
|
|
||||||
// Hash function for a byte array.
|
// Hash function for a byte array.
|
||||||
uint128 CityHash128(const char* s, size_t len);
|
uint128 CityHash128(const char* s, std::size_t len);
|
||||||
|
|
||||||
// Hash function for a byte array. For convenience, a 128-bit seed is also
|
// Hash function for a byte array. For convenience, a 128-bit seed is also
|
||||||
// hashed into the result.
|
// hashed into the result.
|
||||||
uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed);
|
uint128 CityHash128WithSeed(const char* s, std::size_t len, uint128 seed);
|
||||||
|
|
||||||
// Hash 128 input bits down to 64 bits of output.
|
// Hash 128 input bits down to 64 bits of output.
|
||||||
// This is intended to be a reasonably good hash function.
|
// This is intended to be a reasonably good hash function.
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace FileUtil {
|
||||||
// Modifies argument.
|
// Modifies argument.
|
||||||
static void StripTailDirSlashes(std::string& fname) {
|
static void StripTailDirSlashes(std::string& fname) {
|
||||||
if (fname.length() > 1) {
|
if (fname.length() > 1) {
|
||||||
size_t i = fname.length();
|
std::size_t i = fname.length();
|
||||||
while (i > 0 && fname[i - 1] == DIR_SEP_CHR)
|
while (i > 0 && fname[i - 1] == DIR_SEP_CHR)
|
||||||
--i;
|
--i;
|
||||||
fname.resize(i);
|
fname.resize(i);
|
||||||
|
@ -199,7 +199,7 @@ bool CreateFullPath(const std::string& fullPath) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t position = 0;
|
std::size_t position = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
// Find next sub path
|
// Find next sub path
|
||||||
position = fullPath.find(DIR_SEP_CHR, position);
|
position = fullPath.find(DIR_SEP_CHR, position);
|
||||||
|
@ -297,7 +297,7 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
|
||||||
std::array<char, 1024> buffer;
|
std::array<char, 1024> buffer;
|
||||||
while (!feof(input.get())) {
|
while (!feof(input.get())) {
|
||||||
// read input
|
// read input
|
||||||
size_t rnum = fread(buffer.data(), sizeof(char), buffer.size(), input.get());
|
std::size_t rnum = fread(buffer.data(), sizeof(char), buffer.size(), input.get());
|
||||||
if (rnum != buffer.size()) {
|
if (rnum != buffer.size()) {
|
||||||
if (ferror(input.get()) != 0) {
|
if (ferror(input.get()) != 0) {
|
||||||
LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
|
LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
|
||||||
|
@ -307,7 +307,7 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write output
|
// write output
|
||||||
size_t wnum = fwrite(buffer.data(), sizeof(char), rnum, output.get());
|
std::size_t wnum = fwrite(buffer.data(), sizeof(char), rnum, output.get());
|
||||||
if (wnum != rnum) {
|
if (wnum != rnum) {
|
||||||
LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
|
LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
|
||||||
destFilename, GetLastErrorMsg());
|
destFilename, GetLastErrorMsg());
|
||||||
|
|
|
@ -174,16 +174,16 @@ public:
|
||||||
bool Close();
|
bool Close();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t ReadArray(T* data, size_t length) {
|
std::size_t ReadArray(T* data, std::size_t length) {
|
||||||
static_assert(std::is_trivially_copyable_v<T>,
|
static_assert(std::is_trivially_copyable_v<T>,
|
||||||
"Given array does not consist of trivially copyable objects");
|
"Given array does not consist of trivially copyable objects");
|
||||||
|
|
||||||
if (!IsOpen()) {
|
if (!IsOpen()) {
|
||||||
m_good = false;
|
m_good = false;
|
||||||
return std::numeric_limits<size_t>::max();
|
return std::numeric_limits<std::size_t>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t items_read = std::fread(data, sizeof(T), length, m_file);
|
std::size_t items_read = std::fread(data, sizeof(T), length, m_file);
|
||||||
if (items_read != length)
|
if (items_read != length)
|
||||||
m_good = false;
|
m_good = false;
|
||||||
|
|
||||||
|
@ -191,16 +191,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t WriteArray(const T* data, size_t length) {
|
std::size_t WriteArray(const T* data, std::size_t length) {
|
||||||
static_assert(std::is_trivially_copyable_v<T>,
|
static_assert(std::is_trivially_copyable_v<T>,
|
||||||
"Given array does not consist of trivially copyable objects");
|
"Given array does not consist of trivially copyable objects");
|
||||||
|
|
||||||
if (!IsOpen()) {
|
if (!IsOpen()) {
|
||||||
m_good = false;
|
m_good = false;
|
||||||
return std::numeric_limits<size_t>::max();
|
return std::numeric_limits<std::size_t>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t items_written = std::fwrite(data, sizeof(T), length, m_file);
|
std::size_t items_written = std::fwrite(data, sizeof(T), length, m_file);
|
||||||
if (items_written != length)
|
if (items_written != length)
|
||||||
m_good = false;
|
m_good = false;
|
||||||
|
|
||||||
|
@ -208,24 +208,24 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t ReadBytes(T* data, size_t length) {
|
std::size_t ReadBytes(T* data, std::size_t length) {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
|
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
|
||||||
return ReadArray(reinterpret_cast<char*>(data), length);
|
return ReadArray(reinterpret_cast<char*>(data), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t WriteBytes(const T* data, size_t length) {
|
std::size_t WriteBytes(const T* data, std::size_t length) {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
|
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
|
||||||
return WriteArray(reinterpret_cast<const char*>(data), length);
|
return WriteArray(reinterpret_cast<const char*>(data), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t WriteObject(const T& object) {
|
std::size_t WriteObject(const T& object) {
|
||||||
static_assert(!std::is_pointer_v<T>, "WriteObject arguments must not be a pointer");
|
static_assert(!std::is_pointer_v<T>, "WriteObject arguments must not be a pointer");
|
||||||
return WriteArray(&object, 1);
|
return WriteArray(&object, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t WriteString(const std::string& str) {
|
std::size_t WriteString(const std::string& str) {
|
||||||
return WriteArray(str.c_str(), str.length());
|
return WriteArray(str.c_str(), str.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Common {
|
||||||
* @param len Length of data (in bytes) to compute hash over
|
* @param len Length of data (in bytes) to compute hash over
|
||||||
* @returns 64-bit hash value that was computed over the data block
|
* @returns 64-bit hash value that was computed over the data block
|
||||||
*/
|
*/
|
||||||
static inline u64 ComputeHash64(const void* data, size_t len) {
|
static inline u64 ComputeHash64(const void* data, std::size_t len) {
|
||||||
return CityHash64(static_cast<const char*>(data), len);
|
return CityHash64(static_cast<const char*>(data), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ struct HashableStruct {
|
||||||
return !(*this == o);
|
return !(*this == o);
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t Hash() const {
|
std::size_t Hash() const {
|
||||||
return Common::ComputeStructHash64(state);
|
return Common::ComputeStructHash64(state);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -132,7 +132,7 @@ FileBackend::FileBackend(const std::string& filename)
|
||||||
void FileBackend::Write(const Entry& entry) {
|
void FileBackend::Write(const Entry& entry) {
|
||||||
// prevent logs from going over the maximum size (in case its spamming and the user doesn't
|
// prevent logs from going over the maximum size (in case its spamming and the user doesn't
|
||||||
// know)
|
// know)
|
||||||
constexpr size_t MAX_BYTES_WRITTEN = 50 * 1024L * 1024L;
|
constexpr std::size_t MAX_BYTES_WRITTEN = 50 * 1024L * 1024L;
|
||||||
if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) {
|
if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileUtil::IOFile file;
|
FileUtil::IOFile file;
|
||||||
size_t bytes_written;
|
std::size_t bytes_written;
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddBackend(std::unique_ptr<Backend> backend);
|
void AddBackend(std::unique_ptr<Backend> backend);
|
||||||
|
|
|
@ -71,7 +71,7 @@ void Filter::ResetAll(Level level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filter::SetClassLevel(Class log_class, Level level) {
|
void Filter::SetClassLevel(Class log_class, Level level) {
|
||||||
class_levels[static_cast<size_t>(log_class)] = level;
|
class_levels[static_cast<std::size_t>(log_class)] = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Filter::ParseFilterString(std::string_view filter_view) {
|
void Filter::ParseFilterString(std::string_view filter_view) {
|
||||||
|
@ -93,6 +93,7 @@ void Filter::ParseFilterString(std::string_view filter_view) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Filter::CheckMessage(Class log_class, Level level) const {
|
bool Filter::CheckMessage(Class log_class, Level level) const {
|
||||||
return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]);
|
return static_cast<u8>(level) >=
|
||||||
|
static_cast<u8>(class_levels[static_cast<std::size_t>(log_class)]);
|
||||||
}
|
}
|
||||||
} // namespace Log
|
} // namespace Log
|
||||||
|
|
|
@ -46,6 +46,6 @@ public:
|
||||||
bool CheckMessage(Class log_class, Level level) const;
|
bool CheckMessage(Class log_class, Level level) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<Level, (size_t)Class::Count> class_levels;
|
std::array<Level, (std::size_t)Class::Count> class_levels;
|
||||||
};
|
};
|
||||||
} // namespace Log
|
} // namespace Log
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
// This is purposely not a full wrapper for virtualalloc/mmap, but it
|
// This is purposely not a full wrapper for virtualalloc/mmap, but it
|
||||||
// provides exactly the primitive operations that Dolphin needs.
|
// provides exactly the primitive operations that Dolphin needs.
|
||||||
|
|
||||||
void* AllocateExecutableMemory(size_t size, bool low) {
|
void* AllocateExecutableMemory(std::size_t size, bool low) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||||
#else
|
#else
|
||||||
|
@ -75,7 +75,7 @@ void* AllocateExecutableMemory(size_t size, bool low) {
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* AllocateMemoryPages(size_t size) {
|
void* AllocateMemoryPages(std::size_t size) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE);
|
void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE);
|
||||||
#else
|
#else
|
||||||
|
@ -91,7 +91,7 @@ void* AllocateMemoryPages(size_t size) {
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* AllocateAlignedMemory(size_t size, size_t alignment) {
|
void* AllocateAlignedMemory(std::size_t size, std::size_t alignment) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
void* ptr = _aligned_malloc(size, alignment);
|
void* ptr = _aligned_malloc(size, alignment);
|
||||||
#else
|
#else
|
||||||
|
@ -110,7 +110,7 @@ void* AllocateAlignedMemory(size_t size, size_t alignment) {
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeMemoryPages(void* ptr, size_t size) {
|
void FreeMemoryPages(void* ptr, std::size_t size) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (!VirtualFree(ptr, 0, MEM_RELEASE))
|
if (!VirtualFree(ptr, 0, MEM_RELEASE))
|
||||||
|
@ -131,7 +131,7 @@ void FreeAlignedMemory(void* ptr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
|
void WriteProtectMemory(void* ptr, std::size_t size, bool allowExecute) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD oldValue;
|
DWORD oldValue;
|
||||||
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
|
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
|
||||||
|
@ -141,7 +141,7 @@ void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
|
void UnWriteProtectMemory(void* ptr, std::size_t size, bool allowExecute) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD oldValue;
|
DWORD oldValue;
|
||||||
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
|
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
void* AllocateExecutableMemory(size_t size, bool low = true);
|
void* AllocateExecutableMemory(std::size_t size, bool low = true);
|
||||||
void* AllocateMemoryPages(size_t size);
|
void* AllocateMemoryPages(std::size_t size);
|
||||||
void FreeMemoryPages(void* ptr, size_t size);
|
void FreeMemoryPages(void* ptr, std::size_t size);
|
||||||
void* AllocateAlignedMemory(size_t size, size_t alignment);
|
void* AllocateAlignedMemory(std::size_t size, std::size_t alignment);
|
||||||
void FreeAlignedMemory(void* ptr);
|
void FreeAlignedMemory(void* ptr);
|
||||||
void WriteProtectMemory(void* ptr, size_t size, bool executable = false);
|
void WriteProtectMemory(void* ptr, std::size_t size, bool executable = false);
|
||||||
void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute = false);
|
void UnWriteProtectMemory(void* ptr, std::size_t size, bool allowExecute = false);
|
||||||
std::string MemUsage();
|
std::string MemUsage();
|
||||||
|
|
||||||
inline int GetPageSize() {
|
inline int GetPageSize() {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
// Call directly after the command or use the error num.
|
// Call directly after the command or use the error num.
|
||||||
// This function might change the error code.
|
// This function might change the error code.
|
||||||
std::string GetLastErrorMsg() {
|
std::string GetLastErrorMsg() {
|
||||||
static const size_t buff_size = 255;
|
static const std::size_t buff_size = 255;
|
||||||
char err_str[buff_size];
|
char err_str[buff_size];
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -37,7 +37,7 @@ std::string ToUpper(std::string str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For Debugging. Read out an u8 array.
|
// For Debugging. Read out an u8 array.
|
||||||
std::string ArrayToString(const u8* data, size_t size, int line_len, bool spaces) {
|
std::string ArrayToString(const u8* data, std::size_t size, int line_len, bool spaces) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << std::setfill('0') << std::hex;
|
oss << std::setfill('0') << std::hex;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ std::string ArrayToString(const u8* data, size_t size, int line_len, bool spaces
|
||||||
|
|
||||||
// Turns " hej " into "hej". Also handles tabs.
|
// Turns " hej " into "hej". Also handles tabs.
|
||||||
std::string StripSpaces(const std::string& str) {
|
std::string StripSpaces(const std::string& str) {
|
||||||
const size_t s = str.find_first_not_of(" \t\r\n");
|
const std::size_t s = str.find_first_not_of(" \t\r\n");
|
||||||
|
|
||||||
if (str.npos != s)
|
if (str.npos != s)
|
||||||
return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1);
|
return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1);
|
||||||
|
@ -117,7 +117,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
|
||||||
if (full_path.empty())
|
if (full_path.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t dir_end = full_path.find_last_of("/"
|
std::size_t dir_end = full_path.find_last_of("/"
|
||||||
// windows needs the : included for something like just "C:" to be considered a directory
|
// windows needs the : included for something like just "C:" to be considered a directory
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
":"
|
":"
|
||||||
|
@ -128,7 +128,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
|
||||||
else
|
else
|
||||||
dir_end += 1;
|
dir_end += 1;
|
||||||
|
|
||||||
size_t fname_end = full_path.rfind('.');
|
std::size_t fname_end = full_path.rfind('.');
|
||||||
if (fname_end < dir_end || std::string::npos == fname_end)
|
if (fname_end < dir_end || std::string::npos == fname_end)
|
||||||
fname_end = full_path.size();
|
fname_end = full_path.size();
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ void SplitString(const std::string& str, const char delim, std::vector<std::stri
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TabsToSpaces(int tab_size, std::string in) {
|
std::string TabsToSpaces(int tab_size, std::string in) {
|
||||||
size_t i = 0;
|
std::size_t i = 0;
|
||||||
|
|
||||||
while ((i = in.find('\t')) != std::string::npos) {
|
while ((i = in.find('\t')) != std::string::npos) {
|
||||||
in.replace(i, 1, tab_size, ' ');
|
in.replace(i, 1, tab_size, ' ');
|
||||||
|
@ -178,7 +178,7 @@ std::string TabsToSpaces(int tab_size, std::string in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) {
|
std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) {
|
||||||
size_t pos = 0;
|
std::size_t pos = 0;
|
||||||
|
|
||||||
if (src == dest)
|
if (src == dest)
|
||||||
return result;
|
return result;
|
||||||
|
@ -276,22 +276,22 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>&
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t in_bytes = sizeof(T) * input.size();
|
const std::size_t in_bytes = sizeof(T) * input.size();
|
||||||
// Multiply by 4, which is the max number of bytes to encode a codepoint
|
// Multiply by 4, which is the max number of bytes to encode a codepoint
|
||||||
const size_t out_buffer_size = 4 * in_bytes;
|
const std::size_t out_buffer_size = 4 * in_bytes;
|
||||||
|
|
||||||
std::string out_buffer(out_buffer_size, '\0');
|
std::string out_buffer(out_buffer_size, '\0');
|
||||||
|
|
||||||
auto src_buffer = &input[0];
|
auto src_buffer = &input[0];
|
||||||
size_t src_bytes = in_bytes;
|
std::size_t src_bytes = in_bytes;
|
||||||
auto dst_buffer = &out_buffer[0];
|
auto dst_buffer = &out_buffer[0];
|
||||||
size_t dst_bytes = out_buffer.size();
|
std::size_t dst_bytes = out_buffer.size();
|
||||||
|
|
||||||
while (0 != src_bytes) {
|
while (0 != src_bytes) {
|
||||||
size_t const iconv_result =
|
std::size_t const iconv_result =
|
||||||
iconv(conv_desc, (char**)(&src_buffer), &src_bytes, &dst_buffer, &dst_bytes);
|
iconv(conv_desc, (char**)(&src_buffer), &src_bytes, &dst_buffer, &dst_bytes);
|
||||||
|
|
||||||
if (static_cast<size_t>(-1) == iconv_result) {
|
if (static_cast<std::size_t>(-1) == iconv_result) {
|
||||||
if (EILSEQ == errno || EINVAL == errno) {
|
if (EILSEQ == errno || EINVAL == errno) {
|
||||||
// Try to skip the bad character
|
// Try to skip the bad character
|
||||||
if (0 != src_bytes) {
|
if (0 != src_bytes) {
|
||||||
|
@ -322,22 +322,22 @@ std::u16string UTF8ToUTF16(const std::string& input) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t in_bytes = sizeof(char) * input.size();
|
const std::size_t in_bytes = sizeof(char) * input.size();
|
||||||
// Multiply by 4, which is the max number of bytes to encode a codepoint
|
// Multiply by 4, which is the max number of bytes to encode a codepoint
|
||||||
const size_t out_buffer_size = 4 * sizeof(char16_t) * in_bytes;
|
const std::size_t out_buffer_size = 4 * sizeof(char16_t) * in_bytes;
|
||||||
|
|
||||||
std::u16string out_buffer(out_buffer_size, char16_t{});
|
std::u16string out_buffer(out_buffer_size, char16_t{});
|
||||||
|
|
||||||
char* src_buffer = const_cast<char*>(&input[0]);
|
char* src_buffer = const_cast<char*>(&input[0]);
|
||||||
size_t src_bytes = in_bytes;
|
std::size_t src_bytes = in_bytes;
|
||||||
char* dst_buffer = (char*)(&out_buffer[0]);
|
char* dst_buffer = (char*)(&out_buffer[0]);
|
||||||
size_t dst_bytes = out_buffer.size();
|
std::size_t dst_bytes = out_buffer.size();
|
||||||
|
|
||||||
while (0 != src_bytes) {
|
while (0 != src_bytes) {
|
||||||
size_t const iconv_result =
|
std::size_t const iconv_result =
|
||||||
iconv(conv_desc, &src_buffer, &src_bytes, &dst_buffer, &dst_bytes);
|
iconv(conv_desc, &src_buffer, &src_bytes, &dst_buffer, &dst_bytes);
|
||||||
|
|
||||||
if (static_cast<size_t>(-1) == iconv_result) {
|
if (static_cast<std::size_t>(-1) == iconv_result) {
|
||||||
if (EILSEQ == errno || EINVAL == errno) {
|
if (EILSEQ == errno || EINVAL == errno) {
|
||||||
// Try to skip the bad character
|
// Try to skip the bad character
|
||||||
if (0 != src_bytes) {
|
if (0 != src_bytes) {
|
||||||
|
@ -377,8 +377,8 @@ std::string SHIFTJISToUTF8(const std::string& input) {
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len) {
|
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t max_len) {
|
||||||
size_t len = 0;
|
std::size_t len = 0;
|
||||||
while (len < max_len && buffer[len] != '\0')
|
while (len < max_len && buffer[len] != '\0')
|
||||||
++len;
|
++len;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ std::string ToLower(std::string str);
|
||||||
/// Make a string uppercase
|
/// Make a string uppercase
|
||||||
std::string ToUpper(std::string str);
|
std::string ToUpper(std::string str);
|
||||||
|
|
||||||
std::string ArrayToString(const u8* data, size_t size, int line_len = 20, bool spaces = true);
|
std::string ArrayToString(const u8* data, std::size_t size, int line_len = 20, bool spaces = true);
|
||||||
|
|
||||||
std::string StripSpaces(const std::string& s);
|
std::string StripSpaces(const std::string& s);
|
||||||
std::string StripQuotes(const std::string& s);
|
std::string StripQuotes(const std::string& s);
|
||||||
|
@ -116,7 +116,7 @@ bool ComparePartialString(InIt begin, InIt end, const char* other) {
|
||||||
* Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't
|
* Creates a std::string from a fixed-size NUL-terminated char buffer. If the buffer isn't
|
||||||
* NUL-terminated then the string ends at max_len characters.
|
* NUL-terminated then the string ends at max_len characters.
|
||||||
*/
|
*/
|
||||||
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len);
|
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, std::size_t max_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to trim an arbitrary prefix from `path`, leaving only the part starting at `root`. It's
|
* Attempts to trim an arbitrary prefix from `path`, leaving only the part starting at `root`. It's
|
||||||
|
|
|
@ -88,12 +88,12 @@ private:
|
||||||
|
|
||||||
class Barrier {
|
class Barrier {
|
||||||
public:
|
public:
|
||||||
explicit Barrier(size_t count_) : count(count_), waiting(0), generation(0) {}
|
explicit Barrier(std::size_t count_) : count(count_), waiting(0), generation(0) {}
|
||||||
|
|
||||||
/// Blocks until all "count" threads have called Sync()
|
/// Blocks until all "count" threads have called Sync()
|
||||||
void Sync() {
|
void Sync() {
|
||||||
std::unique_lock<std::mutex> lk(mutex);
|
std::unique_lock<std::mutex> lk(mutex);
|
||||||
const size_t current_generation = generation;
|
const std::size_t current_generation = generation;
|
||||||
|
|
||||||
if (++waiting == count) {
|
if (++waiting == count) {
|
||||||
generation++;
|
generation++;
|
||||||
|
@ -108,9 +108,9 @@ public:
|
||||||
private:
|
private:
|
||||||
std::condition_variable condvar;
|
std::condition_variable condvar;
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
const size_t count;
|
const std::size_t count;
|
||||||
size_t waiting;
|
std::size_t waiting;
|
||||||
size_t generation; // Incremented once each time the barrier is used
|
std::size_t generation; // Incremented once each time the barrier is used
|
||||||
};
|
};
|
||||||
|
|
||||||
void SleepCurrentThread(int ms);
|
void SleepCurrentThread(int ms);
|
||||||
|
|
|
@ -97,7 +97,7 @@ const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
|
||||||
Xbyak::util::xmm15,
|
Xbyak::util::xmm15,
|
||||||
});
|
});
|
||||||
|
|
||||||
constexpr size_t ABI_SHADOW_SPACE = 0x20;
|
constexpr std::size_t ABI_SHADOW_SPACE = 0x20;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -147,22 +147,23 @@ const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
|
||||||
Xbyak::util::r15,
|
Xbyak::util::r15,
|
||||||
});
|
});
|
||||||
|
|
||||||
constexpr size_t ABI_SHADOW_SPACE = 0;
|
constexpr std::size_t ABI_SHADOW_SPACE = 0;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t needed_frame_size,
|
inline void ABI_CalculateFrameSize(BitSet32 regs, std::size_t rsp_alignment,
|
||||||
s32* out_subtraction, s32* out_xmm_offset) {
|
std::size_t needed_frame_size, s32* out_subtraction,
|
||||||
|
s32* out_xmm_offset) {
|
||||||
int count = (regs & ABI_ALL_GPRS).Count();
|
int count = (regs & ABI_ALL_GPRS).Count();
|
||||||
rsp_alignment -= count * 8;
|
rsp_alignment -= count * 8;
|
||||||
size_t subtraction = 0;
|
std::size_t subtraction = 0;
|
||||||
int xmm_count = (regs & ABI_ALL_XMMS).Count();
|
int xmm_count = (regs & ABI_ALL_XMMS).Count();
|
||||||
if (xmm_count) {
|
if (xmm_count) {
|
||||||
// If we have any XMMs to save, we must align the stack here.
|
// If we have any XMMs to save, we must align the stack here.
|
||||||
subtraction = rsp_alignment & 0xF;
|
subtraction = rsp_alignment & 0xF;
|
||||||
}
|
}
|
||||||
subtraction += 0x10 * xmm_count;
|
subtraction += 0x10 * xmm_count;
|
||||||
size_t xmm_base_subtraction = subtraction;
|
std::size_t xmm_base_subtraction = subtraction;
|
||||||
subtraction += needed_frame_size;
|
subtraction += needed_frame_size;
|
||||||
subtraction += ABI_SHADOW_SPACE;
|
subtraction += ABI_SHADOW_SPACE;
|
||||||
// Final alignment.
|
// Final alignment.
|
||||||
|
@ -173,8 +174,9 @@ inline void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t n
|
||||||
*out_xmm_offset = (s32)(subtraction - xmm_base_subtraction);
|
*out_xmm_offset = (s32)(subtraction - xmm_base_subtraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
|
inline std::size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
|
||||||
size_t rsp_alignment, size_t needed_frame_size = 0) {
|
std::size_t rsp_alignment,
|
||||||
|
std::size_t needed_frame_size = 0) {
|
||||||
s32 subtraction, xmm_offset;
|
s32 subtraction, xmm_offset;
|
||||||
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
||||||
|
|
||||||
|
@ -195,7 +197,8 @@ inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
|
inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs,
|
||||||
size_t rsp_alignment, size_t needed_frame_size = 0) {
|
std::size_t rsp_alignment,
|
||||||
|
std::size_t needed_frame_size = 0) {
|
||||||
s32 subtraction, xmm_offset;
|
s32 subtraction, xmm_offset;
|
||||||
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ inline bool IsWithin2G(const Xbyak::CodeGenerator& code, uintptr_t target) {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) {
|
inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) {
|
||||||
static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer.");
|
static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer.");
|
||||||
size_t addr = reinterpret_cast<size_t>(f);
|
std::size_t addr = reinterpret_cast<std::size_t>(f);
|
||||||
if (IsWithin2G(code, addr)) {
|
if (IsWithin2G(code, addr)) {
|
||||||
code.call(f);
|
code.call(f);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,12 +20,12 @@ public:
|
||||||
virtual ~ThreadContext() = default;
|
virtual ~ThreadContext() = default;
|
||||||
|
|
||||||
virtual void Reset() = 0;
|
virtual void Reset() = 0;
|
||||||
virtual u32 GetCpuRegister(size_t index) const = 0;
|
virtual u32 GetCpuRegister(std::size_t index) const = 0;
|
||||||
virtual void SetCpuRegister(size_t index, u32 value) = 0;
|
virtual void SetCpuRegister(std::size_t index, u32 value) = 0;
|
||||||
virtual u32 GetCpsr() const = 0;
|
virtual u32 GetCpsr() const = 0;
|
||||||
virtual void SetCpsr(u32 value) = 0;
|
virtual void SetCpsr(u32 value) = 0;
|
||||||
virtual u32 GetFpuRegister(size_t index) const = 0;
|
virtual u32 GetFpuRegister(std::size_t index) const = 0;
|
||||||
virtual void SetFpuRegister(size_t index, u32 value) = 0;
|
virtual void SetFpuRegister(std::size_t index, u32 value) = 0;
|
||||||
virtual u32 GetFpscr() const = 0;
|
virtual u32 GetFpscr() const = 0;
|
||||||
virtual void SetFpscr(u32 value) = 0;
|
virtual void SetFpscr(u32 value) = 0;
|
||||||
virtual u32 GetFpexc() const = 0;
|
virtual u32 GetFpexc() const = 0;
|
||||||
|
@ -67,7 +67,7 @@ public:
|
||||||
* @param start_address The starting address of the range to invalidate.
|
* @param start_address The starting address of the range to invalidate.
|
||||||
* @param length The length (in bytes) of the range to invalidate.
|
* @param length The length (in bytes) of the range to invalidate.
|
||||||
*/
|
*/
|
||||||
virtual void InvalidateCacheRange(u32 start_address, size_t length) = 0;
|
virtual void InvalidateCacheRange(u32 start_address, std::size_t length) = 0;
|
||||||
|
|
||||||
/// Notify CPU emulation that page tables have changed
|
/// Notify CPU emulation that page tables have changed
|
||||||
virtual void PageTableChanged() = 0;
|
virtual void PageTableChanged() = 0;
|
||||||
|
|
|
@ -30,10 +30,10 @@ public:
|
||||||
fpexc = 0;
|
fpexc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetCpuRegister(size_t index) const override {
|
u32 GetCpuRegister(std::size_t index) const override {
|
||||||
return ctx.Regs()[index];
|
return ctx.Regs()[index];
|
||||||
}
|
}
|
||||||
void SetCpuRegister(size_t index, u32 value) override {
|
void SetCpuRegister(std::size_t index, u32 value) override {
|
||||||
ctx.Regs()[index] = value;
|
ctx.Regs()[index] = value;
|
||||||
}
|
}
|
||||||
u32 GetCpsr() const override {
|
u32 GetCpsr() const override {
|
||||||
|
@ -42,10 +42,10 @@ public:
|
||||||
void SetCpsr(u32 value) override {
|
void SetCpsr(u32 value) override {
|
||||||
ctx.SetCpsr(value);
|
ctx.SetCpsr(value);
|
||||||
}
|
}
|
||||||
u32 GetFpuRegister(size_t index) const override {
|
u32 GetFpuRegister(std::size_t index) const override {
|
||||||
return ctx.ExtRegs()[index];
|
return ctx.ExtRegs()[index];
|
||||||
}
|
}
|
||||||
void SetFpuRegister(size_t index, u32 value) override {
|
void SetFpuRegister(std::size_t index, u32 value) override {
|
||||||
ctx.ExtRegs()[index] = value;
|
ctx.ExtRegs()[index] = value;
|
||||||
}
|
}
|
||||||
u32 GetFpscr() const override {
|
u32 GetFpscr() const override {
|
||||||
|
@ -99,7 +99,7 @@ public:
|
||||||
Memory::Write64(vaddr, value);
|
Memory::Write64(vaddr, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterFallback(VAddr pc, size_t num_instructions) override {
|
void InterpreterFallback(VAddr pc, std::size_t num_instructions) override {
|
||||||
parent.interpreter_state->Reg = parent.jit->Regs();
|
parent.interpreter_state->Reg = parent.jit->Regs();
|
||||||
parent.interpreter_state->Cpsr = parent.jit->Cpsr();
|
parent.interpreter_state->Cpsr = parent.jit->Cpsr();
|
||||||
parent.interpreter_state->Reg[15] = pc;
|
parent.interpreter_state->Reg[15] = pc;
|
||||||
|
@ -126,7 +126,7 @@ public:
|
||||||
|
|
||||||
void ExceptionRaised(VAddr pc, Dynarmic::A32::Exception exception) override {
|
void ExceptionRaised(VAddr pc, Dynarmic::A32::Exception exception) override {
|
||||||
ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})",
|
ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})",
|
||||||
static_cast<size_t>(exception), pc, MemoryReadCode(pc));
|
static_cast<std::size_t>(exception), pc, MemoryReadCode(pc));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddTicks(std::uint64_t ticks) override {
|
void AddTicks(std::uint64_t ticks) override {
|
||||||
|
@ -253,7 +253,7 @@ void ARM_Dynarmic::ClearInstructionCache() {
|
||||||
interpreter_state->instruction_cache.clear();
|
interpreter_state->instruction_cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, size_t length) {
|
void ARM_Dynarmic::InvalidateCacheRange(u32 start_address, std::size_t length) {
|
||||||
jit->InvalidateCacheRange(start_address, length);
|
jit->InvalidateCacheRange(start_address, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
void PrepareReschedule() override;
|
void PrepareReschedule() override;
|
||||||
|
|
||||||
void ClearInstructionCache() override;
|
void ClearInstructionCache() override;
|
||||||
void InvalidateCacheRange(u32 start_address, size_t length) override;
|
void InvalidateCacheRange(u32 start_address, std::size_t length) override;
|
||||||
void PageTableChanged() override;
|
void PageTableChanged() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -27,10 +27,10 @@ public:
|
||||||
fpexc = 0;
|
fpexc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetCpuRegister(size_t index) const override {
|
u32 GetCpuRegister(std::size_t index) const override {
|
||||||
return cpu_registers[index];
|
return cpu_registers[index];
|
||||||
}
|
}
|
||||||
void SetCpuRegister(size_t index, u32 value) override {
|
void SetCpuRegister(std::size_t index, u32 value) override {
|
||||||
cpu_registers[index] = value;
|
cpu_registers[index] = value;
|
||||||
}
|
}
|
||||||
u32 GetCpsr() const override {
|
u32 GetCpsr() const override {
|
||||||
|
@ -39,10 +39,10 @@ public:
|
||||||
void SetCpsr(u32 value) override {
|
void SetCpsr(u32 value) override {
|
||||||
cpsr = value;
|
cpsr = value;
|
||||||
}
|
}
|
||||||
u32 GetFpuRegister(size_t index) const override {
|
u32 GetFpuRegister(std::size_t index) const override {
|
||||||
return fpu_registers[index];
|
return fpu_registers[index];
|
||||||
}
|
}
|
||||||
void SetFpuRegister(size_t index, u32 value) override {
|
void SetFpuRegister(std::size_t index, u32 value) override {
|
||||||
fpu_registers[index] = value;
|
fpu_registers[index] = value;
|
||||||
}
|
}
|
||||||
u32 GetFpscr() const override {
|
u32 GetFpscr() const override {
|
||||||
|
@ -87,7 +87,7 @@ void ARM_DynCom::ClearInstructionCache() {
|
||||||
trans_cache_buf_top = 0;
|
trans_cache_buf_top = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_DynCom::InvalidateCacheRange(u32, size_t) {
|
void ARM_DynCom::InvalidateCacheRange(u32, std::size_t) {
|
||||||
ClearInstructionCache();
|
ClearInstructionCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
void Step() override;
|
void Step() override;
|
||||||
|
|
||||||
void ClearInstructionCache() override;
|
void ClearInstructionCache() override;
|
||||||
void InvalidateCacheRange(u32 start_address, size_t length) override;
|
void InvalidateCacheRange(u32 start_address, std::size_t length) override;
|
||||||
void PageTableChanged() override;
|
void PageTableChanged() override;
|
||||||
|
|
||||||
void SetPC(u32 pc) override;
|
void SetPC(u32 pc) override;
|
||||||
|
|
|
@ -293,7 +293,7 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3
|
||||||
0xE6FF0FB0, // REVSH
|
0xE6FF0FB0, // REVSH
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t subset_index = BITS(tinstr, 6, 7);
|
std::size_t subset_index = BITS(tinstr, 6, 7);
|
||||||
|
|
||||||
if (subset_index == 2) {
|
if (subset_index == 2) {
|
||||||
valid = ThumbDecodeStatus::UNDEFINED;
|
valid = ThumbDecodeStatus::UNDEFINED;
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
char trans_cache_buf[TRANS_CACHE_SIZE];
|
char trans_cache_buf[TRANS_CACHE_SIZE];
|
||||||
size_t trans_cache_buf_top = 0;
|
size_t trans_cache_buf_top = 0;
|
||||||
|
|
||||||
static void* AllocBuffer(size_t size) {
|
static void* AllocBuffer(std::size_t size) {
|
||||||
size_t start = trans_cache_buf_top;
|
std::size_t start = trans_cache_buf_top;
|
||||||
trans_cache_buf_top += size;
|
trans_cache_buf_top += size;
|
||||||
ASSERT_MSG(trans_cache_buf_top <= TRANS_CACHE_SIZE, "Translation cache is full!");
|
ASSERT_MSG(trans_cache_buf_top <= TRANS_CACHE_SIZE, "Translation cache is full!");
|
||||||
return static_cast<void*>(&trans_cache_buf[start]);
|
return static_cast<void*>(&trans_cache_buf[start]);
|
||||||
|
@ -2015,4 +2015,4 @@ const transop_fp_t arm_instruction_trans[] = {
|
||||||
INTERPRETER_TRANSLATE(blx_1_thumb),
|
INTERPRETER_TRANSLATE(blx_1_thumb),
|
||||||
};
|
};
|
||||||
|
|
||||||
const size_t arm_instruction_trans_len = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
|
const std::size_t arm_instruction_trans_len = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
|
||||||
|
|
|
@ -491,8 +491,8 @@ typedef arm_inst* ARM_INST_PTR;
|
||||||
typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
|
typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
|
||||||
|
|
||||||
extern const transop_fp_t arm_instruction_trans[];
|
extern const transop_fp_t arm_instruction_trans[];
|
||||||
extern const size_t arm_instruction_trans_len;
|
extern const std::size_t arm_instruction_trans_len;
|
||||||
|
|
||||||
#define TRANS_CACHE_SIZE (64 * 1024 * 2000)
|
#define TRANS_CACHE_SIZE (64 * 1024 * 2000)
|
||||||
extern char trans_cache_buf[TRANS_CACHE_SIZE];
|
extern char trans_cache_buf[TRANS_CACHE_SIZE];
|
||||||
extern size_t trans_cache_buf_top;
|
extern std::size_t trans_cache_buf_top;
|
||||||
|
|
|
@ -102,7 +102,7 @@ std::vector<u8> Path::AsBinary() const {
|
||||||
case LowPathType::Wchar: {
|
case LowPathType::Wchar: {
|
||||||
// use two u8 for each character of u16str
|
// use two u8 for each character of u16str
|
||||||
std::vector<u8> to_return(u16str.size() * 2);
|
std::vector<u8> to_return(u16str.size() * 2);
|
||||||
for (size_t i = 0; i < u16str.size(); ++i) {
|
for (std::size_t i = 0; i < u16str.size(); ++i) {
|
||||||
u16 tmp_char = u16str.at(i);
|
u16 tmp_char = u16str.at(i);
|
||||||
to_return[i * 2] = (tmp_char & 0xFF00) >> 8;
|
to_return[i * 2] = (tmp_char & 0xFF00) >> 8;
|
||||||
to_return[i * 2 + 1] = (tmp_char & 0x00FF);
|
to_return[i * 2 + 1] = (tmp_char & 0x00FF);
|
||||||
|
|
|
@ -37,11 +37,12 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) override {
|
ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
|
||||||
|
const u8* buffer) override {
|
||||||
if (offset > size) {
|
if (offset > size) {
|
||||||
return ERR_WRITE_BEYOND_END;
|
return ERR_WRITE_BEYOND_END;
|
||||||
} else if (offset == size) {
|
} else if (offset == size) {
|
||||||
return MakeResult<size_t>(0);
|
return MakeResult<std::size_t>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset + length > size) {
|
if (offset + length > size) {
|
||||||
|
@ -57,7 +58,7 @@ private:
|
||||||
|
|
||||||
class ExtSaveDataDelayGenerator : public DelayGenerator {
|
class ExtSaveDataDelayGenerator : public DelayGenerator {
|
||||||
public:
|
public:
|
||||||
u64 GetReadDelayNs(size_t length) override {
|
u64 GetReadDelayNs(std::size_t length) override {
|
||||||
// This is the delay measured for a savedate read,
|
// This is the delay measured for a savedate read,
|
||||||
// not for extsaveData
|
// not for extsaveData
|
||||||
// For now we will take that
|
// For now we will take that
|
||||||
|
@ -275,7 +276,7 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_ExtSaveData::GetFormatInfo(const Pat
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data,
|
void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data,
|
||||||
size_t icon_size) {
|
std::size_t icon_size) {
|
||||||
std::string game_path = FileSys::GetExtSaveDataPath(GetMountPoint(), path);
|
std::string game_path = FileSys::GetExtSaveDataPath(GetMountPoint(), path);
|
||||||
FileUtil::IOFile icon_file(game_path + "icon", "wb");
|
FileUtil::IOFile icon_file(game_path + "icon", "wb");
|
||||||
icon_file.WriteBytes(icon_data, icon_size);
|
icon_file.WriteBytes(icon_data, icon_size);
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
* @param icon_data Binary data of the icon
|
* @param icon_data Binary data of the icon
|
||||||
* @param icon_size Size of the icon data
|
* @param icon_size Size of the icon data
|
||||||
*/
|
*/
|
||||||
void WriteIcon(const Path& path, const u8* icon_data, size_t icon_size);
|
void WriteIcon(const Path& path, const u8* icon_data, std::size_t icon_size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool shared; ///< Whether this archive represents an ExtSaveData archive or a SharedExtSaveData
|
bool shared; ///< Whether this archive represents an ExtSaveData archive or a SharedExtSaveData
|
||||||
|
|
|
@ -238,23 +238,24 @@ NCCHFile::NCCHFile(std::vector<u8> buffer, std::unique_ptr<DelayGenerator> delay
|
||||||
delay_generator = std::move(delay_generator_);
|
delay_generator = std::move(delay_generator_);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> NCCHFile::Read(const u64 offset, const size_t length, u8* buffer) const {
|
ResultVal<std::size_t> NCCHFile::Read(const u64 offset, const std::size_t length,
|
||||||
|
u8* buffer) const {
|
||||||
LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
||||||
size_t length_left = static_cast<size_t>(data_size - offset);
|
std::size_t length_left = static_cast<std::size_t>(data_size - offset);
|
||||||
size_t read_length = static_cast<size_t>(std::min(length, length_left));
|
std::size_t read_length = static_cast<std::size_t>(std::min(length, length_left));
|
||||||
|
|
||||||
size_t available_size = static_cast<size_t>(file_buffer.size() - offset);
|
std::size_t available_size = static_cast<std::size_t>(file_buffer.size() - offset);
|
||||||
size_t copy_size = std::min(length, available_size);
|
std::size_t copy_size = std::min(length, available_size);
|
||||||
memcpy(buffer, file_buffer.data() + offset, copy_size);
|
memcpy(buffer, file_buffer.data() + offset, copy_size);
|
||||||
|
|
||||||
return MakeResult<size_t>(copy_size);
|
return MakeResult<std::size_t>(copy_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> NCCHFile::Write(const u64 offset, const size_t length, const bool flush,
|
ResultVal<std::size_t> NCCHFile::Write(const u64 offset, const std::size_t length, const bool flush,
|
||||||
const u8* buffer) {
|
const u8* buffer) {
|
||||||
LOG_ERROR(Service_FS, "Attempted to write to NCCH file");
|
LOG_ERROR(Service_FS, "Attempted to write to NCCH file");
|
||||||
// TODO(shinyquagsire23): Find error code
|
// TODO(shinyquagsire23): Find error code
|
||||||
return MakeResult<size_t>(0);
|
return MakeResult<std::size_t>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NCCHFile::GetSize() const {
|
u64 NCCHFile::GetSize() const {
|
||||||
|
|
|
@ -72,8 +72,9 @@ class NCCHFile : public FileBackend {
|
||||||
public:
|
public:
|
||||||
explicit NCCHFile(std::vector<u8> buffer, std::unique_ptr<DelayGenerator> delay_generator_);
|
explicit NCCHFile(std::vector<u8> buffer, std::unique_ptr<DelayGenerator> delay_generator_);
|
||||||
|
|
||||||
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
|
ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const override;
|
||||||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) override;
|
ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
|
||||||
|
const u8* buffer) override;
|
||||||
u64 GetSize() const override;
|
u64 GetSize() const override;
|
||||||
bool SetSize(u64 size) const override;
|
bool SetSize(u64 size) const override;
|
||||||
bool Close() const override {
|
bool Close() const override {
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace FileSys {
|
||||||
|
|
||||||
class SDMCDelayGenerator : public DelayGenerator {
|
class SDMCDelayGenerator : public DelayGenerator {
|
||||||
public:
|
public:
|
||||||
u64 GetReadDelayNs(size_t length) override {
|
u64 GetReadDelayNs(std::size_t length) override {
|
||||||
// This is the delay measured on O3DS and O2DS with
|
// This is the delay measured on O3DS and O2DS with
|
||||||
// https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
|
// https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
|
||||||
// from the results the average of each length was taken.
|
// from the results the average of each length was taken.
|
||||||
|
|
|
@ -36,7 +36,7 @@ class ExeFSSectionFile final : public FileBackend {
|
||||||
public:
|
public:
|
||||||
explicit ExeFSSectionFile(std::shared_ptr<std::vector<u8>> data_) : data(std::move(data_)) {}
|
explicit ExeFSSectionFile(std::shared_ptr<std::vector<u8>> data_) : data(std::move(data_)) {}
|
||||||
|
|
||||||
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override {
|
ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const override {
|
||||||
if (offset != 0) {
|
if (offset != 0) {
|
||||||
LOG_ERROR(Service_FS, "offset must be zero!");
|
LOG_ERROR(Service_FS, "offset must be zero!");
|
||||||
return ERROR_UNSUPPORTED_OPEN_FLAGS;
|
return ERROR_UNSUPPORTED_OPEN_FLAGS;
|
||||||
|
@ -48,10 +48,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memcpy(buffer, data->data(), data->size());
|
std::memcpy(buffer, data->data(), data->size());
|
||||||
return MakeResult<size_t>(data->size());
|
return MakeResult<std::size_t>(data->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) override {
|
ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
|
||||||
|
const u8* buffer) override {
|
||||||
LOG_ERROR(Service_FS, "The file is read-only!");
|
LOG_ERROR(Service_FS, "The file is read-only!");
|
||||||
return ERROR_UNSUPPORTED_OPEN_FLAGS;
|
return ERROR_UNSUPPORTED_OPEN_FLAGS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ Loader::ResultStatus CIAContainer::Load(const FileBackend& backend) {
|
||||||
std::vector<u8> header_data(sizeof(Header));
|
std::vector<u8> header_data(sizeof(Header));
|
||||||
|
|
||||||
// Load the CIA Header
|
// Load the CIA Header
|
||||||
ResultVal<size_t> read_result = backend.Read(0, sizeof(Header), header_data.data());
|
ResultVal<std::size_t> read_result = backend.Read(0, sizeof(Header), header_data.data());
|
||||||
if (read_result.Failed() || *read_result != sizeof(Header))
|
if (read_result.Failed() || *read_result != sizeof(Header))
|
||||||
return Loader::ResultStatus::Error;
|
return Loader::ResultStatus::Error;
|
||||||
|
|
||||||
|
@ -114,7 +114,8 @@ Loader::ResultStatus CIAContainer::Load(const std::vector<u8>& file_data) {
|
||||||
return Loader::ResultStatus::Success;
|
return Loader::ResultStatus::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader::ResultStatus CIAContainer::LoadHeader(const std::vector<u8>& header_data, size_t offset) {
|
Loader::ResultStatus CIAContainer::LoadHeader(const std::vector<u8>& header_data,
|
||||||
|
std::size_t offset) {
|
||||||
if (header_data.size() - offset < sizeof(Header))
|
if (header_data.size() - offset < sizeof(Header))
|
||||||
return Loader::ResultStatus::Error;
|
return Loader::ResultStatus::Error;
|
||||||
|
|
||||||
|
@ -124,11 +125,12 @@ Loader::ResultStatus CIAContainer::LoadHeader(const std::vector<u8>& header_data
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader::ResultStatus CIAContainer::LoadTitleMetadata(const std::vector<u8>& tmd_data,
|
Loader::ResultStatus CIAContainer::LoadTitleMetadata(const std::vector<u8>& tmd_data,
|
||||||
size_t offset) {
|
std::size_t offset) {
|
||||||
return cia_tmd.Load(tmd_data, offset);
|
return cia_tmd.Load(tmd_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader::ResultStatus CIAContainer::LoadMetadata(const std::vector<u8>& meta_data, size_t offset) {
|
Loader::ResultStatus CIAContainer::LoadMetadata(const std::vector<u8>& meta_data,
|
||||||
|
std::size_t offset) {
|
||||||
if (meta_data.size() - offset < sizeof(Metadata))
|
if (meta_data.size() - offset < sizeof(Metadata))
|
||||||
return Loader::ResultStatus::Error;
|
return Loader::ResultStatus::Error;
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,11 @@ namespace FileSys {
|
||||||
|
|
||||||
class FileBackend;
|
class FileBackend;
|
||||||
|
|
||||||
constexpr size_t CIA_CONTENT_MAX_COUNT = 0x10000;
|
constexpr std::size_t CIA_CONTENT_MAX_COUNT = 0x10000;
|
||||||
constexpr size_t CIA_CONTENT_BITS_SIZE = (CIA_CONTENT_MAX_COUNT / 8);
|
constexpr std::size_t CIA_CONTENT_BITS_SIZE = (CIA_CONTENT_MAX_COUNT / 8);
|
||||||
constexpr size_t CIA_HEADER_SIZE = 0x2020;
|
constexpr std::size_t CIA_HEADER_SIZE = 0x2020;
|
||||||
constexpr size_t CIA_DEPENDENCY_SIZE = 0x300;
|
constexpr std::size_t CIA_DEPENDENCY_SIZE = 0x300;
|
||||||
constexpr size_t CIA_METADATA_SIZE = 0x400;
|
constexpr std::size_t CIA_METADATA_SIZE = 0x400;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper which implements an interface to read and write CTR Installable Archive (CIA) files.
|
* Helper which implements an interface to read and write CTR Installable Archive (CIA) files.
|
||||||
|
@ -43,9 +43,9 @@ public:
|
||||||
Loader::ResultStatus Load(const std::vector<u8>& header_data);
|
Loader::ResultStatus Load(const std::vector<u8>& header_data);
|
||||||
|
|
||||||
// Load parts of CIAs (for CIAs streamed in)
|
// Load parts of CIAs (for CIAs streamed in)
|
||||||
Loader::ResultStatus LoadHeader(const std::vector<u8>& header_data, size_t offset = 0);
|
Loader::ResultStatus LoadHeader(const std::vector<u8>& header_data, std::size_t offset = 0);
|
||||||
Loader::ResultStatus LoadTitleMetadata(const std::vector<u8>& tmd_data, size_t offset = 0);
|
Loader::ResultStatus LoadTitleMetadata(const std::vector<u8>& tmd_data, std::size_t offset = 0);
|
||||||
Loader::ResultStatus LoadMetadata(const std::vector<u8>& meta_data, size_t offset = 0);
|
Loader::ResultStatus LoadMetadata(const std::vector<u8>& meta_data, std::size_t offset = 0);
|
||||||
|
|
||||||
const TitleMetadata& GetTitleMetadata() const;
|
const TitleMetadata& GetTitleMetadata() const;
|
||||||
std::array<u64, 0x30>& GetDependencies();
|
std::array<u64, 0x30>& GetDependencies();
|
||||||
|
|
|
@ -8,14 +8,14 @@ namespace FileSys {
|
||||||
|
|
||||||
class DelayGenerator {
|
class DelayGenerator {
|
||||||
public:
|
public:
|
||||||
virtual u64 GetReadDelayNs(size_t length) = 0;
|
virtual u64 GetReadDelayNs(std::size_t length) = 0;
|
||||||
|
|
||||||
// TODO (B3N30): Add getter for all other file/directory io operations
|
// TODO (B3N30): Add getter for all other file/directory io operations
|
||||||
};
|
};
|
||||||
|
|
||||||
class DefaultDelayGenerator : public DelayGenerator {
|
class DefaultDelayGenerator : public DelayGenerator {
|
||||||
public:
|
public:
|
||||||
u64 GetReadDelayNs(size_t length) override {
|
u64 GetReadDelayNs(std::size_t length) override {
|
||||||
// This is the delay measured for a romfs read.
|
// This is the delay measured for a romfs read.
|
||||||
// For now we will take that as a default
|
// For now we will take that as a default
|
||||||
static constexpr u64 slope(94);
|
static constexpr u64 slope(94);
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
// Structure of a directory entry, from http://3dbrew.org/wiki/FSDir:Read#Entry_format
|
// Structure of a directory entry, from http://3dbrew.org/wiki/FSDir:Read#Entry_format
|
||||||
const size_t FILENAME_LENGTH = 0x20C / 2;
|
const std::size_t FILENAME_LENGTH = 0x20C / 2;
|
||||||
struct Entry {
|
struct Entry {
|
||||||
char16_t filename[FILENAME_LENGTH]; // Entry name (UTF-16, null-terminated)
|
char16_t filename[FILENAME_LENGTH]; // Entry name (UTF-16, null-terminated)
|
||||||
std::array<char, 9> short_name; // 8.3 file name ('longfilename' -> 'LONGFI~1', null-terminated)
|
std::array<char, 9> short_name; // 8.3 file name ('longfilename' -> 'LONGFI~1', null-terminated)
|
||||||
|
|
|
@ -16,24 +16,25 @@
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
ResultVal<size_t> DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const {
|
ResultVal<std::size_t> DiskFile::Read(const u64 offset, const std::size_t length,
|
||||||
|
u8* buffer) const {
|
||||||
if (!mode.read_flag)
|
if (!mode.read_flag)
|
||||||
return ERROR_INVALID_OPEN_FLAGS;
|
return ERROR_INVALID_OPEN_FLAGS;
|
||||||
|
|
||||||
file->Seek(offset, SEEK_SET);
|
file->Seek(offset, SEEK_SET);
|
||||||
return MakeResult<size_t>(file->ReadBytes(buffer, length));
|
return MakeResult<std::size_t>(file->ReadBytes(buffer, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> DiskFile::Write(const u64 offset, const size_t length, const bool flush,
|
ResultVal<std::size_t> DiskFile::Write(const u64 offset, const std::size_t length, const bool flush,
|
||||||
const u8* buffer) {
|
const u8* buffer) {
|
||||||
if (!mode.write_flag)
|
if (!mode.write_flag)
|
||||||
return ERROR_INVALID_OPEN_FLAGS;
|
return ERROR_INVALID_OPEN_FLAGS;
|
||||||
|
|
||||||
file->Seek(offset, SEEK_SET);
|
file->Seek(offset, SEEK_SET);
|
||||||
size_t written = file->WriteBytes(buffer, length);
|
std::size_t written = file->WriteBytes(buffer, length);
|
||||||
if (flush)
|
if (flush)
|
||||||
file->Flush();
|
file->Flush();
|
||||||
return MakeResult<size_t>(written);
|
return MakeResult<std::size_t>(written);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 DiskFile::GetSize() const {
|
u64 DiskFile::GetSize() const {
|
||||||
|
@ -70,7 +71,7 @@ u32 DiskDirectory::Read(const u32 count, Entry* entries) {
|
||||||
LOG_TRACE(Service_FS, "File {}: size={} dir={}", filename, file.size, file.isDirectory);
|
LOG_TRACE(Service_FS, "File {}: size={} dir={}", filename, file.size, file.isDirectory);
|
||||||
|
|
||||||
// TODO(Link Mauve): use a proper conversion to UTF-16.
|
// TODO(Link Mauve): use a proper conversion to UTF-16.
|
||||||
for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
|
for (std::size_t j = 0; j < FILENAME_LENGTH; ++j) {
|
||||||
entry.filename[j] = filename[j];
|
entry.filename[j] = filename[j];
|
||||||
if (!filename[j])
|
if (!filename[j])
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -29,8 +29,9 @@ public:
|
||||||
mode.hex = mode_.hex;
|
mode.hex = mode_.hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
|
ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const override;
|
||||||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) override;
|
ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
|
||||||
|
const u8* buffer) override;
|
||||||
u64 GetSize() const override;
|
u64 GetSize() const override;
|
||||||
bool SetSize(u64 size) const override;
|
bool SetSize(u64 size) const override;
|
||||||
bool Close() const override;
|
bool Close() const override;
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
* @param buffer Buffer to read data into
|
* @param buffer Buffer to read data into
|
||||||
* @return Number of bytes read, or error code
|
* @return Number of bytes read, or error code
|
||||||
*/
|
*/
|
||||||
virtual ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const = 0;
|
virtual ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write data to the file
|
* Write data to the file
|
||||||
|
@ -38,14 +38,15 @@ public:
|
||||||
* @param buffer Buffer to read data from
|
* @param buffer Buffer to read data from
|
||||||
* @return Number of bytes written, or error code
|
* @return Number of bytes written, or error code
|
||||||
*/
|
*/
|
||||||
virtual ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) = 0;
|
virtual ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
|
||||||
|
const u8* buffer) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the amount of time a 3ds needs to read those data
|
* Get the amount of time a 3ds needs to read those data
|
||||||
* @param length Length in bytes of data read from file
|
* @param length Length in bytes of data read from file
|
||||||
* @return Nanoseconds for the delay
|
* @return Nanoseconds for the delay
|
||||||
*/
|
*/
|
||||||
u64 GetReadDelayNs(size_t length) {
|
u64 GetReadDelayNs(std::size_t length) {
|
||||||
if (delay_generator != nullptr) {
|
if (delay_generator != nullptr) {
|
||||||
return delay_generator->GetReadDelayNs(length);
|
return delay_generator->GetReadDelayNs(length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,16 +90,17 @@ IVFCFile::IVFCFile(std::shared_ptr<RomFSReader> file,
|
||||||
delay_generator = std::move(delay_generator_);
|
delay_generator = std::move(delay_generator_);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> IVFCFile::Read(const u64 offset, const size_t length, u8* buffer) const {
|
ResultVal<std::size_t> IVFCFile::Read(const u64 offset, const std::size_t length,
|
||||||
|
u8* buffer) const {
|
||||||
LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
||||||
return MakeResult<size_t>(romfs_file->ReadFile(offset, length, buffer));
|
return MakeResult<std::size_t>(romfs_file->ReadFile(offset, length, buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> IVFCFile::Write(const u64 offset, const size_t length, const bool flush,
|
ResultVal<std::size_t> IVFCFile::Write(const u64 offset, const std::size_t length, const bool flush,
|
||||||
const u8* buffer) {
|
const u8* buffer) {
|
||||||
LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
|
LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
|
||||||
// TODO(Subv): Find error code
|
// TODO(Subv): Find error code
|
||||||
return MakeResult<size_t>(0);
|
return MakeResult<std::size_t>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 IVFCFile::GetSize() const {
|
u64 IVFCFile::GetSize() const {
|
||||||
|
@ -119,19 +120,20 @@ IVFCFileInMemory::IVFCFileInMemory(std::vector<u8> bytes, u64 offset, u64 size,
|
||||||
delay_generator = std::move(delay_generator_);
|
delay_generator = std::move(delay_generator_);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> IVFCFileInMemory::Read(const u64 offset, const size_t length, u8* buffer) const {
|
ResultVal<std::size_t> IVFCFileInMemory::Read(const u64 offset, const std::size_t length,
|
||||||
|
u8* buffer) const {
|
||||||
LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
||||||
size_t read_length = (size_t)std::min((u64)length, data_size - offset);
|
std::size_t read_length = (std::size_t)std::min((u64)length, data_size - offset);
|
||||||
|
|
||||||
std::memcpy(buffer, romfs_file.data() + data_offset + offset, read_length);
|
std::memcpy(buffer, romfs_file.data() + data_offset + offset, read_length);
|
||||||
return MakeResult<size_t>(read_length);
|
return MakeResult<std::size_t>(read_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> IVFCFileInMemory::Write(const u64 offset, const size_t length, const bool flush,
|
ResultVal<std::size_t> IVFCFileInMemory::Write(const u64 offset, const std::size_t length,
|
||||||
const u8* buffer) {
|
const bool flush, const u8* buffer) {
|
||||||
LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
|
LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
|
||||||
// TODO(Subv): Find error code
|
// TODO(Subv): Find error code
|
||||||
return MakeResult<size_t>(0);
|
return MakeResult<std::size_t>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 IVFCFileInMemory::GetSize() const {
|
u64 IVFCFileInMemory::GetSize() const {
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
|
||||||
class IVFCDelayGenerator : public DelayGenerator {
|
class IVFCDelayGenerator : public DelayGenerator {
|
||||||
u64 GetReadDelayNs(size_t length) override {
|
u64 GetReadDelayNs(std::size_t length) override {
|
||||||
// This is the delay measured for a romfs read.
|
// This is the delay measured for a romfs read.
|
||||||
// For now we will take that as a default
|
// For now we will take that as a default
|
||||||
static constexpr u64 slope(94);
|
static constexpr u64 slope(94);
|
||||||
|
@ -35,7 +35,7 @@ class IVFCDelayGenerator : public DelayGenerator {
|
||||||
|
|
||||||
class RomFSDelayGenerator : public DelayGenerator {
|
class RomFSDelayGenerator : public DelayGenerator {
|
||||||
public:
|
public:
|
||||||
u64 GetReadDelayNs(size_t length) override {
|
u64 GetReadDelayNs(std::size_t length) override {
|
||||||
// The delay was measured on O3DS and O2DS with
|
// The delay was measured on O3DS and O2DS with
|
||||||
// https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
|
// https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
|
||||||
// from the results the average of each length was taken.
|
// from the results the average of each length was taken.
|
||||||
|
@ -49,7 +49,7 @@ public:
|
||||||
|
|
||||||
class ExeFSDelayGenerator : public DelayGenerator {
|
class ExeFSDelayGenerator : public DelayGenerator {
|
||||||
public:
|
public:
|
||||||
u64 GetReadDelayNs(size_t length) override {
|
u64 GetReadDelayNs(std::size_t length) override {
|
||||||
// The delay was measured on O3DS and O2DS with
|
// The delay was measured on O3DS and O2DS with
|
||||||
// https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
|
// https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
|
||||||
// from the results the average of each length was taken.
|
// from the results the average of each length was taken.
|
||||||
|
@ -92,8 +92,9 @@ class IVFCFile : public FileBackend {
|
||||||
public:
|
public:
|
||||||
IVFCFile(std::shared_ptr<RomFSReader> file, std::unique_ptr<DelayGenerator> delay_generator_);
|
IVFCFile(std::shared_ptr<RomFSReader> file, std::unique_ptr<DelayGenerator> delay_generator_);
|
||||||
|
|
||||||
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
|
ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const override;
|
||||||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) override;
|
ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
|
||||||
|
const u8* buffer) override;
|
||||||
u64 GetSize() const override;
|
u64 GetSize() const override;
|
||||||
bool SetSize(u64 size) const override;
|
bool SetSize(u64 size) const override;
|
||||||
bool Close() const override {
|
bool Close() const override {
|
||||||
|
@ -120,8 +121,9 @@ public:
|
||||||
IVFCFileInMemory(std::vector<u8> bytes, u64 offset, u64 size,
|
IVFCFileInMemory(std::vector<u8> bytes, u64 offset, u64 size,
|
||||||
std::unique_ptr<DelayGenerator> delay_generator_);
|
std::unique_ptr<DelayGenerator> delay_generator_);
|
||||||
|
|
||||||
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
|
ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const override;
|
||||||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) override;
|
ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
|
||||||
|
const u8* buffer) override;
|
||||||
u64 GetSize() const override;
|
u64 GetSize() const override;
|
||||||
bool SetSize(u64 size) const override;
|
bool SetSize(u64 size) const override;
|
||||||
bool Close() const override {
|
bool Close() const override {
|
||||||
|
|
|
@ -394,8 +394,8 @@ Loader::ResultStatus NCCHContainer::LoadSectionExeFS(const char* name, std::vect
|
||||||
// instead of the ExeFS.
|
// instead of the ExeFS.
|
||||||
if (std::strcmp(name, "logo") == 0) {
|
if (std::strcmp(name, "logo") == 0) {
|
||||||
if (ncch_header.logo_region_offset && ncch_header.logo_region_size) {
|
if (ncch_header.logo_region_offset && ncch_header.logo_region_size) {
|
||||||
size_t logo_offset = ncch_header.logo_region_offset * kBlockSize;
|
std::size_t logo_offset = ncch_header.logo_region_offset * kBlockSize;
|
||||||
size_t logo_size = ncch_header.logo_region_size * kBlockSize;
|
std::size_t logo_size = ncch_header.logo_region_size * kBlockSize;
|
||||||
|
|
||||||
buffer.resize(logo_size);
|
buffer.resize(logo_size);
|
||||||
file.Seek(ncch_offset + logo_offset, SEEK_SET);
|
file.Seek(ncch_offset + logo_offset, SEEK_SET);
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace FileSys {
|
||||||
|
|
||||||
class SaveDataDelayGenerator : public DelayGenerator {
|
class SaveDataDelayGenerator : public DelayGenerator {
|
||||||
public:
|
public:
|
||||||
u64 GetReadDelayNs(size_t length) override {
|
u64 GetReadDelayNs(std::size_t length) override {
|
||||||
// The delay was measured on O3DS and O2DS with
|
// The delay was measured on O3DS and O2DS with
|
||||||
// https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
|
// https://gist.github.com/B3n30/ac40eac20603f519ff106107f4ac9182
|
||||||
// from the results the average of each length was taken.
|
// from the results the average of each length was taken.
|
||||||
|
|
|
@ -50,8 +50,8 @@ Loader::ResultStatus TitleMetadata::Load(const std::string& file_path) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader::ResultStatus TitleMetadata::Load(const std::vector<u8> file_data, size_t offset) {
|
Loader::ResultStatus TitleMetadata::Load(const std::vector<u8> file_data, std::size_t offset) {
|
||||||
size_t total_size = static_cast<size_t>(file_data.size() - offset);
|
std::size_t total_size = static_cast<std::size_t>(file_data.size() - offset);
|
||||||
if (total_size < sizeof(u32_be))
|
if (total_size < sizeof(u32_be))
|
||||||
return Loader::ResultStatus::Error;
|
return Loader::ResultStatus::Error;
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ Loader::ResultStatus TitleMetadata::Load(const std::vector<u8> file_data, size_t
|
||||||
u32 signature_size = GetSignatureSize(signature_type);
|
u32 signature_size = GetSignatureSize(signature_type);
|
||||||
|
|
||||||
// The TMD body start position is rounded to the nearest 0x40 after the signature
|
// The TMD body start position is rounded to the nearest 0x40 after the signature
|
||||||
size_t body_start = Common::AlignUp(signature_size + sizeof(u32), 0x40);
|
std::size_t body_start = Common::AlignUp(signature_size + sizeof(u32), 0x40);
|
||||||
size_t body_end = body_start + sizeof(Body);
|
std::size_t body_end = body_start + sizeof(Body);
|
||||||
|
|
||||||
if (total_size < body_end)
|
if (total_size < body_end)
|
||||||
return Loader::ResultStatus::Error;
|
return Loader::ResultStatus::Error;
|
||||||
|
@ -72,7 +72,7 @@ Loader::ResultStatus TitleMetadata::Load(const std::vector<u8> file_data, size_t
|
||||||
memcpy(tmd_signature.data(), &file_data[offset + sizeof(u32_be)], signature_size);
|
memcpy(tmd_signature.data(), &file_data[offset + sizeof(u32_be)], signature_size);
|
||||||
memcpy(&tmd_body, &file_data[offset + body_start], sizeof(TitleMetadata::Body));
|
memcpy(&tmd_body, &file_data[offset + body_start], sizeof(TitleMetadata::Body));
|
||||||
|
|
||||||
size_t expected_size =
|
std::size_t expected_size =
|
||||||
body_start + sizeof(Body) + static_cast<u16>(tmd_body.content_count) * sizeof(ContentChunk);
|
body_start + sizeof(Body) + static_cast<u16>(tmd_body.content_count) * sizeof(ContentChunk);
|
||||||
if (total_size < expected_size) {
|
if (total_size < expected_size) {
|
||||||
LOG_ERROR(Service_FS, "Malformed TMD, expected size 0x{:x}, got 0x{:x}!", expected_size,
|
LOG_ERROR(Service_FS, "Malformed TMD, expected size 0x{:x}, got 0x{:x}!", expected_size,
|
||||||
|
@ -106,7 +106,7 @@ Loader::ResultStatus TitleMetadata::Save(const std::string& file_path) {
|
||||||
return Loader::ResultStatus::Error;
|
return Loader::ResultStatus::Error;
|
||||||
|
|
||||||
// The TMD body start position is rounded to the nearest 0x40 after the signature
|
// The TMD body start position is rounded to the nearest 0x40 after the signature
|
||||||
size_t body_start = Common::AlignUp(signature_size + sizeof(u32), 0x40);
|
std::size_t body_start = Common::AlignUp(signature_size + sizeof(u32), 0x40);
|
||||||
file.Seek(body_start, SEEK_SET);
|
file.Seek(body_start, SEEK_SET);
|
||||||
|
|
||||||
// Update our TMD body values and hashes
|
// Update our TMD body values and hashes
|
||||||
|
@ -126,7 +126,7 @@ Loader::ResultStatus TitleMetadata::Save(const std::string& file_path) {
|
||||||
chunk_hash.Final(tmd_body.contentinfo[0].hash.data());
|
chunk_hash.Final(tmd_body.contentinfo[0].hash.data());
|
||||||
|
|
||||||
CryptoPP::SHA256 contentinfo_hash;
|
CryptoPP::SHA256 contentinfo_hash;
|
||||||
for (size_t i = 0; i < tmd_body.contentinfo.size(); i++) {
|
for (std::size_t i = 0; i < tmd_body.contentinfo.size(); i++) {
|
||||||
chunk_hash.Update(reinterpret_cast<u8*>(&tmd_body.contentinfo[i]), sizeof(ContentInfo));
|
chunk_hash.Update(reinterpret_cast<u8*>(&tmd_body.contentinfo[i]), sizeof(ContentInfo));
|
||||||
}
|
}
|
||||||
chunk_hash.Final(tmd_body.contentinfo_hash.data());
|
chunk_hash.Final(tmd_body.contentinfo_hash.data());
|
||||||
|
@ -213,7 +213,7 @@ void TitleMetadata::Print() const {
|
||||||
|
|
||||||
// Content info describes ranges of content chunks
|
// Content info describes ranges of content chunks
|
||||||
LOG_DEBUG(Service_FS, "Content info:");
|
LOG_DEBUG(Service_FS, "Content info:");
|
||||||
for (size_t i = 0; i < tmd_body.contentinfo.size(); i++) {
|
for (std::size_t i = 0; i < tmd_body.contentinfo.size(); i++) {
|
||||||
if (tmd_body.contentinfo[i].command_count == 0)
|
if (tmd_body.contentinfo[i].command_count == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ void TitleMetadata::Print() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each content info, print their content chunk range
|
// For each content info, print their content chunk range
|
||||||
for (size_t i = 0; i < tmd_body.contentinfo.size(); i++) {
|
for (std::size_t i = 0; i < tmd_body.contentinfo.size(); i++) {
|
||||||
u16 index = static_cast<u16>(tmd_body.contentinfo[i].index);
|
u16 index = static_cast<u16>(tmd_body.contentinfo[i].index);
|
||||||
u16 count = static_cast<u16>(tmd_body.contentinfo[i].command_count);
|
u16 count = static_cast<u16>(tmd_body.contentinfo[i].command_count);
|
||||||
|
|
||||||
|
|
|
@ -94,14 +94,14 @@ public:
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
Loader::ResultStatus Load(const std::string& file_path);
|
Loader::ResultStatus Load(const std::string& file_path);
|
||||||
Loader::ResultStatus Load(const std::vector<u8> file_data, size_t offset = 0);
|
Loader::ResultStatus Load(const std::vector<u8> file_data, std::size_t offset = 0);
|
||||||
Loader::ResultStatus Save(const std::string& file_path);
|
Loader::ResultStatus Save(const std::string& file_path);
|
||||||
|
|
||||||
u64 GetTitleID() const;
|
u64 GetTitleID() const;
|
||||||
u32 GetTitleType() const;
|
u32 GetTitleType() const;
|
||||||
u16 GetTitleVersion() const;
|
u16 GetTitleVersion() const;
|
||||||
u64 GetSystemVersion() const;
|
u64 GetSystemVersion() const;
|
||||||
size_t GetContentCount() const;
|
std::size_t GetContentCount() const;
|
||||||
u32 GetBootContentID() const;
|
u32 GetBootContentID() const;
|
||||||
u32 GetManualContentID() const;
|
u32 GetManualContentID() const;
|
||||||
u32 GetDLPContentID() const;
|
u32 GetDLPContentID() const;
|
||||||
|
|
|
@ -262,7 +262,7 @@ static u8 NibbleToHex(u8 n) {
|
||||||
* @param src Pointer to array of output hex string characters.
|
* @param src Pointer to array of output hex string characters.
|
||||||
* @param len Length of src array.
|
* @param len Length of src array.
|
||||||
*/
|
*/
|
||||||
static u32 HexToInt(const u8* src, size_t len) {
|
static u32 HexToInt(const u8* src, std::size_t len) {
|
||||||
u32 output = 0;
|
u32 output = 0;
|
||||||
while (len-- > 0) {
|
while (len-- > 0) {
|
||||||
output = (output << 4) | HexCharToValue(src[0]);
|
output = (output << 4) | HexCharToValue(src[0]);
|
||||||
|
@ -278,7 +278,7 @@ static u32 HexToInt(const u8* src, size_t len) {
|
||||||
* @param src Pointer to array of u8 bytes.
|
* @param src Pointer to array of u8 bytes.
|
||||||
* @param len Length of src array.
|
* @param len Length of src array.
|
||||||
*/
|
*/
|
||||||
static void MemToGdbHex(u8* dest, const u8* src, size_t len) {
|
static void MemToGdbHex(u8* dest, const u8* src, std::size_t len) {
|
||||||
while (len-- > 0) {
|
while (len-- > 0) {
|
||||||
u8 tmp = *src++;
|
u8 tmp = *src++;
|
||||||
*dest++ = NibbleToHex(tmp >> 4);
|
*dest++ = NibbleToHex(tmp >> 4);
|
||||||
|
@ -293,7 +293,7 @@ static void MemToGdbHex(u8* dest, const u8* src, size_t len) {
|
||||||
* @param src Pointer to array of output hex string characters.
|
* @param src Pointer to array of output hex string characters.
|
||||||
* @param len Length of src array.
|
* @param len Length of src array.
|
||||||
*/
|
*/
|
||||||
static void GdbHexToMem(u8* dest, const u8* src, size_t len) {
|
static void GdbHexToMem(u8* dest, const u8* src, std::size_t len) {
|
||||||
while (len-- > 0) {
|
while (len-- > 0) {
|
||||||
*dest++ = (HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]);
|
*dest++ = (HexCharToValue(src[0]) << 4) | HexCharToValue(src[1]);
|
||||||
src += 2;
|
src += 2;
|
||||||
|
@ -361,7 +361,7 @@ static u64 GdbHexToLong(const u8* src) {
|
||||||
/// Read a byte from the gdb client.
|
/// Read a byte from the gdb client.
|
||||||
static u8 ReadByte() {
|
static u8 ReadByte() {
|
||||||
u8 c;
|
u8 c;
|
||||||
size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL);
|
std::size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL);
|
||||||
if (received_size != 1) {
|
if (received_size != 1) {
|
||||||
LOG_ERROR(Debug_GDBStub, "recv failed : {}", received_size);
|
LOG_ERROR(Debug_GDBStub, "recv failed : {}", received_size);
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
@ -371,7 +371,7 @@ static u8 ReadByte() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the checksum of the current command buffer.
|
/// Calculate the checksum of the current command buffer.
|
||||||
static u8 CalculateChecksum(const u8* buffer, size_t length) {
|
static u8 CalculateChecksum(const u8* buffer, std::size_t length) {
|
||||||
return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>()));
|
return static_cast<u8>(std::accumulate(buffer, buffer + length, 0, std::plus<u8>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ bool CheckBreakpoint(VAddr addr, BreakpointType type) {
|
||||||
* @param packet Packet to be sent to client.
|
* @param packet Packet to be sent to client.
|
||||||
*/
|
*/
|
||||||
static void SendPacket(const char packet) {
|
static void SendPacket(const char packet) {
|
||||||
size_t sent_size = send(gdbserver_socket, &packet, 1, 0);
|
std::size_t sent_size = send(gdbserver_socket, &packet, 1, 0);
|
||||||
if (sent_size != 1) {
|
if (sent_size != 1) {
|
||||||
LOG_ERROR(Debug_GDBStub, "send failed");
|
LOG_ERROR(Debug_GDBStub, "send failed");
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ Frontend::KeyboardConfig SoftwareKeyboard::ToFrontendConfig(
|
||||||
frontend_config.max_text_length = config.max_text_length;
|
frontend_config.max_text_length = config.max_text_length;
|
||||||
frontend_config.max_digits = config.max_digits;
|
frontend_config.max_digits = config.max_digits;
|
||||||
|
|
||||||
size_t text_size = config.hint_text.size();
|
std::size_t text_size = config.hint_text.size();
|
||||||
const auto text_end = std::find(config.hint_text.begin(), config.hint_text.end(), u'\0');
|
const auto text_end = std::find(config.hint_text.begin(), config.hint_text.end(), u'\0');
|
||||||
if (text_end != config.hint_text.end())
|
if (text_end != config.hint_text.end())
|
||||||
text_size = std::distance(config.hint_text.begin(), text_end);
|
text_size = std::distance(config.hint_text.begin(), text_end);
|
||||||
|
|
|
@ -33,10 +33,10 @@ inline u32* GetCommandBuffer(const int offset = 0) {
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
|
||||||
/// Size of the command buffer area, in 32-bit words.
|
/// Size of the command buffer area, in 32-bit words.
|
||||||
constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32);
|
constexpr std::size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32);
|
||||||
|
|
||||||
// Maximum number of static buffers per thread.
|
// Maximum number of static buffers per thread.
|
||||||
constexpr size_t MAX_STATIC_BUFFERS = 16;
|
constexpr std::size_t MAX_STATIC_BUFFERS = 16;
|
||||||
|
|
||||||
// These errors are commonly returned by invalid IPC translations, so alias them here for
|
// These errors are commonly returned by invalid IPC translations, so alias them here for
|
||||||
// convenience.
|
// convenience.
|
||||||
|
@ -113,7 +113,7 @@ union StaticBufferDescInfo {
|
||||||
BitField<14, 18, u32> size;
|
BitField<14, 18, u32> size;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline u32 StaticBufferDesc(size_t size, u8 buffer_id) {
|
inline u32 StaticBufferDesc(std::size_t size, u8 buffer_id) {
|
||||||
StaticBufferDescInfo info{};
|
StaticBufferDescInfo info{};
|
||||||
info.descriptor_type.Assign(StaticBuffer);
|
info.descriptor_type.Assign(StaticBuffer);
|
||||||
info.buffer_id.Assign(buffer_id);
|
info.buffer_id.Assign(buffer_id);
|
||||||
|
@ -151,7 +151,7 @@ union MappedBufferDescInfo {
|
||||||
BitField<4, 28, u32> size;
|
BitField<4, 28, u32> size;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline u32 MappedBufferDesc(size_t size, MappedBufferPermissions perms) {
|
inline u32 MappedBufferDesc(std::size_t size, MappedBufferPermissions perms) {
|
||||||
MappedBufferDescInfo info{};
|
MappedBufferDescInfo info{};
|
||||||
info.flags.Assign(MappedBuffer);
|
info.flags.Assign(MappedBuffer);
|
||||||
info.perms.Assign(perms);
|
info.perms.Assign(perms);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
: context(&context), cmdbuf(context.CommandBuffer()), header(desired_header) {}
|
: context(&context), cmdbuf(context.CommandBuffer()), header(desired_header) {}
|
||||||
|
|
||||||
/// Returns the total size of the request in words
|
/// Returns the total size of the request in words
|
||||||
size_t TotalSize() const {
|
std::size_t TotalSize() const {
|
||||||
return 1 /* command header */ + header.normal_params_size + header.translate_params_size;
|
return 1 /* command header */ + header.normal_params_size + header.translate_params_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ inline std::array<Kernel::SharedPtr<Kernel::Object>, N> RequestParser::PopGeneri
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <typename... T, size_t... I>
|
template <typename... T, std::size_t... I>
|
||||||
std::tuple<Kernel::SharedPtr<T>...> PopObjectsHelper(
|
std::tuple<Kernel::SharedPtr<T>...> PopObjectsHelper(
|
||||||
std::array<Kernel::SharedPtr<Kernel::Object>, sizeof...(T)>&& pointers,
|
std::array<Kernel::SharedPtr<Kernel::Object>, sizeof...(T)>&& pointers,
|
||||||
std::index_sequence<I...>) {
|
std::index_sequence<I...>) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ ResultCode HandleTable::Close(Handle handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HandleTable::IsValid(Handle handle) const {
|
bool HandleTable::IsValid(Handle handle) const {
|
||||||
size_t slot = GetSlot(handle);
|
std::size_t slot = GetSlot(handle);
|
||||||
u16 generation = GetGeneration(handle);
|
u16 generation = GetGeneration(handle);
|
||||||
|
|
||||||
return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation;
|
return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation;
|
||||||
|
|
|
@ -93,7 +93,7 @@ private:
|
||||||
* This is the maximum limit of handles allowed per process in CTR-OS. It can be further
|
* This is the maximum limit of handles allowed per process in CTR-OS. It can be further
|
||||||
* reduced by ExHeader values, but this is not emulated here.
|
* reduced by ExHeader values, but this is not emulated here.
|
||||||
*/
|
*/
|
||||||
static const size_t MAX_COUNT = 4096;
|
static const std::size_t MAX_COUNT = 4096;
|
||||||
|
|
||||||
static u16 GetSlot(Handle handle) {
|
static u16 GetSlot(Handle handle) {
|
||||||
return handle >> 15;
|
return handle >> 15;
|
||||||
|
|
|
@ -100,13 +100,13 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr
|
||||||
HandleTable& src_table) {
|
HandleTable& src_table) {
|
||||||
IPC::Header header{src_cmdbuf[0]};
|
IPC::Header header{src_cmdbuf[0]};
|
||||||
|
|
||||||
size_t untranslated_size = 1u + header.normal_params_size;
|
std::size_t untranslated_size = 1u + header.normal_params_size;
|
||||||
size_t command_size = untranslated_size + header.translate_params_size;
|
std::size_t command_size = untranslated_size + header.translate_params_size;
|
||||||
ASSERT(command_size <= IPC::COMMAND_BUFFER_LENGTH); // TODO(yuriks): Return error
|
ASSERT(command_size <= IPC::COMMAND_BUFFER_LENGTH); // TODO(yuriks): Return error
|
||||||
|
|
||||||
std::copy_n(src_cmdbuf, untranslated_size, cmd_buf.begin());
|
std::copy_n(src_cmdbuf, untranslated_size, cmd_buf.begin());
|
||||||
|
|
||||||
size_t i = untranslated_size;
|
std::size_t i = untranslated_size;
|
||||||
while (i < command_size) {
|
while (i < command_size) {
|
||||||
u32 descriptor = cmd_buf[i] = src_cmdbuf[i];
|
u32 descriptor = cmd_buf[i] = src_cmdbuf[i];
|
||||||
i += 1;
|
i += 1;
|
||||||
|
@ -165,13 +165,13 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
|
||||||
HandleTable& dst_table) const {
|
HandleTable& dst_table) const {
|
||||||
IPC::Header header{cmd_buf[0]};
|
IPC::Header header{cmd_buf[0]};
|
||||||
|
|
||||||
size_t untranslated_size = 1u + header.normal_params_size;
|
std::size_t untranslated_size = 1u + header.normal_params_size;
|
||||||
size_t command_size = untranslated_size + header.translate_params_size;
|
std::size_t command_size = untranslated_size + header.translate_params_size;
|
||||||
ASSERT(command_size <= IPC::COMMAND_BUFFER_LENGTH);
|
ASSERT(command_size <= IPC::COMMAND_BUFFER_LENGTH);
|
||||||
|
|
||||||
std::copy_n(cmd_buf.begin(), untranslated_size, dst_cmdbuf);
|
std::copy_n(cmd_buf.begin(), untranslated_size, dst_cmdbuf);
|
||||||
|
|
||||||
size_t i = untranslated_size;
|
std::size_t i = untranslated_size;
|
||||||
while (i < command_size) {
|
while (i < command_size) {
|
||||||
u32 descriptor = dst_cmdbuf[i] = cmd_buf[i];
|
u32 descriptor = dst_cmdbuf[i] = cmd_buf[i];
|
||||||
i += 1;
|
i += 1;
|
||||||
|
@ -201,7 +201,8 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
|
||||||
// Grab the address that the target thread set up to receive the response static buffer
|
// Grab the address that the target thread set up to receive the response static buffer
|
||||||
// and write our data there. The static buffers area is located right after the command
|
// and write our data there. The static buffers area is located right after the command
|
||||||
// buffer area.
|
// buffer area.
|
||||||
size_t static_buffer_offset = IPC::COMMAND_BUFFER_LENGTH + 2 * buffer_info.buffer_id;
|
std::size_t static_buffer_offset =
|
||||||
|
IPC::COMMAND_BUFFER_LENGTH + 2 * buffer_info.buffer_id;
|
||||||
IPC::StaticBufferDescInfo target_descriptor{dst_cmdbuf[static_buffer_offset]};
|
IPC::StaticBufferDescInfo target_descriptor{dst_cmdbuf[static_buffer_offset]};
|
||||||
VAddr target_address = dst_cmdbuf[static_buffer_offset + 1];
|
VAddr target_address = dst_cmdbuf[static_buffer_offset + 1];
|
||||||
|
|
||||||
|
@ -237,13 +238,13 @@ MappedBuffer::MappedBuffer(const Process& process, u32 descriptor, VAddr address
|
||||||
perms = desc.perms;
|
perms = desc.perms;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MappedBuffer::Read(void* dest_buffer, size_t offset, size_t size) {
|
void MappedBuffer::Read(void* dest_buffer, std::size_t offset, std::size_t size) {
|
||||||
ASSERT(perms & IPC::R);
|
ASSERT(perms & IPC::R);
|
||||||
ASSERT(offset + size <= this->size);
|
ASSERT(offset + size <= this->size);
|
||||||
Memory::ReadBlock(*process, address + static_cast<VAddr>(offset), dest_buffer, size);
|
Memory::ReadBlock(*process, address + static_cast<VAddr>(offset), dest_buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MappedBuffer::Write(const void* src_buffer, size_t offset, size_t size) {
|
void MappedBuffer::Write(const void* src_buffer, std::size_t offset, std::size_t size) {
|
||||||
ASSERT(perms & IPC::W);
|
ASSERT(perms & IPC::W);
|
||||||
ASSERT(offset + size <= this->size);
|
ASSERT(offset + size <= this->size);
|
||||||
Memory::WriteBlock(*process, address + static_cast<VAddr>(offset), src_buffer, size);
|
Memory::WriteBlock(*process, address + static_cast<VAddr>(offset), src_buffer, size);
|
||||||
|
|
|
@ -98,9 +98,9 @@ public:
|
||||||
MappedBuffer(const Process& process, u32 descriptor, VAddr address, u32 id);
|
MappedBuffer(const Process& process, u32 descriptor, VAddr address, u32 id);
|
||||||
|
|
||||||
// interface for service
|
// interface for service
|
||||||
void Read(void* dest_buffer, size_t offset, size_t size);
|
void Read(void* dest_buffer, std::size_t offset, std::size_t size);
|
||||||
void Write(const void* src_buffer, size_t offset, size_t size);
|
void Write(const void* src_buffer, std::size_t offset, std::size_t size);
|
||||||
size_t GetSize() const {
|
std::size_t GetSize() const {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ private:
|
||||||
u32 id;
|
u32 id;
|
||||||
VAddr address;
|
VAddr address;
|
||||||
const Process* process;
|
const Process* process;
|
||||||
size_t size;
|
std::size_t size;
|
||||||
IPC::MappedBufferPermissions perms;
|
IPC::MappedBufferPermissions perms;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
||||||
// TODO(Subv): Replace by Memory::Read32 when possible.
|
// TODO(Subv): Replace by Memory::Read32 when possible.
|
||||||
Memory::ReadBlock(*src_process, src_address, &header.raw, sizeof(header.raw));
|
Memory::ReadBlock(*src_process, src_address, &header.raw, sizeof(header.raw));
|
||||||
|
|
||||||
size_t untranslated_size = 1u + header.normal_params_size;
|
std::size_t untranslated_size = 1u + header.normal_params_size;
|
||||||
size_t command_size = untranslated_size + header.translate_params_size;
|
std::size_t command_size = untranslated_size + header.translate_params_size;
|
||||||
|
|
||||||
// Note: The real kernel does not check that the command length fits into the IPC buffer area.
|
// Note: The real kernel does not check that the command length fits into the IPC buffer area.
|
||||||
ASSERT(command_size <= IPC::COMMAND_BUFFER_LENGTH);
|
ASSERT(command_size <= IPC::COMMAND_BUFFER_LENGTH);
|
||||||
|
@ -33,7 +33,7 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
||||||
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
||||||
Memory::ReadBlock(*src_process, src_address, cmd_buf.data(), command_size * sizeof(u32));
|
Memory::ReadBlock(*src_process, src_address, cmd_buf.data(), command_size * sizeof(u32));
|
||||||
|
|
||||||
size_t i = untranslated_size;
|
std::size_t i = untranslated_size;
|
||||||
while (i < command_size) {
|
while (i < command_size) {
|
||||||
u32 descriptor = cmd_buf[i];
|
u32 descriptor = cmd_buf[i];
|
||||||
i += 1;
|
i += 1;
|
||||||
|
@ -178,11 +178,12 @@ ResultCode TranslateCommandBuffer(SharedPtr<Thread> src_thread, SharedPtr<Thread
|
||||||
auto buffer = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
|
auto buffer = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
|
||||||
|
|
||||||
// Number of bytes until the next page.
|
// Number of bytes until the next page.
|
||||||
size_t difference_to_page =
|
std::size_t difference_to_page =
|
||||||
Common::AlignUp(source_address, Memory::PAGE_SIZE) - source_address;
|
Common::AlignUp(source_address, Memory::PAGE_SIZE) - source_address;
|
||||||
// If the data fits in one page we can just copy the required size instead of the
|
// If the data fits in one page we can just copy the required size instead of the
|
||||||
// entire page.
|
// entire page.
|
||||||
size_t read_size = num_pages == 1 ? static_cast<size_t>(size) : difference_to_page;
|
std::size_t read_size =
|
||||||
|
num_pages == 1 ? static_cast<std::size_t>(size) : difference_to_page;
|
||||||
|
|
||||||
Memory::ReadBlock(*src_process, source_address, buffer->data() + page_offset,
|
Memory::ReadBlock(*src_process, source_address, buffer->data() + page_offset,
|
||||||
read_size);
|
read_size);
|
||||||
|
|
|
@ -46,8 +46,8 @@ SharedPtr<Process> Process::Create(SharedPtr<CodeSet> code_set) {
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
|
void Process::ParseKernelCaps(const u32* kernel_caps, std::size_t len) {
|
||||||
for (size_t i = 0; i < len; ++i) {
|
for (std::size_t i = 0; i < len; ++i) {
|
||||||
u32 descriptor = kernel_caps[i];
|
u32 descriptor = kernel_caps[i];
|
||||||
u32 type = descriptor >> 20;
|
u32 type = descriptor >> 20;
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p
|
||||||
|
|
||||||
// TODO(yuriks): As is, this lets processes map memory allocated by other processes from the
|
// TODO(yuriks): As is, this lets processes map memory allocated by other processes from the
|
||||||
// same region. It is unknown if or how the 3DS kernel checks against this.
|
// same region. It is unknown if or how the 3DS kernel checks against this.
|
||||||
size_t offset = target - GetLinearHeapBase();
|
std::size_t offset = target - GetLinearHeapBase();
|
||||||
CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, linheap_memory, offset, size,
|
CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, linheap_memory, offset, size,
|
||||||
MemoryState::Continuous));
|
MemoryState::Continuous));
|
||||||
vm_manager.Reprotect(vma, perms);
|
vm_manager.Reprotect(vma, perms);
|
||||||
|
|
|
@ -57,7 +57,7 @@ struct MemoryRegionInfo;
|
||||||
|
|
||||||
struct CodeSet final : public Object {
|
struct CodeSet final : public Object {
|
||||||
struct Segment {
|
struct Segment {
|
||||||
size_t offset = 0;
|
std::size_t offset = 0;
|
||||||
VAddr addr = 0;
|
VAddr addr = 0;
|
||||||
u32 size = 0;
|
u32 size = 0;
|
||||||
};
|
};
|
||||||
|
@ -159,7 +159,7 @@ public:
|
||||||
* Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
|
* Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
|
||||||
* to this process.
|
* to this process.
|
||||||
*/
|
*/
|
||||||
void ParseKernelCaps(const u32* kernel_caps, size_t len);
|
void ParseKernelCaps(const u32* kernel_caps, std::size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies address space changes and launches the process main thread.
|
* Applies address space changes and launches the process main thread.
|
||||||
|
|
|
@ -114,7 +114,7 @@ public:
|
||||||
/// Backing memory for this shared memory block.
|
/// Backing memory for this shared memory block.
|
||||||
std::shared_ptr<std::vector<u8>> backing_block;
|
std::shared_ptr<std::vector<u8>> backing_block;
|
||||||
/// Offset into the backing block for this shared memory.
|
/// Offset into the backing block for this shared memory.
|
||||||
size_t backing_block_offset;
|
std::size_t backing_block_offset;
|
||||||
/// Size of the memory block. Page-aligned.
|
/// Size of the memory block. Page-aligned.
|
||||||
u32 size;
|
u32 size;
|
||||||
/// Permission restrictions applied to the process which created the block.
|
/// Permission restrictions applied to the process which created the block.
|
||||||
|
|
|
@ -424,7 +424,7 @@ static ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 hand
|
||||||
thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
|
thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
|
||||||
|
|
||||||
// Add the thread to each of the objects' waiting threads.
|
// Add the thread to each of the objects' waiting threads.
|
||||||
for (size_t i = 0; i < objects.size(); ++i) {
|
for (std::size_t i = 0; i < objects.size(); ++i) {
|
||||||
WaitObject* object = objects[i].get();
|
WaitObject* object = objects[i].get();
|
||||||
object->AddWaitingThread(thread);
|
object->AddWaitingThread(thread);
|
||||||
}
|
}
|
||||||
|
@ -581,7 +581,7 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_
|
||||||
thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
|
thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
|
||||||
|
|
||||||
// Add the thread to each of the objects' waiting threads.
|
// Add the thread to each of the objects' waiting threads.
|
||||||
for (size_t i = 0; i < objects.size(); ++i) {
|
for (std::size_t i = 0; i < objects.size(); ++i) {
|
||||||
WaitObject* object = objects[i].get();
|
WaitObject* object = objects[i].get();
|
||||||
object->AddWaitingThread(thread);
|
object->AddWaitingThread(thread);
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,7 +378,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
|
||||||
return ERR_OUT_OF_MEMORY;
|
return ERR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t offset = linheap_memory->size();
|
std::size_t offset = linheap_memory->size();
|
||||||
|
|
||||||
// Allocate some memory from the end of the linear heap for this region.
|
// Allocate some memory from the end of the linear heap for this region.
|
||||||
linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0);
|
linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0);
|
||||||
|
|
|
@ -73,7 +73,7 @@ VMManager::VMAHandle VMManager::FindVMA(VAddr target) const {
|
||||||
|
|
||||||
ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
|
ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
|
||||||
std::shared_ptr<std::vector<u8>> block,
|
std::shared_ptr<std::vector<u8>> block,
|
||||||
size_t offset, u32 size,
|
std::size_t offset, u32 size,
|
||||||
MemoryState state) {
|
MemoryState state) {
|
||||||
ASSERT(block != nullptr);
|
ASSERT(block != nullptr);
|
||||||
ASSERT(offset + size <= block->size());
|
ASSERT(offset + size <= block->size());
|
||||||
|
@ -95,7 +95,7 @@ ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
|
||||||
|
|
||||||
ResultVal<VAddr> VMManager::MapMemoryBlockToBase(VAddr base, u32 region_size,
|
ResultVal<VAddr> VMManager::MapMemoryBlockToBase(VAddr base, u32 region_size,
|
||||||
std::shared_ptr<std::vector<u8>> block,
|
std::shared_ptr<std::vector<u8>> block,
|
||||||
size_t offset, u32 size, MemoryState state) {
|
std::size_t offset, u32 size, MemoryState state) {
|
||||||
|
|
||||||
// Find the first Free VMA.
|
// Find the first Free VMA.
|
||||||
VMAHandle vma_handle = std::find_if(vma_map.begin(), vma_map.end(), [&](const auto& vma) {
|
VMAHandle vma_handle = std::find_if(vma_map.begin(), vma_map.end(), [&](const auto& vma) {
|
||||||
|
|
|
@ -75,7 +75,7 @@ struct VirtualMemoryArea {
|
||||||
/// Memory block backing this VMA.
|
/// Memory block backing this VMA.
|
||||||
std::shared_ptr<std::vector<u8>> backing_block = nullptr;
|
std::shared_ptr<std::vector<u8>> backing_block = nullptr;
|
||||||
/// Offset into the backing_memory the mapping starts from.
|
/// Offset into the backing_memory the mapping starts from.
|
||||||
size_t offset = 0;
|
std::size_t offset = 0;
|
||||||
|
|
||||||
// Settings for type = BackingMemory
|
// Settings for type = BackingMemory
|
||||||
/// Pointer backing this VMA. It will not be destroyed or freed when the VMA is removed.
|
/// Pointer backing this VMA. It will not be destroyed or freed when the VMA is removed.
|
||||||
|
@ -142,7 +142,7 @@ public:
|
||||||
* @param state MemoryState tag to attach to the VMA.
|
* @param state MemoryState tag to attach to the VMA.
|
||||||
*/
|
*/
|
||||||
ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block,
|
ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block,
|
||||||
size_t offset, u32 size, MemoryState state);
|
std::size_t offset, u32 size, MemoryState state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps part of a ref-counted block of memory at the first free address after the given base.
|
* Maps part of a ref-counted block of memory at the first free address after the given base.
|
||||||
|
@ -156,8 +156,8 @@ public:
|
||||||
* @returns The address at which the memory was mapped.
|
* @returns The address at which the memory was mapped.
|
||||||
*/
|
*/
|
||||||
ResultVal<VAddr> MapMemoryBlockToBase(VAddr base, u32 region_size,
|
ResultVal<VAddr> MapMemoryBlockToBase(VAddr base, u32 region_size,
|
||||||
std::shared_ptr<std::vector<u8>> block, size_t offset,
|
std::shared_ptr<std::vector<u8>> block,
|
||||||
u32 size, MemoryState state);
|
std::size_t offset, u32 size, MemoryState state);
|
||||||
/**
|
/**
|
||||||
* Maps an unmanaged host memory pointer at a given address.
|
* Maps an unmanaged host memory pointer at a given address.
|
||||||
*
|
*
|
||||||
|
|
|
@ -74,12 +74,13 @@ struct TicketInfo {
|
||||||
|
|
||||||
static_assert(sizeof(TicketInfo) == 0x18, "Ticket info structure size is wrong");
|
static_assert(sizeof(TicketInfo) == 0x18, "Ticket info structure size is wrong");
|
||||||
|
|
||||||
ResultVal<size_t> CIAFile::Read(u64 offset, size_t length, u8* buffer) const {
|
ResultVal<std::size_t> CIAFile::Read(u64 offset, std::size_t length, u8* buffer) const {
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
return MakeResult<size_t>(length);
|
return MakeResult<std::size_t>(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> CIAFile::WriteTitleMetadata(u64 offset, size_t length, const u8* buffer) {
|
ResultVal<std::size_t> CIAFile::WriteTitleMetadata(u64 offset, std::size_t length,
|
||||||
|
const u8* buffer) {
|
||||||
container.LoadTitleMetadata(data, container.GetTitleMetadataOffset());
|
container.LoadTitleMetadata(data, container.GetTitleMetadataOffset());
|
||||||
FileSys::TitleMetadata tmd = container.GetTitleMetadata();
|
FileSys::TitleMetadata tmd = container.GetTitleMetadata();
|
||||||
tmd.Print();
|
tmd.Print();
|
||||||
|
@ -111,10 +112,10 @@ ResultVal<size_t> CIAFile::WriteTitleMetadata(u64 offset, size_t length, const u
|
||||||
content_written.resize(container.GetTitleMetadata().GetContentCount());
|
content_written.resize(container.GetTitleMetadata().GetContentCount());
|
||||||
install_state = CIAInstallState::TMDLoaded;
|
install_state = CIAInstallState::TMDLoaded;
|
||||||
|
|
||||||
return MakeResult<size_t>(length);
|
return MakeResult<std::size_t>(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> CIAFile::WriteContentData(u64 offset, size_t length, const u8* buffer) {
|
ResultVal<std::size_t> CIAFile::WriteContentData(u64 offset, std::size_t length, const u8* buffer) {
|
||||||
// Data is not being buffered, so we have to keep track of how much of each <ID>.app
|
// Data is not being buffered, so we have to keep track of how much of each <ID>.app
|
||||||
// has been written since we might get a written buffer which contains multiple .app
|
// has been written since we might get a written buffer which contains multiple .app
|
||||||
// contents or only part of a larger .app's contents.
|
// contents or only part of a larger .app's contents.
|
||||||
|
@ -153,10 +154,11 @@ ResultVal<size_t> CIAFile::WriteContentData(u64 offset, size_t length, const u8*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return MakeResult<size_t>(length);
|
return MakeResult<std::size_t>(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> CIAFile::Write(u64 offset, size_t length, bool flush, const u8* buffer) {
|
ResultVal<std::size_t> CIAFile::Write(u64 offset, std::size_t length, bool flush,
|
||||||
|
const u8* buffer) {
|
||||||
written += length;
|
written += length;
|
||||||
|
|
||||||
// TODO(shinyquagsire23): Can we assume that things will only be written in sequence?
|
// TODO(shinyquagsire23): Can we assume that things will only be written in sequence?
|
||||||
|
@ -168,9 +170,9 @@ ResultVal<size_t> CIAFile::Write(u64 offset, size_t length, bool flush, const u8
|
||||||
// content sizes so it ends up becoming a problem of keeping track of how much has been
|
// content sizes so it ends up becoming a problem of keeping track of how much has been
|
||||||
// written and what we have been able to pick up.
|
// written and what we have been able to pick up.
|
||||||
if (install_state == CIAInstallState::InstallStarted) {
|
if (install_state == CIAInstallState::InstallStarted) {
|
||||||
size_t buf_copy_size = std::min(length, FileSys::CIA_HEADER_SIZE);
|
std::size_t buf_copy_size = std::min(length, FileSys::CIA_HEADER_SIZE);
|
||||||
size_t buf_max_size =
|
std::size_t buf_max_size =
|
||||||
std::min(static_cast<size_t>(offset + length), FileSys::CIA_HEADER_SIZE);
|
std::min(static_cast<std::size_t>(offset + length), FileSys::CIA_HEADER_SIZE);
|
||||||
data.resize(buf_max_size);
|
data.resize(buf_max_size);
|
||||||
memcpy(data.data() + offset, buffer, buf_copy_size);
|
memcpy(data.data() + offset, buffer, buf_copy_size);
|
||||||
|
|
||||||
|
@ -184,18 +186,18 @@ ResultVal<size_t> CIAFile::Write(u64 offset, size_t length, bool flush, const u8
|
||||||
|
|
||||||
// If we don't have a header yet, we can't pull offsets of other sections
|
// If we don't have a header yet, we can't pull offsets of other sections
|
||||||
if (install_state == CIAInstallState::InstallStarted)
|
if (install_state == CIAInstallState::InstallStarted)
|
||||||
return MakeResult<size_t>(length);
|
return MakeResult<std::size_t>(length);
|
||||||
|
|
||||||
// If we have been given data before (or including) .app content, pull it into
|
// If we have been given data before (or including) .app content, pull it into
|
||||||
// our buffer, but only pull *up to* the content offset, no further.
|
// our buffer, but only pull *up to* the content offset, no further.
|
||||||
if (offset < container.GetContentOffset()) {
|
if (offset < container.GetContentOffset()) {
|
||||||
size_t buf_loaded = data.size();
|
std::size_t buf_loaded = data.size();
|
||||||
size_t copy_offset = std::max(static_cast<size_t>(offset), buf_loaded);
|
std::size_t copy_offset = std::max(static_cast<std::size_t>(offset), buf_loaded);
|
||||||
size_t buf_offset = buf_loaded - offset;
|
std::size_t buf_offset = buf_loaded - offset;
|
||||||
size_t buf_copy_size =
|
std::size_t buf_copy_size =
|
||||||
std::min(length, static_cast<size_t>(container.GetContentOffset() - offset)) -
|
std::min(length, static_cast<std::size_t>(container.GetContentOffset() - offset)) -
|
||||||
buf_loaded;
|
buf_loaded;
|
||||||
size_t buf_max_size = std::min(offset + length, container.GetContentOffset());
|
std::size_t buf_max_size = std::min(offset + length, container.GetContentOffset());
|
||||||
data.resize(buf_max_size);
|
data.resize(buf_max_size);
|
||||||
memcpy(data.data() + copy_offset, buffer + buf_offset, buf_copy_size);
|
memcpy(data.data() + copy_offset, buffer + buf_offset, buf_copy_size);
|
||||||
}
|
}
|
||||||
|
@ -212,14 +214,14 @@ ResultVal<size_t> CIAFile::Write(u64 offset, size_t length, bool flush, const u8
|
||||||
|
|
||||||
// Content data sizes can only be retrieved from TMD data
|
// Content data sizes can only be retrieved from TMD data
|
||||||
if (install_state != CIAInstallState::TMDLoaded)
|
if (install_state != CIAInstallState::TMDLoaded)
|
||||||
return MakeResult<size_t>(length);
|
return MakeResult<std::size_t>(length);
|
||||||
|
|
||||||
// From this point forward, data will no longer be buffered in data
|
// From this point forward, data will no longer be buffered in data
|
||||||
auto result = WriteContentData(offset, length, buffer);
|
auto result = WriteContentData(offset, length, buffer);
|
||||||
if (result.Failed())
|
if (result.Failed())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return MakeResult<size_t>(length);
|
return MakeResult<std::size_t>(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 CIAFile::GetSize() const {
|
u64 CIAFile::GetSize() const {
|
||||||
|
@ -232,7 +234,7 @@ bool CIAFile::SetSize(u64 size) const {
|
||||||
|
|
||||||
bool CIAFile::Close() const {
|
bool CIAFile::Close() const {
|
||||||
bool complete = true;
|
bool complete = true;
|
||||||
for (size_t i = 0; i < container.GetTitleMetadata().GetContentCount(); i++) {
|
for (std::size_t i = 0; i < container.GetTitleMetadata().GetContentCount(); i++) {
|
||||||
if (content_written[i] < container.GetContentSize(static_cast<u16>(i)))
|
if (content_written[i] < container.GetContentSize(static_cast<u16>(i)))
|
||||||
complete = false;
|
complete = false;
|
||||||
}
|
}
|
||||||
|
@ -294,7 +296,7 @@ InstallStatus InstallCIA(const std::string& path,
|
||||||
Service::AM::CIAFile installFile(
|
Service::AM::CIAFile installFile(
|
||||||
Service::AM::GetTitleMediaType(container.GetTitleMetadata().GetTitleID()));
|
Service::AM::GetTitleMediaType(container.GetTitleMetadata().GetTitleID()));
|
||||||
|
|
||||||
for (size_t i = 0; i < container.GetTitleMetadata().GetContentCount(); i++) {
|
for (std::size_t i = 0; i < container.GetTitleMetadata().GetContentCount(); i++) {
|
||||||
if (container.GetTitleMetadata().GetContentTypeByIndex(static_cast<u16>(i)) &
|
if (container.GetTitleMetadata().GetContentTypeByIndex(static_cast<u16>(i)) &
|
||||||
FileSys::TMDContentTypeFlag::Encrypted) {
|
FileSys::TMDContentTypeFlag::Encrypted) {
|
||||||
LOG_ERROR(Service_AM, "File {} is encrypted! Aborting...", path);
|
LOG_ERROR(Service_AM, "File {} is encrypted! Aborting...", path);
|
||||||
|
@ -307,9 +309,9 @@ InstallStatus InstallCIA(const std::string& path,
|
||||||
return InstallStatus::ErrorFailedToOpenFile;
|
return InstallStatus::ErrorFailedToOpenFile;
|
||||||
|
|
||||||
std::array<u8, 0x10000> buffer;
|
std::array<u8, 0x10000> buffer;
|
||||||
size_t total_bytes_read = 0;
|
std::size_t total_bytes_read = 0;
|
||||||
while (total_bytes_read != file.GetSize()) {
|
while (total_bytes_read != file.GetSize()) {
|
||||||
size_t bytes_read = file.ReadBytes(buffer.data(), buffer.size());
|
std::size_t bytes_read = file.ReadBytes(buffer.data(), buffer.size());
|
||||||
auto result = installFile.Write(static_cast<u64>(total_bytes_read), bytes_read, true,
|
auto result = installFile.Write(static_cast<u64>(total_bytes_read), bytes_read, true,
|
||||||
static_cast<u8*>(buffer.data()));
|
static_cast<u8*>(buffer.data()));
|
||||||
|
|
||||||
|
@ -525,7 +527,7 @@ void Module::Interface::FindDLCContentInfos(Kernel::HLERequestContext& ctx) {
|
||||||
if (tmd.Load(tmd_path) == Loader::ResultStatus::Success) {
|
if (tmd.Load(tmd_path) == Loader::ResultStatus::Success) {
|
||||||
std::size_t write_offset = 0;
|
std::size_t write_offset = 0;
|
||||||
// Get info for each content index requested
|
// Get info for each content index requested
|
||||||
for (size_t i = 0; i < content_count; i++) {
|
for (std::size_t i = 0; i < content_count; i++) {
|
||||||
std::shared_ptr<FileUtil::IOFile> romfs_file;
|
std::shared_ptr<FileUtil::IOFile> romfs_file;
|
||||||
u64 romfs_offset = 0;
|
u64 romfs_offset = 0;
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,10 @@ enum class InstallStatus : u32 {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Title ID valid length
|
// Title ID valid length
|
||||||
constexpr size_t TITLE_ID_VALID_LENGTH = 16;
|
constexpr std::size_t TITLE_ID_VALID_LENGTH = 16;
|
||||||
|
|
||||||
// Progress callback for InstallCIA, receives bytes written and total bytes
|
// Progress callback for InstallCIA, receives bytes written and total bytes
|
||||||
using ProgressCallback = void(size_t, size_t);
|
using ProgressCallback = void(std::size_t, std::size_t);
|
||||||
|
|
||||||
// A file handled returned for CIAs to be written into and subsequently installed.
|
// A file handled returned for CIAs to be written into and subsequently installed.
|
||||||
class CIAFile final : public FileSys::FileBackend {
|
class CIAFile final : public FileSys::FileBackend {
|
||||||
|
@ -66,10 +66,11 @@ public:
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
|
ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const override;
|
||||||
ResultVal<size_t> WriteTitleMetadata(u64 offset, size_t length, const u8* buffer);
|
ResultVal<std::size_t> WriteTitleMetadata(u64 offset, std::size_t length, const u8* buffer);
|
||||||
ResultVal<size_t> WriteContentData(u64 offset, size_t length, const u8* buffer);
|
ResultVal<std::size_t> WriteContentData(u64 offset, std::size_t length, const u8* buffer);
|
||||||
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) override;
|
ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush,
|
||||||
|
const u8* buffer) override;
|
||||||
u64 GetSize() const override;
|
u64 GetSize() const override;
|
||||||
bool SetSize(u64 size) const override;
|
bool SetSize(u64 size) const override;
|
||||||
bool Close() const override;
|
bool Close() const override;
|
||||||
|
|
|
@ -19,11 +19,11 @@ struct AppletTitleData {
|
||||||
std::array<AppletId, 2> applet_ids;
|
std::array<AppletId, 2> applet_ids;
|
||||||
|
|
||||||
// There's a specific TitleId per region for each applet.
|
// There's a specific TitleId per region for each applet.
|
||||||
static constexpr size_t NumRegions = 7;
|
static constexpr std::size_t NumRegions = 7;
|
||||||
std::array<u64, NumRegions> title_ids;
|
std::array<u64, NumRegions> title_ids;
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr size_t NumApplets = 29;
|
static constexpr std::size_t NumApplets = 29;
|
||||||
static constexpr std::array<AppletTitleData, NumApplets> applet_titleids = {{
|
static constexpr std::array<AppletTitleData, NumApplets> applet_titleids = {{
|
||||||
{AppletId::HomeMenu, AppletId::None, 0x4003000008202, 0x4003000008F02, 0x4003000009802,
|
{AppletId::HomeMenu, AppletId::None, 0x4003000008202, 0x4003000008F02, 0x4003000009802,
|
||||||
0x4003000008202, 0x400300000A102, 0x400300000A902, 0x400300000B102},
|
0x4003000008202, 0x400300000A102, 0x400300000A902, 0x400300000B102},
|
||||||
|
@ -84,7 +84,7 @@ static u64 GetTitleIdForApplet(AppletId id) {
|
||||||
|
|
||||||
AppletManager::AppletSlotData* AppletManager::GetAppletSlotData(AppletId id) {
|
AppletManager::AppletSlotData* AppletManager::GetAppletSlotData(AppletId id) {
|
||||||
auto GetSlot = [this](AppletSlot slot) -> AppletSlotData* {
|
auto GetSlot = [this](AppletSlot slot) -> AppletSlotData* {
|
||||||
return &applet_slots[static_cast<size_t>(slot)];
|
return &applet_slots[static_cast<std::size_t>(slot)];
|
||||||
};
|
};
|
||||||
|
|
||||||
if (id == AppletId::Application) {
|
if (id == AppletId::Application) {
|
||||||
|
@ -160,9 +160,9 @@ AppletManager::AppletSlotData* AppletManager::GetAppletSlotData(AppletAttributes
|
||||||
// The Home Menu is a system applet, however, it has its own applet slot so that it can run
|
// The Home Menu is a system applet, however, it has its own applet slot so that it can run
|
||||||
// concurrently with other system applets.
|
// concurrently with other system applets.
|
||||||
if (slot == AppletSlot::SystemApplet && attributes.is_home_menu)
|
if (slot == AppletSlot::SystemApplet && attributes.is_home_menu)
|
||||||
return &applet_slots[static_cast<size_t>(AppletSlot::HomeMenu)];
|
return &applet_slots[static_cast<std::size_t>(AppletSlot::HomeMenu)];
|
||||||
|
|
||||||
return &applet_slots[static_cast<size_t>(slot)];
|
return &applet_slots[static_cast<std::size_t>(slot)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppletManager::CancelAndSendParameter(const MessageParameter& parameter) {
|
void AppletManager::CancelAndSendParameter(const MessageParameter& parameter) {
|
||||||
|
@ -314,7 +314,7 @@ ResultCode AppletManager::PrepareToStartLibraryApplet(AppletId applet_id) {
|
||||||
ErrorSummary::InvalidState, ErrorLevel::Status);
|
ErrorSummary::InvalidState, ErrorLevel::Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& slot = applet_slots[static_cast<size_t>(AppletSlot::LibraryApplet)];
|
const auto& slot = applet_slots[static_cast<std::size_t>(AppletSlot::LibraryApplet)];
|
||||||
|
|
||||||
if (slot.registered) {
|
if (slot.registered) {
|
||||||
return ResultCode(ErrorDescription::AlreadyExists, ErrorModule::Applet,
|
return ResultCode(ErrorDescription::AlreadyExists, ErrorModule::Applet,
|
||||||
|
@ -341,7 +341,7 @@ ResultCode AppletManager::PrepareToStartLibraryApplet(AppletId applet_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode AppletManager::PreloadLibraryApplet(AppletId applet_id) {
|
ResultCode AppletManager::PreloadLibraryApplet(AppletId applet_id) {
|
||||||
const auto& slot = applet_slots[static_cast<size_t>(AppletSlot::LibraryApplet)];
|
const auto& slot = applet_slots[static_cast<std::size_t>(AppletSlot::LibraryApplet)];
|
||||||
|
|
||||||
if (slot.registered) {
|
if (slot.registered) {
|
||||||
return ResultCode(ErrorDescription::AlreadyExists, ErrorModule::Applet,
|
return ResultCode(ErrorDescription::AlreadyExists, ErrorModule::Applet,
|
||||||
|
@ -369,7 +369,7 @@ ResultCode AppletManager::PreloadLibraryApplet(AppletId applet_id) {
|
||||||
|
|
||||||
ResultCode AppletManager::FinishPreloadingLibraryApplet(AppletId applet_id) {
|
ResultCode AppletManager::FinishPreloadingLibraryApplet(AppletId applet_id) {
|
||||||
// TODO(Subv): This function should fail depending on the applet preparation state.
|
// TODO(Subv): This function should fail depending on the applet preparation state.
|
||||||
auto& slot = applet_slots[static_cast<size_t>(AppletSlot::LibraryApplet)];
|
auto& slot = applet_slots[static_cast<std::size_t>(AppletSlot::LibraryApplet)];
|
||||||
slot.loaded = true;
|
slot.loaded = true;
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ ResultCode AppletManager::PrepareToCloseLibraryApplet(bool not_pause, bool exiti
|
||||||
|
|
||||||
ResultCode AppletManager::CloseLibraryApplet(Kernel::SharedPtr<Kernel::Object> object,
|
ResultCode AppletManager::CloseLibraryApplet(Kernel::SharedPtr<Kernel::Object> object,
|
||||||
std::vector<u8> buffer) {
|
std::vector<u8> buffer) {
|
||||||
auto& slot = applet_slots[static_cast<size_t>(AppletSlot::LibraryApplet)];
|
auto& slot = applet_slots[static_cast<std::size_t>(AppletSlot::LibraryApplet)];
|
||||||
|
|
||||||
MessageParameter param;
|
MessageParameter param;
|
||||||
// TODO(Subv): The destination id should be the "current applet slot id", which changes
|
// TODO(Subv): The destination id should be the "current applet slot id", which changes
|
||||||
|
@ -467,7 +467,7 @@ ResultVal<AppletManager::AppletInfo> AppletManager::GetAppletInfo(AppletId app_i
|
||||||
}
|
}
|
||||||
|
|
||||||
AppletManager::AppletManager() {
|
AppletManager::AppletManager() {
|
||||||
for (size_t slot = 0; slot < applet_slots.size(); ++slot) {
|
for (std::size_t slot = 0; slot < applet_slots.size(); ++slot) {
|
||||||
auto& slot_data = applet_slots[slot];
|
auto& slot_data = applet_slots[slot];
|
||||||
slot_data.slot = static_cast<AppletSlot>(slot);
|
slot_data.slot = static_cast<AppletSlot>(slot);
|
||||||
slot_data.applet_id = AppletId::None;
|
slot_data.applet_id = AppletId::None;
|
||||||
|
|
|
@ -146,7 +146,7 @@ private:
|
||||||
/// TODO(Subv): Use std::optional once we migrate to C++17.
|
/// TODO(Subv): Use std::optional once we migrate to C++17.
|
||||||
boost::optional<MessageParameter> next_parameter;
|
boost::optional<MessageParameter> next_parameter;
|
||||||
|
|
||||||
static constexpr size_t NumAppletSlot = 4;
|
static constexpr std::size_t NumAppletSlot = 4;
|
||||||
|
|
||||||
enum class AppletSlot : u8 {
|
enum class AppletSlot : u8 {
|
||||||
Application,
|
Application,
|
||||||
|
|
|
@ -533,7 +533,7 @@ void Module::Interface::StartLibraryApplet(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx, 0x1E, 2, 4); // 0x1E0084
|
IPC::RequestParser rp(ctx, 0x1E, 2, 4); // 0x1E0084
|
||||||
AppletId applet_id = rp.PopEnum<AppletId>();
|
AppletId applet_id = rp.PopEnum<AppletId>();
|
||||||
|
|
||||||
size_t buffer_size = rp.Pop<u32>();
|
std::size_t buffer_size = rp.Pop<u32>();
|
||||||
Kernel::SharedPtr<Kernel::Object> object = rp.PopGenericObject();
|
Kernel::SharedPtr<Kernel::Object> object = rp.PopGenericObject();
|
||||||
std::vector<u8> buffer = rp.PopStaticBuffer();
|
std::vector<u8> buffer = rp.PopStaticBuffer();
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ void Module::CompletionEventCallBack(u64 port_id, s64) {
|
||||||
port.dest_size, buffer_size);
|
port.dest_size, buffer_size);
|
||||||
}
|
}
|
||||||
Memory::WriteBlock(*port.dest_process, port.dest, buffer.data(),
|
Memory::WriteBlock(*port.dest_process, port.dest, buffer.data(),
|
||||||
std::min<size_t>(port.dest_size, buffer_size));
|
std::min<std::size_t>(port.dest_size, buffer_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
port.is_receiving = false;
|
port.is_receiving = false;
|
||||||
|
|
|
@ -477,7 +477,7 @@ ResultCode Module::FormatConfig() {
|
||||||
|
|
||||||
u16_le country_name_buffer[16][0x40] = {};
|
u16_le country_name_buffer[16][0x40] = {};
|
||||||
std::u16string region_name = Common::UTF8ToUTF16("Gensokyo");
|
std::u16string region_name = Common::UTF8ToUTF16("Gensokyo");
|
||||||
for (size_t i = 0; i < 16; ++i) {
|
for (std::size_t i = 0; i < 16; ++i) {
|
||||||
std::copy(region_name.cbegin(), region_name.cend(), country_name_buffer[i]);
|
std::copy(region_name.cbegin(), region_name.cend(), country_name_buffer[i]);
|
||||||
}
|
}
|
||||||
// 0x000B0001 - Localized names for the profile Country
|
// 0x000B0001 - Localized names for the profile Country
|
||||||
|
@ -627,7 +627,7 @@ std::u16string Module::GetUsername() {
|
||||||
// the username string in the block isn't null-terminated,
|
// the username string in the block isn't null-terminated,
|
||||||
// so we need to find the end manually.
|
// so we need to find the end manually.
|
||||||
std::u16string username(block.username, ARRAY_SIZE(block.username));
|
std::u16string username(block.username, ARRAY_SIZE(block.username));
|
||||||
const size_t pos = username.find(u'\0');
|
const std::size_t pos = username.find(u'\0');
|
||||||
if (pos != std::u16string::npos)
|
if (pos != std::u16string::npos)
|
||||||
username.erase(pos);
|
username.erase(pos);
|
||||||
return username;
|
return username;
|
||||||
|
|
|
@ -330,16 +330,16 @@ Kernel::SharedPtr<Kernel::Event>& DSP_DSP::GetInterruptEvent(InterruptType type,
|
||||||
case InterruptType::One:
|
case InterruptType::One:
|
||||||
return interrupt_one;
|
return interrupt_one;
|
||||||
case InterruptType::Pipe: {
|
case InterruptType::Pipe: {
|
||||||
const size_t pipe_index = static_cast<size_t>(pipe);
|
const std::size_t pipe_index = static_cast<std::size_t>(pipe);
|
||||||
ASSERT(pipe_index < AudioCore::num_dsp_pipe);
|
ASSERT(pipe_index < AudioCore::num_dsp_pipe);
|
||||||
return pipes[pipe_index];
|
return pipes[pipe_index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UNREACHABLE_MSG("Invalid interrupt type = {}", static_cast<size_t>(type));
|
UNREACHABLE_MSG("Invalid interrupt type = {}", static_cast<std::size_t>(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DSP_DSP::HasTooManyEventsRegistered() const {
|
bool DSP_DSP::HasTooManyEventsRegistered() const {
|
||||||
size_t number =
|
std::size_t number =
|
||||||
std::count_if(pipes.begin(), pipes.end(), [](const auto& evt) { return evt != nullptr; });
|
std::count_if(pipes.begin(), pipes.end(), [](const auto& evt) { return evt != nullptr; });
|
||||||
|
|
||||||
if (interrupt_zero != nullptr)
|
if (interrupt_zero != nullptr)
|
||||||
|
|
|
@ -18,11 +18,11 @@ public:
|
||||||
~DSP_DSP();
|
~DSP_DSP();
|
||||||
|
|
||||||
/// There are three types of interrupts
|
/// There are three types of interrupts
|
||||||
static constexpr size_t NUM_INTERRUPT_TYPE = 3;
|
static constexpr std::size_t NUM_INTERRUPT_TYPE = 3;
|
||||||
enum class InterruptType : u32 { Zero = 0, One = 1, Pipe = 2 };
|
enum class InterruptType : u32 { Zero = 0, One = 1, Pipe = 2 };
|
||||||
|
|
||||||
/// Actual service implementation only has 6 'slots' for interrupts.
|
/// Actual service implementation only has 6 'slots' for interrupts.
|
||||||
static constexpr size_t max_number_of_interrupt_events = 6;
|
static constexpr std::size_t max_number_of_interrupt_events = 6;
|
||||||
|
|
||||||
/// Signal interrupt on pipe
|
/// Signal interrupt on pipe
|
||||||
void SignalInterrupt(InterruptType type, AudioCore::DspPipe pipe);
|
void SignalInterrupt(InterruptType type, AudioCore::DspPipe pipe);
|
||||||
|
|
|
@ -106,8 +106,8 @@ void Module::Interface::GetMyScreenName(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::Interface::UnscrambleLocalFriendCode(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::UnscrambleLocalFriendCode(Kernel::HLERequestContext& ctx) {
|
||||||
const size_t scrambled_friend_code_size = 12;
|
const std::size_t scrambled_friend_code_size = 12;
|
||||||
const size_t friend_code_size = 8;
|
const std::size_t friend_code_size = 8;
|
||||||
|
|
||||||
IPC::RequestParser rp(ctx, 0x1C, 1, 2);
|
IPC::RequestParser rp(ctx, 0x1C, 1, 2);
|
||||||
const u32 friend_code_count = rp.Pop<u32>();
|
const u32 friend_code_count = rp.Pop<u32>();
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue