mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-05 05:35:07 +01:00
Run Android Studio Formatter on the Project
This commit fixes a lot of style errors throughout the project by letting the Android Studio Formatter fix them. This commit also splits the Circular Buffer into it's own file.
This commit is contained in:
parent
7f78a679c3
commit
4637b4ac97
@ -17,7 +17,7 @@ namespace skyline::audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<AudioTrack> Audio::OpenTrack(const int channelCount, const int sampleRate, const std::function<void()> &releaseCallback) {
|
std::shared_ptr<AudioTrack> Audio::OpenTrack(const int channelCount, const int sampleRate, const std::function<void()> &releaseCallback) {
|
||||||
std::lock_guard trackGuard(trackMutex);
|
std::lock_guard trackGuard(trackLock);
|
||||||
|
|
||||||
auto track = std::make_shared<AudioTrack>(channelCount, sampleRate, releaseCallback);
|
auto track = std::make_shared<AudioTrack>(channelCount, sampleRate, releaseCallback);
|
||||||
audioTracks.push_back(track);
|
audioTracks.push_back(track);
|
||||||
@ -26,7 +26,7 @@ namespace skyline::audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Audio::CloseTrack(std::shared_ptr<AudioTrack> &track) {
|
void Audio::CloseTrack(std::shared_ptr<AudioTrack> &track) {
|
||||||
std::lock_guard trackGuard(trackMutex);
|
std::lock_guard trackGuard(trackLock);
|
||||||
|
|
||||||
audioTracks.erase(std::remove(audioTracks.begin(), audioTracks.end(), track), audioTracks.end());
|
audioTracks.erase(std::remove(audioTracks.begin(), audioTracks.end(), track), audioTracks.end());
|
||||||
track.reset();
|
track.reset();
|
||||||
@ -37,7 +37,7 @@ namespace skyline::audio {
|
|||||||
size_t streamSamples = static_cast<size_t>(numFrames) * audioStream->getChannelCount();
|
size_t streamSamples = static_cast<size_t>(numFrames) * audioStream->getChannelCount();
|
||||||
size_t writtenSamples = 0;
|
size_t writtenSamples = 0;
|
||||||
|
|
||||||
std::unique_lock trackLock(trackMutex);
|
std::unique_lock trackGuard(trackLock);
|
||||||
|
|
||||||
for (auto &track : audioTracks) {
|
for (auto &track : audioTracks) {
|
||||||
if (track->playbackState == AudioOutState::Stopped)
|
if (track->playbackState == AudioOutState::Stopped)
|
||||||
@ -55,7 +55,7 @@ namespace skyline::audio {
|
|||||||
track->CheckReleasedBuffers();
|
track->CheckReleasedBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
trackLock.unlock();
|
trackGuard.unlock();
|
||||||
|
|
||||||
if (streamSamples > writtenSamples)
|
if (streamSamples > writtenSamples)
|
||||||
memset(destBuffer + writtenSamples, 0, (streamSamples - writtenSamples) * sizeof(i16));
|
memset(destBuffer + writtenSamples, 0, (streamSamples - writtenSamples) * sizeof(i16));
|
||||||
|
@ -20,7 +20,7 @@ namespace skyline::audio {
|
|||||||
oboe::AudioStreamBuilder builder; //!< The audio stream builder, used to open
|
oboe::AudioStreamBuilder builder; //!< The audio stream builder, used to open
|
||||||
oboe::ManagedStream outputStream; //!< The output oboe audio stream
|
oboe::ManagedStream outputStream; //!< The output oboe audio stream
|
||||||
std::vector<std::shared_ptr<audio::AudioTrack>> audioTracks; //!< A vector of shared_ptr to every open audio track
|
std::vector<std::shared_ptr<audio::AudioTrack>> audioTracks; //!< A vector of shared_ptr to every open audio track
|
||||||
Mutex trackMutex; //!< This mutex is used to ensure that audioTracks isn't modified while it is being used
|
Mutex trackLock; //!< This mutex is used to ensure that audioTracks isn't modified while it is being used
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Audio(const DeviceState &state);
|
Audio(const DeviceState &state);
|
||||||
|
152
app/src/main/cpp/skyline/audio/circular_buffer.h
Normal file
152
app/src/main/cpp/skyline/audio/circular_buffer.h
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace skyline::audio {
|
||||||
|
/**
|
||||||
|
* @brief This class is used to abstract an array into a circular buffer
|
||||||
|
* @tparam Type The type of elements stored in the buffer
|
||||||
|
* @tparam Size The maximum size of the circular buffer
|
||||||
|
*/
|
||||||
|
template<typename Type, size_t Size>
|
||||||
|
class CircularBuffer {
|
||||||
|
private:
|
||||||
|
std::array <Type, Size> array{}; //!< The internal array holding the circular buffer
|
||||||
|
Type *start{array.begin()}; //!< The start/oldest element of the internal array
|
||||||
|
Type *end{array.begin()}; //!< The end/newest element of the internal array
|
||||||
|
bool empty{true}; //!< This boolean is used to differentiate between the buffer being full or empty
|
||||||
|
Mutex mtx; //!< The mutex ensures that the buffer operations don't overlap
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief This reads data from this buffer into the specified buffer
|
||||||
|
* @param address The address to write buffer data into
|
||||||
|
* @param maxSize The maximum amount of data to write in units of Type
|
||||||
|
* @param copyFunction If this is specified, then this is called rather than memcpy
|
||||||
|
* @return The amount of data written into the input buffer in units of Type
|
||||||
|
*/
|
||||||
|
inline size_t Read(Type *address, ssize_t maxSize, void copyFunction(Type *, Type *) = {}, ssize_t copyOffset = -1) {
|
||||||
|
std::lock_guard guard(mtx);
|
||||||
|
|
||||||
|
if (empty)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ssize_t size{}, sizeBegin{}, sizeEnd{};
|
||||||
|
|
||||||
|
if (start < end) {
|
||||||
|
sizeEnd = std::min(end - start, maxSize);
|
||||||
|
|
||||||
|
size = sizeEnd;
|
||||||
|
} else {
|
||||||
|
sizeEnd = std::min(array.end() - start, maxSize);
|
||||||
|
sizeBegin = std::min(end - array.begin(), maxSize - sizeEnd);
|
||||||
|
|
||||||
|
size = sizeBegin + sizeEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copyFunction && copyOffset) {
|
||||||
|
auto sourceEnd = start + ((copyOffset != -1) ? copyOffset : sizeEnd);
|
||||||
|
|
||||||
|
for (auto source = start, destination = address; source < sourceEnd; source++, destination++)
|
||||||
|
copyFunction(source, destination);
|
||||||
|
|
||||||
|
if (copyOffset != -1) {
|
||||||
|
std::memcpy(address + copyOffset, start + copyOffset, (sizeEnd - copyOffset) * sizeof(Type));
|
||||||
|
copyOffset -= sizeEnd;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::memcpy(address, start, sizeEnd * sizeof(Type));
|
||||||
|
}
|
||||||
|
|
||||||
|
address += sizeEnd;
|
||||||
|
|
||||||
|
if (sizeBegin) {
|
||||||
|
if (copyFunction && copyOffset) {
|
||||||
|
auto sourceEnd = array.begin() + ((copyOffset != -1) ? copyOffset : sizeBegin);
|
||||||
|
|
||||||
|
for (auto source = array.begin(), destination = address; source < sourceEnd; source++, destination++)
|
||||||
|
copyFunction(source, destination);
|
||||||
|
|
||||||
|
if (copyOffset != -1)
|
||||||
|
std::memcpy(array.begin() + copyOffset, address + copyOffset, (sizeBegin - copyOffset) * sizeof(Type));
|
||||||
|
} else {
|
||||||
|
std::memcpy(address, array.begin(), sizeBegin * sizeof(Type));
|
||||||
|
}
|
||||||
|
|
||||||
|
start = array.begin() + sizeBegin;
|
||||||
|
} else {
|
||||||
|
start += sizeEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start == end)
|
||||||
|
empty = true;
|
||||||
|
|
||||||
|
return static_cast<size_t>(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This appends data from the specified buffer into this buffer
|
||||||
|
* @param address The address of the buffer
|
||||||
|
* @param size The size of the buffer in units of Type
|
||||||
|
*/
|
||||||
|
inline void Append(Type *address, ssize_t size) {
|
||||||
|
std::lock_guard guard(mtx);
|
||||||
|
|
||||||
|
while (size) {
|
||||||
|
if (start <= end && end != array.end()) {
|
||||||
|
auto sizeEnd = std::min(array.end() - end, size);
|
||||||
|
std::memcpy(end, address, sizeEnd * sizeof(Type));
|
||||||
|
|
||||||
|
address += sizeEnd;
|
||||||
|
size -= sizeEnd;
|
||||||
|
|
||||||
|
end += sizeEnd;
|
||||||
|
} else {
|
||||||
|
auto sizePreStart = (end == array.end()) ? std::min(start - array.begin(), size) : std::min(start - end, size);
|
||||||
|
auto sizePostStart = std::min(array.end() - start, size - sizePreStart);
|
||||||
|
|
||||||
|
if (sizePreStart)
|
||||||
|
std::memcpy((end == array.end()) ? array.begin() : end, address, sizePreStart * sizeof(Type));
|
||||||
|
|
||||||
|
if (end == array.end())
|
||||||
|
end = array.begin() + sizePreStart;
|
||||||
|
else
|
||||||
|
end += sizePreStart;
|
||||||
|
|
||||||
|
address += sizePreStart;
|
||||||
|
size -= sizePreStart;
|
||||||
|
|
||||||
|
if (sizePostStart)
|
||||||
|
std::memcpy(end, address, sizePostStart * sizeof(Type));
|
||||||
|
|
||||||
|
if (start == array.end())
|
||||||
|
start = array.begin() + sizePostStart;
|
||||||
|
else
|
||||||
|
start += sizePostStart;
|
||||||
|
|
||||||
|
if (end == array.end())
|
||||||
|
end = array.begin() + sizePostStart;
|
||||||
|
else
|
||||||
|
end += sizePostStart;
|
||||||
|
|
||||||
|
address += sizePostStart;
|
||||||
|
size -= sizePostStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This appends data from a vector to the buffer
|
||||||
|
* @param sampleData A reference to a vector containing the data to be appended
|
||||||
|
*/
|
||||||
|
inline void Append(const std::vector <Type> &data) {
|
||||||
|
Append(const_cast<Type *>(data.data()), data.size());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -4,8 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <oboe/Oboe.h>
|
#include <oboe/Oboe.h>
|
||||||
#include <common.h>
|
#include "circular_buffer.h"
|
||||||
#include <array>
|
|
||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
@ -59,148 +58,5 @@ namespace skyline {
|
|||||||
inline Out Saturate(In value) {
|
inline Out Saturate(In value) {
|
||||||
return static_cast<Out>(std::clamp(static_cast<Intermediate>(value), static_cast<Intermediate>(std::numeric_limits<Out>::min()), static_cast<Intermediate>(std::numeric_limits<Out>::max())));
|
return static_cast<Out>(std::clamp(static_cast<Intermediate>(value), static_cast<Intermediate>(std::numeric_limits<Out>::min()), static_cast<Intermediate>(std::numeric_limits<Out>::max())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This class is used to abstract an array into a circular buffer
|
|
||||||
* @tparam Type The type of elements stored in the buffer
|
|
||||||
* @tparam Size The maximum size of the circular buffer
|
|
||||||
*/
|
|
||||||
template<typename Type, size_t Size>
|
|
||||||
class CircularBuffer {
|
|
||||||
private:
|
|
||||||
std::array<Type, Size> array{}; //!< The internal array holding the circular buffer
|
|
||||||
Type *start{array.begin()}; //!< The start/oldest element of the internal array
|
|
||||||
Type *end{array.begin()}; //!< The end/newest element of the internal array
|
|
||||||
bool empty{true}; //!< This boolean is used to differentiate between the buffer being full or empty
|
|
||||||
Mutex mtx; //!< The mutex ensures that the buffer operations don't overlap
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief This reads data from this buffer into the specified buffer
|
|
||||||
* @param address The address to write buffer data into
|
|
||||||
* @param maxSize The maximum amount of data to write in units of Type
|
|
||||||
* @param function If this is specified, then this is called rather than memcpy
|
|
||||||
* @return The amount of data written into the input buffer in units of Type
|
|
||||||
*/
|
|
||||||
inline size_t Read(Type *address, ssize_t maxSize, void function(Type *, Type *) = {}, ssize_t copyOffset = -1) {
|
|
||||||
std::lock_guard guard(mtx);
|
|
||||||
|
|
||||||
if (empty)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ssize_t size{}, sizeBegin{}, sizeEnd{};
|
|
||||||
|
|
||||||
if (start < end) {
|
|
||||||
sizeEnd = std::min(end - start, maxSize);
|
|
||||||
|
|
||||||
size = sizeEnd;
|
|
||||||
} else {
|
|
||||||
sizeEnd = std::min(array.end() - start, maxSize);
|
|
||||||
sizeBegin = std::min(end - array.begin(), maxSize - sizeEnd);
|
|
||||||
|
|
||||||
size = sizeBegin + sizeEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (function && copyOffset) {
|
|
||||||
auto sourceEnd = start + ((copyOffset != -1) ? copyOffset : sizeEnd);
|
|
||||||
|
|
||||||
for (auto source = start, destination = address; source < sourceEnd; source++, destination++)
|
|
||||||
function(source, destination);
|
|
||||||
|
|
||||||
if (copyOffset != -1) {
|
|
||||||
std::memcpy(address + copyOffset, start + copyOffset, (sizeEnd - copyOffset) * sizeof(Type));
|
|
||||||
copyOffset -= sizeEnd;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
std::memcpy(address, start, sizeEnd * sizeof(Type));
|
|
||||||
}
|
|
||||||
|
|
||||||
address += sizeEnd;
|
|
||||||
|
|
||||||
if (sizeBegin) {
|
|
||||||
if (function && copyOffset) {
|
|
||||||
auto sourceEnd = array.begin() + ((copyOffset != -1) ? copyOffset : sizeBegin);
|
|
||||||
|
|
||||||
for (auto source = array.begin(), destination = address; source < sourceEnd; source++, destination++)
|
|
||||||
function(source, destination);
|
|
||||||
|
|
||||||
if (copyOffset != -1)
|
|
||||||
std::memcpy(array.begin() + copyOffset, address + copyOffset, (sizeBegin - copyOffset) * sizeof(Type));
|
|
||||||
} else {
|
|
||||||
std::memcpy(address, array.begin(), sizeBegin * sizeof(Type));
|
|
||||||
}
|
|
||||||
|
|
||||||
start = array.begin() + sizeBegin;
|
|
||||||
} else {
|
|
||||||
start += sizeEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start == end)
|
|
||||||
empty = true;
|
|
||||||
|
|
||||||
return static_cast<size_t>(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This appends data from the specified buffer into this buffer
|
|
||||||
* @param address The address of the buffer
|
|
||||||
* @param size The size of the buffer in units of Type
|
|
||||||
*/
|
|
||||||
inline void Append(Type *address, ssize_t size) {
|
|
||||||
std::lock_guard guard(mtx);
|
|
||||||
|
|
||||||
while (size) {
|
|
||||||
if (start <= end && end != array.end()) {
|
|
||||||
auto sizeEnd = std::min(array.end() - end, size);
|
|
||||||
std::memcpy(end, address, sizeEnd * sizeof(Type));
|
|
||||||
|
|
||||||
address += sizeEnd;
|
|
||||||
size -= sizeEnd;
|
|
||||||
|
|
||||||
end += sizeEnd;
|
|
||||||
} else {
|
|
||||||
auto sizePreStart = (end == array.end()) ? std::min(start - array.begin(), size) : std::min(start - end, size);
|
|
||||||
auto sizePostStart = std::min(array.end() - start, size - sizePreStart);
|
|
||||||
|
|
||||||
if (sizePreStart)
|
|
||||||
std::memcpy((end == array.end()) ? array.begin() : end, address, sizePreStart * sizeof(Type));
|
|
||||||
|
|
||||||
if (end == array.end())
|
|
||||||
end = array.begin() + sizePreStart;
|
|
||||||
else
|
|
||||||
end += sizePreStart;
|
|
||||||
|
|
||||||
address += sizePreStart;
|
|
||||||
size -= sizePreStart;
|
|
||||||
|
|
||||||
if (sizePostStart)
|
|
||||||
std::memcpy(end, address, sizePostStart * sizeof(Type));
|
|
||||||
|
|
||||||
if (start == array.end())
|
|
||||||
start = array.begin() + sizePostStart;
|
|
||||||
else
|
|
||||||
start += sizePostStart;
|
|
||||||
|
|
||||||
if (end == array.end())
|
|
||||||
end = array.begin() + sizePostStart;
|
|
||||||
else
|
|
||||||
end += sizePostStart;
|
|
||||||
|
|
||||||
address += sizePostStart;
|
|
||||||
size -= sizePostStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
empty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This appends data from a vector to the buffer
|
|
||||||
* @param sampleData A reference to a vector containing the data to be appended
|
|
||||||
*/
|
|
||||||
inline void Append(const std::vector<Type> &data) {
|
|
||||||
Append(const_cast<Type *>(data.data()), data.size());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ namespace skyline::audio {
|
|||||||
return bufferIds;
|
return bufferIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioTrack::AppendBuffer(u64 tag, const i16* address, u64 size) {
|
void AudioTrack::AppendBuffer(u64 tag, const i16 *address, u64 size) {
|
||||||
BufferIdentifier identifier;
|
BufferIdentifier identifier;
|
||||||
|
|
||||||
identifier.released = false;
|
identifier.released = false;
|
||||||
|
@ -36,7 +36,7 @@ namespace skyline::audio {
|
|||||||
AudioTrack(const u8 channelCount, const u32 sampleRate, const std::function<void()> &releaseCallback);
|
AudioTrack(const u8 channelCount, const u32 sampleRate, const std::function<void()> &releaseCallback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts audio playback using data from appended buffers.
|
* @brief Starts audio playback using data from appended buffers
|
||||||
*/
|
*/
|
||||||
inline void Start() {
|
inline void Start() {
|
||||||
playbackState = AudioOutState::Started;
|
playbackState = AudioOutState::Started;
|
||||||
@ -67,7 +67,7 @@ namespace skyline::audio {
|
|||||||
* @param address The address of the audio buffer
|
* @param address The address of the audio buffer
|
||||||
* @param size The size of the audio buffer in i16 units
|
* @param size The size of the audio buffer in i16 units
|
||||||
*/
|
*/
|
||||||
void AppendBuffer(u64 tag, const i16* address, u64 size);
|
void AppendBuffer(u64 tag, const i16 *address, u64 size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Appends audio samples to the output buffer
|
* @brief Appends audio samples to the output buffer
|
||||||
|
@ -138,7 +138,7 @@ namespace skyline {
|
|||||||
Type object{};
|
Type object{};
|
||||||
auto offset = 0;
|
auto offset = 0;
|
||||||
|
|
||||||
for(auto& character : string) {
|
for (auto &character : string) {
|
||||||
object |= static_cast<Type>(character) << offset;
|
object |= static_cast<Type>(character) << offset;
|
||||||
offset += sizeof(character) * 8;
|
offset += sizeof(character) * 8;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ namespace skyline::kernel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MemoryManager::InsertBlock(ChunkDescriptor *chunk, const BlockDescriptor block) {
|
void MemoryManager::InsertBlock(ChunkDescriptor *chunk, const BlockDescriptor block) {
|
||||||
if(chunk->address + chunk->size < block.address + block.size)
|
if (chunk->address + chunk->size < block.address + block.size)
|
||||||
throw exception("InsertBlock: Inserting block past chunk end is not allowed");
|
throw exception("InsertBlock: Inserting block past chunk end is not allowed");
|
||||||
|
|
||||||
for (auto iter = chunk->blockList.begin(); iter != chunk->blockList.end(); iter++) {
|
for (auto iter = chunk->blockList.begin(); iter != chunk->blockList.end(); iter++) {
|
||||||
|
@ -280,7 +280,7 @@ namespace skyline {
|
|||||||
* @param address The address to find a block at
|
* @param address The address to find a block at
|
||||||
* @return A pointer to the BlockDescriptor or nullptr in case chunk was not found
|
* @return A pointer to the BlockDescriptor or nullptr in case chunk was not found
|
||||||
*/
|
*/
|
||||||
BlockDescriptor *GetBlock(u64 address, ChunkDescriptor* chunk = nullptr);
|
BlockDescriptor *GetBlock(u64 address, ChunkDescriptor *chunk = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Inserts a chunk into the memory map
|
* @brief Inserts a chunk into the memory map
|
||||||
|
@ -33,24 +33,24 @@ namespace skyline::kernel::svc {
|
|||||||
state.logger->Warn("svcSetMemoryAttribute: 'address' not page aligned: 0x{:X}", address);
|
state.logger->Warn("svcSetMemoryAttribute: 'address' not page aligned: 0x{:X}", address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto size = state.ctx->registers.x1;
|
auto size = state.ctx->registers.x1;
|
||||||
if (!util::PageAligned(size)) {
|
if (!util::PageAligned(size)) {
|
||||||
state.ctx->registers.w0 = constant::status::InvSize;
|
state.ctx->registers.w0 = constant::status::InvSize;
|
||||||
state.logger->Warn("svcSetMemoryAttribute: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
state.logger->Warn("svcSetMemoryAttribute: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory::MemoryAttribute mask{.value = state.ctx->registers.w2};
|
memory::MemoryAttribute mask{.value = state.ctx->registers.w2};
|
||||||
memory::MemoryAttribute value{.value = state.ctx->registers.w3};
|
memory::MemoryAttribute value{.value = state.ctx->registers.w3};
|
||||||
|
|
||||||
auto maskedValue = mask.value | value.value;
|
auto maskedValue = mask.value | value.value;
|
||||||
if (maskedValue != mask.value || !mask.isUncached || mask.isDeviceShared || mask.isBorrowed || mask.isIpcLocked) {
|
if (maskedValue != mask.value || !mask.isUncached || mask.isDeviceShared || mask.isBorrowed || mask.isIpcLocked) {
|
||||||
state.ctx->registers.w0 = constant::status::InvCombination;
|
state.ctx->registers.w0 = constant::status::InvCombination;
|
||||||
state.logger->Warn("svcSetMemoryAttribute: 'mask' invalid: 0x{:X}, 0x{:X}", mask.value, value.value);
|
state.logger->Warn("svcSetMemoryAttribute: 'mask' invalid: 0x{:X}, 0x{:X}", mask.value, value.value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto chunk = state.os->memory.GetChunk(address);
|
auto chunk = state.os->memory.GetChunk(address);
|
||||||
auto block = state.os->memory.GetBlock(address);
|
auto block = state.os->memory.GetBlock(address);
|
||||||
if (!chunk || !block) {
|
if (!chunk || !block) {
|
||||||
@ -58,16 +58,16 @@ namespace skyline::kernel::svc {
|
|||||||
state.logger->Warn("svcSetMemoryAttribute: Cannot find memory region: 0x{:X}", address);
|
state.logger->Warn("svcSetMemoryAttribute: Cannot find memory region: 0x{:X}", address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chunk->state.attributeChangeAllowed) {
|
if (!chunk->state.attributeChangeAllowed) {
|
||||||
state.ctx->registers.w0 = constant::status::InvState;
|
state.ctx->registers.w0 = constant::status::InvState;
|
||||||
state.logger->Warn("svcSetMemoryAttribute: Attribute change not allowed for chunk: 0x{:X}", address);
|
state.logger->Warn("svcSetMemoryAttribute: Attribute change not allowed for chunk: 0x{:X}", address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
block->attributes.isUncached = value.isUncached;
|
block->attributes.isUncached = value.isUncached;
|
||||||
MemoryManager::InsertBlock(chunk, *block);
|
MemoryManager::InsertBlock(chunk, *block);
|
||||||
|
|
||||||
state.logger->Debug("svcSetMemoryAttribute: Set caching to {} at 0x{:X} for 0x{:X} bytes", !block->attributes.isUncached, address, size);
|
state.logger->Debug("svcSetMemoryAttribute: Set caching to {} at 0x{:X} for 0x{:X} bytes", !block->attributes.isUncached, address, size);
|
||||||
state.ctx->registers.w0 = constant::status::Success;
|
state.ctx->registers.w0 = constant::status::Success;
|
||||||
}
|
}
|
||||||
@ -76,19 +76,19 @@ namespace skyline::kernel::svc {
|
|||||||
auto destination = state.ctx->registers.x0;
|
auto destination = state.ctx->registers.x0;
|
||||||
auto source = state.ctx->registers.x1;
|
auto source = state.ctx->registers.x1;
|
||||||
auto size = state.ctx->registers.x2;
|
auto size = state.ctx->registers.x2;
|
||||||
|
|
||||||
if (!util::PageAligned(destination) || !util::PageAligned(source)) {
|
if (!util::PageAligned(destination) || !util::PageAligned(source)) {
|
||||||
state.ctx->registers.w0 = constant::status::InvAddress;
|
state.ctx->registers.w0 = constant::status::InvAddress;
|
||||||
state.logger->Warn("svcMapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
state.logger->Warn("svcMapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!util::PageAligned(size)) {
|
if (!util::PageAligned(size)) {
|
||||||
state.ctx->registers.w0 = constant::status::InvSize;
|
state.ctx->registers.w0 = constant::status::InvSize;
|
||||||
state.logger->Warn("svcMapMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
state.logger->Warn("svcMapMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto stack = state.os->memory.GetRegion(memory::Regions::Stack);
|
auto stack = state.os->memory.GetRegion(memory::Regions::Stack);
|
||||||
if (!stack.IsInside(destination)) {
|
if (!stack.IsInside(destination)) {
|
||||||
state.ctx->registers.w0 = constant::status::InvMemRange;
|
state.ctx->registers.w0 = constant::status::InvMemRange;
|
||||||
|
@ -282,7 +282,7 @@ namespace skyline {
|
|||||||
HandleOut<objectClass> NewHandle(objectArgs... args) {
|
HandleOut<objectClass> NewHandle(objectArgs... args) {
|
||||||
std::shared_ptr<objectClass> item;
|
std::shared_ptr<objectClass> item;
|
||||||
if constexpr (std::is_same<objectClass, KThread>())
|
if constexpr (std::is_same<objectClass, KThread>())
|
||||||
item = std::make_shared<objectClass>(state, handleIndex, args...);
|
item = std::make_shared<objectClass>(state, handleIndex, args...);
|
||||||
else
|
else
|
||||||
item = std::make_shared<objectClass>(state, args...);
|
item = std::make_shared<objectClass>(state, args...);
|
||||||
handles[handleIndex] = std::static_pointer_cast<KObject>(item);
|
handles[handleIndex] = std::static_pointer_cast<KObject>(item);
|
||||||
@ -310,19 +310,19 @@ namespace skyline {
|
|||||||
std::shared_ptr<objectClass> GetHandle(KHandle handle) {
|
std::shared_ptr<objectClass> GetHandle(KHandle handle) {
|
||||||
KType objectType;
|
KType objectType;
|
||||||
if constexpr(std::is_same<objectClass, KThread>())
|
if constexpr(std::is_same<objectClass, KThread>())
|
||||||
objectType = KType::KThread;
|
objectType = KType::KThread;
|
||||||
else if constexpr(std::is_same<objectClass, KProcess>())
|
else if constexpr(std::is_same<objectClass, KProcess>())
|
||||||
objectType = KType::KProcess;
|
objectType = KType::KProcess;
|
||||||
else if constexpr(std::is_same<objectClass, KSharedMemory>())
|
else if constexpr(std::is_same<objectClass, KSharedMemory>())
|
||||||
objectType = KType::KSharedMemory;
|
objectType = KType::KSharedMemory;
|
||||||
else if constexpr(std::is_same<objectClass, KTransferMemory>())
|
else if constexpr(std::is_same<objectClass, KTransferMemory>())
|
||||||
objectType = KType::KTransferMemory;
|
objectType = KType::KTransferMemory;
|
||||||
else if constexpr(std::is_same<objectClass, KPrivateMemory>())
|
else if constexpr(std::is_same<objectClass, KPrivateMemory>())
|
||||||
objectType = KType::KPrivateMemory;
|
objectType = KType::KPrivateMemory;
|
||||||
else if constexpr(std::is_same<objectClass, KSession>())
|
else if constexpr(std::is_same<objectClass, KSession>())
|
||||||
objectType = KType::KSession;
|
objectType = KType::KSession;
|
||||||
else if constexpr(std::is_same<objectClass, KEvent>())
|
else if constexpr(std::is_same<objectClass, KEvent>())
|
||||||
objectType = KType::KEvent;
|
objectType = KType::KEvent;
|
||||||
else
|
else
|
||||||
throw exception("KProcess::GetHandle couldn't determine object type");
|
throw exception("KProcess::GetHandle couldn't determine object type");
|
||||||
try {
|
try {
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
#include "KProcess.h"
|
#include "KProcess.h"
|
||||||
|
|
||||||
namespace skyline::kernel::type {
|
namespace skyline::kernel::type {
|
||||||
KThread::KThread(const DeviceState &state, KHandle handle, pid_t selfPid, u64 entryPoint, u64 entryArg, u64 stackTop, u64 tls, u8 priority, KProcess *parent, std::shared_ptr<type::KSharedMemory> &tlsMemory) : handle(handle), pid(selfPid), entryPoint(entryPoint), entryArg(entryArg), stackTop(stackTop), tls(tls), priority(priority), parent(parent), ctxMemory(tlsMemory), KSyncObject(state, KType::KThread) {
|
KThread::KThread(const DeviceState &state, KHandle handle, pid_t selfPid, u64 entryPoint, u64 entryArg, u64 stackTop, u64 tls, u8 priority, KProcess *parent, std::shared_ptr<type::KSharedMemory> &tlsMemory)
|
||||||
|
: handle(handle), pid(selfPid), entryPoint(entryPoint), entryArg(entryArg), stackTop(stackTop), tls(tls), priority(priority), parent(parent), ctxMemory(tlsMemory), KSyncObject(state, KType::KThread) {
|
||||||
UpdatePriority(priority);
|
UpdatePriority(priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,7 +35,8 @@ namespace skyline::kernel::type {
|
|||||||
|
|
||||||
void KThread::UpdatePriority(u8 priority) {
|
void KThread::UpdatePriority(u8 priority) {
|
||||||
this->priority = priority;
|
this->priority = priority;
|
||||||
auto linuxPriority = static_cast<int8_t>(constant::AndroidPriority.first + ((static_cast<float>(constant::AndroidPriority.second - constant::AndroidPriority.first) / static_cast<float>(constant::SwitchPriority.second - constant::SwitchPriority.first)) * (static_cast<float>(priority) - constant::SwitchPriority.first))); // Resize range SwitchPriority (Nintendo Priority) to AndroidPriority (Android Priority)
|
auto linuxPriority =
|
||||||
|
static_cast<int8_t>(constant::AndroidPriority.first + ((static_cast<float>(constant::AndroidPriority.second - constant::AndroidPriority.first) / static_cast<float>(constant::SwitchPriority.second - constant::SwitchPriority.first)) * (static_cast<float>(priority) - constant::SwitchPriority.first))); // Resize range SwitchPriority (Nintendo Priority) to AndroidPriority (Android Priority)
|
||||||
|
|
||||||
if (setpriority(PRIO_PROCESS, static_cast<id_t>(pid), linuxPriority) == -1)
|
if (setpriority(PRIO_PROCESS, static_cast<id_t>(pid), linuxPriority) == -1)
|
||||||
throw exception("Couldn't set process priority to {} for PID: {}", linuxPriority, pid);
|
throw exception("Couldn't set process priority to {} for PID: {}", linuxPriority, pid);
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <services/am/controller/IAppletCommonFunctions.h>
|
#include <services/am/controller/IAppletCommonFunctions.h>
|
||||||
#include "base_proxy.h"
|
#include "base_proxy.h"
|
||||||
|
|
||||||
|
|
||||||
namespace skyline::service::am {
|
namespace skyline::service::am {
|
||||||
BaseProxy::BaseProxy(const DeviceState &state, ServiceManager &manager, const Service serviceType, const std::string &serviceName, const std::unordered_map<u32, std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> &vTable) : BaseService(state, manager, serviceType, serviceName, vTable) {}
|
BaseProxy::BaseProxy(const DeviceState &state, ServiceManager &manager, const Service serviceType, const std::string &serviceName, const std::unordered_map<u32, std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> &vTable) : BaseService(state, manager, serviceType, serviceName, vTable) {}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ namespace skyline::service::am {
|
|||||||
*/
|
*/
|
||||||
class BaseProxy : public BaseService {
|
class BaseProxy : public BaseService {
|
||||||
public:
|
public:
|
||||||
BaseProxy(const DeviceState &state, ServiceManager &manager, const Service serviceType, const std::string &serviceName, const std::unordered_map<u32, std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> &vTable);
|
BaseProxy(const DeviceState &state, ServiceManager &manager, const Service serviceType, const std::string &serviceName, const std::unordered_map<u32, std::function<void(type::KSession & , ipc::IpcRequest & , ipc::IpcResponse & )>> &vTable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This returns #ICommonStateGetter (https://switchbrew.org/wiki/Applet_Manager_services#ICommonStateGetter)
|
* @brief This returns #ICommonStateGetter (https://switchbrew.org/wiki/Applet_Manager_services#ICommonStateGetter)
|
||||||
|
@ -47,7 +47,7 @@ namespace skyline::service::audio {
|
|||||||
|
|
||||||
state.logger->Debug("IAudioOut: Appending buffer with address: 0x{:X}, size: 0x{:X}", data.sampleBufferPtr, data.sampleSize);
|
state.logger->Debug("IAudioOut: Appending buffer with address: 0x{:X}, size: 0x{:X}", data.sampleBufferPtr, data.sampleSize);
|
||||||
|
|
||||||
if(sampleRate != constant::SampleRate) {
|
if (sampleRate != constant::SampleRate) {
|
||||||
tmpSampleBuffer.resize(data.sampleSize / sizeof(i16));
|
tmpSampleBuffer.resize(data.sampleSize / sizeof(i16));
|
||||||
state.process->ReadMemory(tmpSampleBuffer.data(), data.sampleBufferPtr, data.sampleSize);
|
state.process->ReadMemory(tmpSampleBuffer.data(), data.sampleBufferPtr, data.sampleSize);
|
||||||
resampler.ResampleBuffer(tmpSampleBuffer, static_cast<double>(sampleRate) / constant::SampleRate, channelCount);
|
resampler.ResampleBuffer(tmpSampleBuffer, static_cast<double>(sampleRate) / constant::SampleRate, channelCount);
|
||||||
|
@ -89,9 +89,9 @@ namespace skyline::service::hid {
|
|||||||
JoyConDevice(const NpadId &id) : id(id) {}
|
JoyConDevice(const NpadId &id) : id(id) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr <IAppletResource> resource{}; //!< A shared pointer to the applet resource
|
std::shared_ptr<IAppletResource> resource{}; //!< A shared pointer to the applet resource
|
||||||
std::optional <StyleSet> styleSet; //!< The controller styles supported by the application
|
std::optional<StyleSet> styleSet; //!< The controller styles supported by the application
|
||||||
std::unordered_map <NpadId, JoyConDevice> deviceMap; //!< Mapping from a controller's ID to it's corresponding JoyConDevice
|
std::unordered_map<NpadId, JoyConDevice> deviceMap; //!< Mapping from a controller's ID to it's corresponding JoyConDevice
|
||||||
JoyConOrientation orientation{JoyConOrientation::Unset}; //!< The Orientation of the Joy-Con(s)
|
JoyConOrientation orientation{JoyConOrientation::Unset}; //!< The Orientation of the Joy-Con(s)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -20,7 +20,7 @@ namespace skyline::service::hosbinder {
|
|||||||
/**
|
/**
|
||||||
* @brief A mapping from a display's name to it's displayType entry
|
* @brief A mapping from a display's name to it's displayType entry
|
||||||
*/
|
*/
|
||||||
static const std::unordered_map <std::string, DisplayId> DisplayTypeMap{
|
static const std::unordered_map<std::string, DisplayId> DisplayTypeMap{
|
||||||
{"Default", DisplayId::Default},
|
{"Default", DisplayId::Default},
|
||||||
{"External", DisplayId::External},
|
{"External", DisplayId::External},
|
||||||
{"Edid", DisplayId::Edid},
|
{"Edid", DisplayId::Edid},
|
||||||
|
@ -105,7 +105,7 @@ namespace skyline::service {
|
|||||||
handle = state.process->NewHandle<type::KSession>(serviceObject).handle;
|
handle = state.process->NewHandle<type::KSession>(serviceObject).handle;
|
||||||
response.moveHandles.push_back(handle);
|
response.moveHandles.push_back(handle);
|
||||||
}
|
}
|
||||||
if(!submodule)
|
if (!submodule)
|
||||||
serviceMap[serviceObject->serviceType] = serviceObject;
|
serviceMap[serviceObject->serviceType] = serviceObject;
|
||||||
state.logger->Debug("Service has been registered: \"{}\" (0x{:X})", serviceObject->serviceName, handle);
|
state.logger->Debug("Service has been registered: \"{}\" (0x{:X})", serviceObject->serviceName, handle);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ namespace skyline::service {
|
|||||||
private:
|
private:
|
||||||
const DeviceState &state; //!< The state of the device
|
const DeviceState &state; //!< The state of the device
|
||||||
std::unordered_map<Service, std::shared_ptr<BaseService>> serviceMap; //!< A mapping from a Service to the underlying object
|
std::unordered_map<Service, std::shared_ptr<BaseService>> serviceMap; //!< A mapping from a Service to the underlying object
|
||||||
skyline::Mutex mutex; //!< This mutex is used to ensure concurrent access to services doesn't cause crashes
|
Mutex mutex; //!< This mutex is used to ensure concurrent access to services doesn't cause crashes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates an instance of the service if it doesn't already exist, otherwise returns an existing instance
|
* @brief Creates an instance of the service if it doesn't already exist, otherwise returns an existing instance
|
||||||
|
@ -27,7 +27,7 @@ namespace skyline::service::visrv {
|
|||||||
static_assert(sizeof(LayerParcel) == 0x28);
|
static_assert(sizeof(LayerParcel) == 0x28);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IDisplayService(const DeviceState &state, ServiceManager &manager, const Service serviceType, const std::string &serviceName, const std::unordered_map <u32, std::function<void(type::KSession & , ipc::IpcRequest & , ipc::IpcResponse & )>> &vTable);
|
IDisplayService(const DeviceState &state, ServiceManager &manager, const Service serviceType, const std::string &serviceName, const std::unordered_map<u32, std::function<void(type::KSession & , ipc::IpcRequest & , ipc::IpcResponse & )>> &vTable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This creates a stray layer using a display's ID and returns a layer ID and the corresponding buffer ID
|
* @brief This creates a stray layer using a display's ID and returns a layer ID and the corresponding buffer ID
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="?attr/colorOnSecondary"
|
android:fillColor="?attr/colorOnSecondary"
|
||||||
android:pathData="M10,16.5l6,-4.5 -6,-4.5v9zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
|
android:pathData="M10,16.5l6,-4.5 -6,-4.5v9zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z" />
|
||||||
</vector>
|
</vector>
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include layout="@layout/titlebar"/>
|
<include layout="@layout/titlebar" />
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/settings"
|
android:id="@+id/settings"
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
style="@style/Widget.MaterialComponents.Toolbar.Primary"
|
style="@style/Widget.MaterialComponents.Toolbar.Primary"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
app:layout_scrollFlags="scroll|enterAlways|snap"
|
android:theme="@style/AppTheme.ActionBar"
|
||||||
android:theme="@style/AppTheme.ActionBar" />
|
app:layout_scrollFlags="scroll|enterAlways|snap" />
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryVariant">@color/colorPrimaryDark</item>
|
<item name="colorPrimaryVariant">@color/colorPrimaryDark</item>
|
||||||
@ -7,10 +8,12 @@
|
|||||||
<item name="colorSecondaryVariant">@color/colorSecondaryDark</item>
|
<item name="colorSecondaryVariant">@color/colorSecondaryDark</item>
|
||||||
<item name="colorOnSecondary">@color/colorOnSecondary</item>
|
<item name="colorOnSecondary">@color/colorOnSecondary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme.ActionBar" parent="">
|
<style name="AppTheme.ActionBar" parent="">
|
||||||
<item name="android:textColorPrimary">@color/colorOnPrimary</item>
|
<item name="android:textColorPrimary">@color/colorOnPrimary</item>
|
||||||
<item name="android:textColorSecondary">@color/colorOnPrimary</item>
|
<item name="android:textColorSecondary">@color/colorOnPrimary</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="roundedAppImage" parent="">
|
<style name="roundedAppImage" parent="">
|
||||||
<item name="cornerFamily">rounded</item>
|
<item name="cornerFamily">rounded</item>
|
||||||
<item name="cornerSize">6dp</item>
|
<item name="cornerSize">6dp</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user