mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 18:31:50 +01:00
Improve Shared Fonts + Fix AM PopLaunchParameter
& Choreographer Bug
* Move Shared Font TTFs to AAsset storage + Support external shared font loading from `/data/data/skyline.emu/data/fonts` * Fix bug in `IApplicationFunctions::PopLaunchParameter` caused by ignoring `LaunchParameterKind` * Fix bug with Choreographer causing it to be awoken and exit prior to the destruction of `PresentationEngine` * Fix bug with `IDirectory::Read` where it used `inputBuf` for the output buffer rather than `outputBuf` * Improve `GetFunctionStackTrace` logs when `dli_sname` or `dli_fname` are missing * Support more RT Formats
This commit is contained in:
parent
95a08627e5
commit
f8acc1e131
@ -50,6 +50,15 @@ android {
|
|||||||
debuggable true
|
debuggable true
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
shrinkResources false
|
shrinkResources false
|
||||||
|
|
||||||
|
/* Vulkan Validation Layers */
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
jniLibs {
|
||||||
|
srcDir "$buildDir/generated/vulkan_layers"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
@ -71,17 +80,6 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vulkan Validation Layers */
|
|
||||||
sourceSets {
|
|
||||||
debug {
|
|
||||||
main {
|
|
||||||
jniLibs {
|
|
||||||
srcDir "$buildDir/generated/vulkan_layers"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Android Assets */
|
/* Android Assets */
|
||||||
aaptOptions {
|
aaptOptions {
|
||||||
ignoreAssetsPattern "*.md"
|
ignoreAssetsPattern "*.md"
|
||||||
|
BIN
app/src/main/assets/fonts/FontChineseSimplified.ttf
Normal file
BIN
app/src/main/assets/fonts/FontChineseSimplified.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/fonts/FontChineseTraditional.ttf
Normal file
BIN
app/src/main/assets/fonts/FontChineseTraditional.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/fonts/FontExtendedChineseSimplified.ttf
Normal file
BIN
app/src/main/assets/fonts/FontExtendedChineseSimplified.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/fonts/FontKorean.ttf
Normal file
BIN
app/src/main/assets/fonts/FontKorean.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/fonts/FontNintendoExtended.ttf
Normal file
BIN
app/src/main/assets/fonts/FontNintendoExtended.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/fonts/FontStandard.ttf
Normal file
BIN
app/src/main/assets/fonts/FontStandard.ttf
Normal file
Binary file not shown.
4
app/src/main/assets/fonts/README.md
Normal file
4
app/src/main/assets/fonts/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#### Skyline FOSS Shared Fonts: (Credit to [FearlessTobi/yuzu_system_archives](https://github.com/FearlessTobi/yuzu_system_archives) for font choice)
|
||||||
|
* [FontStandard](FontStandard.ttf), [FontKorean](FontKorean.ttf), [FontChineseSimplified](FontChineseSimplified.ttf) and [FontChineseTraditional](FontChineseTraditional.ttf) are using [Open Sans Regular](https://fonts.google.com/specimen/Open+Sans), which is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
* [FontNintendoExtended](FontNintendoExtended.ttf) is using [Roboto](https://fonts.google.com/specimen/Roboto), which is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
* [FontExtendedChineseSimplified](FontExtendedChineseSimplified.ttf) is using [Source Sans Pro](https://fonts.google.com/specimen/Source+Sans+Pro), which is licensed under [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL)
|
@ -425,9 +425,9 @@ namespace skyline {
|
|||||||
return std::string_view(reinterpret_cast<const char *>(span::data()), nullTerminated ? (std::find(span::begin(), span::end(), 0) - span::begin()) : span::size_bytes());
|
return std::string_view(reinterpret_cast<const char *>(span::data()), nullTerminated ? (std::find(span::begin(), span::end(), 0) - span::begin()) : span::size_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Out, size_t OutExtent = std::dynamic_extent>
|
template<typename Out, size_t OutExtent = std::dynamic_extent, bool SkipAlignmentCheck = false>
|
||||||
constexpr span<Out> cast() {
|
constexpr span<Out> cast() {
|
||||||
if (util::IsAligned(span::size_bytes(), sizeof(Out)))
|
if (SkipAlignmentCheck || util::IsAligned(span::size_bytes(), sizeof(Out)))
|
||||||
return span<Out, OutExtent>(reinterpret_cast<Out *>(span::data()), span::size_bytes() / sizeof(Out));
|
return span<Out, OutExtent>(reinterpret_cast<Out *>(span::data()), span::size_bytes() / sizeof(Out));
|
||||||
throw exception("Span size not aligned with Out type size (0x{:X}/0x{:X})", span::size_bytes(), sizeof(Out));
|
throw exception("Span size not aligned with Out type size (0x{:X}/0x{:X})", span::size_bytes(), sizeof(Out));
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
nodes.emplace_back(std::in_place_type_t<node::NextSubpassNode>(), function);
|
nodes.emplace_back(std::in_place_type_t<node::NextSubpassNode>(), function);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandExecutor::AddClearSubpass(TextureView attachment, const vk::ClearColorValue &value) {
|
void CommandExecutor::AddClearColorSubpass(TextureView attachment, const vk::ClearColorValue &value) {
|
||||||
bool newRenderpass{CreateRenderpass(vk::Rect2D{
|
bool newRenderpass{CreateRenderpass(vk::Rect2D{
|
||||||
.extent = attachment.backing->dimensions,
|
.extent = attachment.backing->dimensions,
|
||||||
})};
|
})};
|
||||||
|
@ -35,7 +35,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
* @brief Adds a subpass that clears the entirety of the specified attachment with a value, it may utilize VK_ATTACHMENT_LOAD_OP_CLEAR for a more efficient clear when possible
|
* @brief Adds a subpass that clears the entirety of the specified attachment with a value, it may utilize VK_ATTACHMENT_LOAD_OP_CLEAR for a more efficient clear when possible
|
||||||
* @note Any texture supplied to this **must** be locked by the calling thread, it should also undergo no persistent layout transitions till execution
|
* @note Any texture supplied to this **must** be locked by the calling thread, it should also undergo no persistent layout transitions till execution
|
||||||
*/
|
*/
|
||||||
void AddClearSubpass(TextureView attachment, const vk::ClearColorValue& value);
|
void AddClearColorSubpass(TextureView attachment, const vk::ClearColorValue& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute all the nodes and submit the resulting command buffer to the GPU
|
* @brief Execute all the nodes and submit the resulting command buffer to the GPU
|
||||||
|
@ -22,7 +22,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
gpu::interconnect::CommandExecutor &executor;
|
gpu::interconnect::CommandExecutor &executor;
|
||||||
|
|
||||||
struct RenderTarget {
|
struct RenderTarget {
|
||||||
bool disabled{}; //!< If this RT has been disabled and will be an unbound attachment instead
|
bool disabled{true}; //!< If this RT has been disabled and will be an unbound attachment instead
|
||||||
union {
|
union {
|
||||||
u64 gpuAddress;
|
u64 gpuAddress;
|
||||||
struct {
|
struct {
|
||||||
@ -90,6 +90,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
return {};
|
return {};
|
||||||
case maxwell3d::RenderTarget::ColorFormat::R32B32G32A32Float:
|
case maxwell3d::RenderTarget::ColorFormat::R32B32G32A32Float:
|
||||||
return format::R32B32G32A32Float;
|
return format::R32B32G32A32Float;
|
||||||
|
case maxwell3d::RenderTarget::ColorFormat::R16G16B16A16Unorm:
|
||||||
|
return format::R16G16B16A16Unorm;
|
||||||
|
case maxwell3d::RenderTarget::ColorFormat::R16G16B16A16Uint:
|
||||||
|
return format::R16G16B16A16Uint;
|
||||||
case maxwell3d::RenderTarget::ColorFormat::R16G16B16A16Float:
|
case maxwell3d::RenderTarget::ColorFormat::R16G16B16A16Float:
|
||||||
return format::R16G16B16A16Float;
|
return format::R16G16B16A16Float;
|
||||||
case maxwell3d::RenderTarget::ColorFormat::A2B10G10R10Unorm:
|
case maxwell3d::RenderTarget::ColorFormat::A2B10G10R10Unorm:
|
||||||
@ -98,6 +102,8 @@ namespace skyline::gpu::interconnect {
|
|||||||
return format::R8G8B8A8Unorm;
|
return format::R8G8B8A8Unorm;
|
||||||
case maxwell3d::RenderTarget::ColorFormat::A8B8G8R8Srgb:
|
case maxwell3d::RenderTarget::ColorFormat::A8B8G8R8Srgb:
|
||||||
return format::A8B8G8R8Srgb;
|
return format::A8B8G8R8Srgb;
|
||||||
|
case maxwell3d::RenderTarget::ColorFormat::A8B8G8R8Snorm:
|
||||||
|
return format::A8B8G8R8Snorm;
|
||||||
case maxwell3d::RenderTarget::ColorFormat::R16G16Snorm:
|
case maxwell3d::RenderTarget::ColorFormat::R16G16Snorm:
|
||||||
return format::R16G16Snorm;
|
return format::R16G16Snorm;
|
||||||
case maxwell3d::RenderTarget::ColorFormat::R16G16Float:
|
case maxwell3d::RenderTarget::ColorFormat::R16G16Float:
|
||||||
@ -106,8 +112,12 @@ namespace skyline::gpu::interconnect {
|
|||||||
return format::B10G11R11Float;
|
return format::B10G11R11Float;
|
||||||
case maxwell3d::RenderTarget::ColorFormat::R32Float:
|
case maxwell3d::RenderTarget::ColorFormat::R32Float:
|
||||||
return format::R32Float;
|
return format::R32Float;
|
||||||
|
case maxwell3d::RenderTarget::ColorFormat::R8G8Unorm:
|
||||||
|
return format::R8G8Unorm;
|
||||||
case maxwell3d::RenderTarget::ColorFormat::R8G8Snorm:
|
case maxwell3d::RenderTarget::ColorFormat::R8G8Snorm:
|
||||||
return format::R8G8Snorm;
|
return format::R8G8Snorm;
|
||||||
|
case maxwell3d::RenderTarget::ColorFormat::R16Unorm:
|
||||||
|
return format::R16Unorm;
|
||||||
case maxwell3d::RenderTarget::ColorFormat::R16Float:
|
case maxwell3d::RenderTarget::ColorFormat::R16Float:
|
||||||
return format::R16Float;
|
return format::R16Float;
|
||||||
case maxwell3d::RenderTarget::ColorFormat::R8Unorm:
|
case maxwell3d::RenderTarget::ColorFormat::R8Unorm:
|
||||||
@ -234,8 +244,8 @@ namespace skyline::gpu::interconnect {
|
|||||||
if (scissor.extent.width == 0 || scissor.extent.height == 0)
|
if (scissor.extent.width == 0 || scissor.extent.height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (scissor.extent.width == renderTarget.backing->dimensions.width && scissor.extent.width == renderTarget.backing->dimensions.width && renderTarget.range.baseArrayLayer == 0 && renderTarget.range.layerCount == 1 && clear.layerId == 0) {
|
if (scissor.extent.width == renderTarget.backing->dimensions.width && scissor.extent.height == renderTarget.backing->dimensions.height && renderTarget.range.baseArrayLayer == 0 && renderTarget.range.layerCount == 1 && clear.layerId == 0) {
|
||||||
executor.AddClearSubpass(renderTarget, clearColorValue);
|
executor.AddClearColorSubpass(renderTarget, clearColorValue);
|
||||||
} else {
|
} else {
|
||||||
executor.AddSubpass([aspect, clearColorValue = clearColorValue, layerId = clear.layerId, scissor](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &) {
|
executor.AddSubpass([aspect, clearColorValue = clearColorValue, layerId = clear.layerId, scissor](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &) {
|
||||||
commandBuffer.clearAttachments(vk::ClearAttachment{
|
commandBuffer.clearAttachments(vk::ClearAttachment{
|
||||||
|
@ -32,8 +32,10 @@ namespace skyline::gpu {
|
|||||||
env->DeleteGlobalRef(jSurface);
|
env->DeleteGlobalRef(jSurface);
|
||||||
|
|
||||||
if (choreographerThread.joinable()) {
|
if (choreographerThread.joinable()) {
|
||||||
if (choreographerLooper)
|
if (choreographerLooper) {
|
||||||
|
choreographerStop = true;
|
||||||
ALooper_wake(choreographerLooper);
|
ALooper_wake(choreographerLooper);
|
||||||
|
}
|
||||||
choreographerThread.join();
|
choreographerThread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +64,7 @@ namespace skyline::gpu {
|
|||||||
signal::SetSignalHandler({SIGINT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV}, signal::ExceptionalSignalHandler);
|
signal::SetSignalHandler({SIGINT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV}, signal::ExceptionalSignalHandler);
|
||||||
choreographerLooper = ALooper_prepare(0);
|
choreographerLooper = ALooper_prepare(0);
|
||||||
AChoreographer_postFrameCallback64(AChoreographer_getInstance(), reinterpret_cast<AChoreographer_frameCallback64>(&ChoreographerCallback), this);
|
AChoreographer_postFrameCallback64(AChoreographer_getInstance(), reinterpret_cast<AChoreographer_frameCallback64>(&ChoreographerCallback), this);
|
||||||
ALooper_pollAll(-1, nullptr, nullptr, nullptr); // Will block and process callbacks till ALooper_wake() is called
|
while (ALooper_pollAll(-1, nullptr, nullptr, nullptr) == ALOOPER_POLL_WAKE && !choreographerStop); // Will block and process callbacks till ALooper_wake() is called with choreographerStop set
|
||||||
} catch (const signal::SignalException &e) {
|
} catch (const signal::SignalException &e) {
|
||||||
state.logger->Error("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames));
|
state.logger->Error("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames));
|
||||||
if (state.process)
|
if (state.process)
|
||||||
@ -275,8 +277,7 @@ namespace skyline::gpu {
|
|||||||
// We need to nullify the timestamp if it transitioned from being specified (non-zero) to unspecified (zero)
|
// We need to nullify the timestamp if it transitioned from being specified (non-zero) to unspecified (zero)
|
||||||
timestamp = NativeWindowTimestampAuto;
|
timestamp = NativeWindowTimestampAuto;
|
||||||
|
|
||||||
if (timestamp)
|
if (timestamp && (result = window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP, timestamp)))
|
||||||
if (window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP, timestamp))
|
|
||||||
throw exception("Setting the buffer timestamp to {} failed with {}", timestamp, result);
|
throw exception("Setting the buffer timestamp to {} failed with {}", timestamp, result);
|
||||||
|
|
||||||
if ((result = window->perform(window, NATIVE_WINDOW_GET_NEXT_FRAME_ID, &frameId)))
|
if ((result = window->perform(window, NATIVE_WINDOW_GET_NEXT_FRAME_ID, &frameId)))
|
||||||
|
@ -49,6 +49,7 @@ namespace skyline::gpu {
|
|||||||
ALooper *choreographerLooper{};
|
ALooper *choreographerLooper{};
|
||||||
i64 lastChoreographerTime{}; //!< The timestamp of the last invocation of Choreographer::doFrame
|
i64 lastChoreographerTime{}; //!< The timestamp of the last invocation of Choreographer::doFrame
|
||||||
i64 refreshCycleDuration{}; //!< The duration of a single refresh cycle for the display in nanoseconds
|
i64 refreshCycleDuration{}; //!< The duration of a single refresh cycle for the display in nanoseconds
|
||||||
|
bool choreographerStop{}; //!< If the Choreographer thread should stop on the next ALooper_wake()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @url https://developer.android.com/ndk/reference/group/choreographer#achoreographer_postframecallback64
|
* @url https://developer.android.com/ndk/reference/group/choreographer#achoreographer_postframecallback64
|
||||||
|
@ -15,17 +15,22 @@ namespace skyline::gpu::format {
|
|||||||
constexpr Format R5G6B5Unorm{sizeof(u16), vkf::eR5G6B5UnormPack16};
|
constexpr Format R5G6B5Unorm{sizeof(u16), vkf::eR5G6B5UnormPack16};
|
||||||
constexpr Format A2B10G10R10Unorm{sizeof(u32), vkf::eA2B10G10R10UnormPack32};
|
constexpr Format A2B10G10R10Unorm{sizeof(u32), vkf::eA2B10G10R10UnormPack32};
|
||||||
constexpr Format A8B8G8R8Srgb{sizeof(u32), vkf::eA8B8G8R8SrgbPack32};
|
constexpr Format A8B8G8R8Srgb{sizeof(u32), vkf::eA8B8G8R8SrgbPack32};
|
||||||
|
constexpr Format A8B8G8R8Snorm{sizeof(u32), vkf::eA8B8G8R8SnormPack32};
|
||||||
constexpr Format R16G16Snorm{sizeof(u32), vkf::eR16G16Snorm};
|
constexpr Format R16G16Snorm{sizeof(u32), vkf::eR16G16Snorm};
|
||||||
constexpr Format R16G16Float{sizeof(u32), vkf::eR16G16Sfloat};
|
constexpr Format R16G16Float{sizeof(u32), vkf::eR16G16Sfloat};
|
||||||
constexpr Format B10G11R11Float{sizeof(u32), vkf::eB10G11R11UfloatPack32};
|
constexpr Format B10G11R11Float{sizeof(u32), vkf::eB10G11R11UfloatPack32};
|
||||||
constexpr Format R32Float{sizeof(u32), vkf::eR32Sfloat};
|
constexpr Format R32Float{sizeof(u32), vkf::eR32Sfloat};
|
||||||
|
constexpr Format R8G8Unorm{sizeof(u16), vkf::eR8G8Unorm};
|
||||||
constexpr Format R8G8Snorm{sizeof(u16), vkf::eR8G8Snorm};
|
constexpr Format R8G8Snorm{sizeof(u16), vkf::eR8G8Snorm};
|
||||||
|
constexpr Format R16Unorm{sizeof(u16), vkf::eR16Unorm};
|
||||||
constexpr Format R16Float{sizeof(u16), vkf::eR16Sfloat};
|
constexpr Format R16Float{sizeof(u16), vkf::eR16Sfloat};
|
||||||
constexpr Format R8Unorm{sizeof(u8), vkf::eR8Unorm};
|
constexpr Format R8Unorm{sizeof(u8), vkf::eR8Unorm};
|
||||||
constexpr Format R32B32G32A32Float{sizeof(u32) * 4, vkf::eR32G32B32A32Sfloat, .swizzle = {
|
constexpr Format R32B32G32A32Float{sizeof(u32) * 4, vkf::eR32G32B32A32Sfloat, .swizzle = {
|
||||||
.blue = swc::Green,
|
.blue = swc::Green,
|
||||||
.green = swc::Blue,
|
.green = swc::Blue,
|
||||||
}};
|
}};
|
||||||
|
constexpr Format R16G16B16A16Unorm{sizeof(u16) * 4, vkf::eR16G16B16A16Unorm};
|
||||||
|
constexpr Format R16G16B16A16Uint{sizeof(u16) * 4, vkf::eR16G16B16A16Uint};
|
||||||
constexpr Format R16G16B16A16Float{sizeof(u16) * 4, vkf::eR16G16B16A16Sfloat};
|
constexpr Format R16G16B16A16Float{sizeof(u16) * 4, vkf::eR16G16B16A16Sfloat};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,6 +46,8 @@ namespace skyline::gpu::format {
|
|||||||
return A2B10G10R10Unorm;
|
return A2B10G10R10Unorm;
|
||||||
case vk::Format::eA8B8G8R8SrgbPack32:
|
case vk::Format::eA8B8G8R8SrgbPack32:
|
||||||
return A8B8G8R8Srgb;
|
return A8B8G8R8Srgb;
|
||||||
|
case vk::Format::eA8B8G8R8SnormPack32:
|
||||||
|
return A8B8G8R8Snorm;
|
||||||
case vk::Format::eR16G16Snorm:
|
case vk::Format::eR16G16Snorm:
|
||||||
return R16G16Snorm;
|
return R16G16Snorm;
|
||||||
case vk::Format::eR16G16Sfloat:
|
case vk::Format::eR16G16Sfloat:
|
||||||
@ -49,12 +56,20 @@ namespace skyline::gpu::format {
|
|||||||
return B10G11R11Float;
|
return B10G11R11Float;
|
||||||
case vk::Format::eR32Sfloat:
|
case vk::Format::eR32Sfloat:
|
||||||
return format::R32Float;
|
return format::R32Float;
|
||||||
|
case vk::Format::eR16Unorm:
|
||||||
|
return R16Unorm;
|
||||||
case vk::Format::eR16Sfloat:
|
case vk::Format::eR16Sfloat:
|
||||||
return R16Float;
|
return R16Float;
|
||||||
|
case vk::Format::eR8G8Unorm:
|
||||||
|
return R8G8Unorm;
|
||||||
case vk::Format::eR8G8Snorm:
|
case vk::Format::eR8G8Snorm:
|
||||||
return R8G8Snorm;
|
return R8G8Snorm;
|
||||||
case vk::Format::eR8Unorm:
|
case vk::Format::eR8Unorm:
|
||||||
return R8Unorm;
|
return R8Unorm;
|
||||||
|
case vk::Format::eR16G16B16A16Unorm:
|
||||||
|
return R16G16B16A16Unorm;
|
||||||
|
case vk::Format::eR16G16B16A16Uint:
|
||||||
|
return R16G16B16A16Uint;
|
||||||
case vk::Format::eR16G16B16A16Sfloat:
|
case vk::Format::eR16G16B16A16Sfloat:
|
||||||
return R16G16B16A16Float;
|
return R16G16B16A16Float;
|
||||||
default:
|
default:
|
||||||
|
@ -71,11 +71,9 @@ namespace skyline::gpu {
|
|||||||
textures.emplace(mappingEnd, TextureMapping{texture, it, guestMapping});
|
textures.emplace(mappingEnd, TextureMapping{texture, it, guestMapping});
|
||||||
while ((++it) != texture->guest->mappings.end()) {
|
while ((++it) != texture->guest->mappings.end()) {
|
||||||
guestMapping = *it;
|
guestMapping = *it;
|
||||||
mappingEnd = hostMapping = std::upper_bound(textures.begin(), textures.end(), guestMapping);
|
auto mapping{std::upper_bound(textures.begin(), textures.end(), guestMapping)};
|
||||||
while (hostMapping != textures.begin() && std::prev(hostMapping)->end() > guestMapping.begin()) {
|
// TODO: Delete overlapping textures that aren't in texture pool
|
||||||
// TODO: Delete textures not in texture pool
|
textures.emplace(mapping, TextureMapping{texture, it, guestMapping});
|
||||||
}
|
|
||||||
textures.emplace(mappingEnd, TextureMapping{texture, it, guestMapping});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TextureView(texture, static_cast<vk::ImageViewType>(guestTexture.type), vk::ImageSubresourceRange{
|
return TextureView(texture, static_cast<vk::ImageViewType>(guestTexture.type), vk::ImageSubresourceRange{
|
||||||
|
@ -92,7 +92,14 @@ namespace skyline::loader {
|
|||||||
size_t length{};
|
size_t length{};
|
||||||
std::unique_ptr<char, decltype(&std::free)> demangled{abi::__cxa_demangle(info.dli_sname, nullptr, &length, &status), std::free};
|
std::unique_ptr<char, decltype(&std::free)> demangled{abi::__cxa_demangle(info.dli_sname, nullptr, &length, &status), std::free};
|
||||||
|
|
||||||
return fmt::format("\n* 0x{:X} ({} from {})", reinterpret_cast<uintptr_t>(pointer), (status == 0) ? std::string_view(demangled.get()) : info.dli_sname ? info.dli_sname : "Unresolved", info.dli_fname ? info.dli_fname : "Unresolved");
|
if (info.dli_sname && info.dli_fname)
|
||||||
|
return fmt::format("\n* 0x{:X} ({} from {})", reinterpret_cast<uintptr_t>(pointer), (status == 0) ? std::string_view(demangled.get()) : info.dli_sname, info.dli_fname);
|
||||||
|
else if (info.dli_sname)
|
||||||
|
return fmt::format("\n* 0x{:X} ({})", reinterpret_cast<uintptr_t>(pointer), (status == 0) ? std::string_view(demangled.get()) : info.dli_sname);
|
||||||
|
else if (info.dli_fname)
|
||||||
|
return fmt::format("\n* 0x{:X} (from {})", reinterpret_cast<uintptr_t>(pointer), info.dli_fname);
|
||||||
|
else
|
||||||
|
return fmt::format("\n* 0x{:X}", reinterpret_cast<uintptr_t>(pointer));
|
||||||
} else {
|
} else {
|
||||||
return fmt::format("\n* 0x{:X}", reinterpret_cast<uintptr_t>(pointer));
|
return fmt::format("\n* 0x{:X}", reinterpret_cast<uintptr_t>(pointer));
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,34 @@ namespace skyline::service::am {
|
|||||||
constexpr u32 LaunchParameterMagic{0xC79497CA}; //!< The magic of the application launch parameters
|
constexpr u32 LaunchParameterMagic{0xC79497CA}; //!< The magic of the application launch parameters
|
||||||
constexpr size_t LaunchParameterSize{0x88}; //!< The size of the launch parameter IStorage
|
constexpr size_t LaunchParameterSize{0x88}; //!< The size of the launch parameter IStorage
|
||||||
|
|
||||||
auto storageService{std::make_shared<IStorage>(state, manager, LaunchParameterSize)};
|
enum class LaunchParameterKind : u32 {
|
||||||
|
UserChannel = 1,
|
||||||
|
PreselectedUser = 2,
|
||||||
|
Unknown = 3,
|
||||||
|
} launchParameterKind{request.Pop<LaunchParameterKind>()};
|
||||||
|
|
||||||
|
std::shared_ptr<IStorage> storageService;
|
||||||
|
switch (launchParameterKind) {
|
||||||
|
case LaunchParameterKind::UserChannel:
|
||||||
|
return result::NotAvailable;
|
||||||
|
|
||||||
|
case LaunchParameterKind::PreselectedUser: {
|
||||||
|
storageService = std::make_shared<IStorage>(state, manager, LaunchParameterSize);
|
||||||
|
|
||||||
storageService->Push<u32>(LaunchParameterMagic);
|
storageService->Push<u32>(LaunchParameterMagic);
|
||||||
storageService->Push<u32>(1);
|
storageService->Push<u32>(1);
|
||||||
storageService->Push(constant::DefaultUserId);
|
storageService->Push(constant::DefaultUserId);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LaunchParameterKind::Unknown:
|
||||||
|
throw exception("Popping 'Unknown' Launch Parameter: {}", static_cast<u32>(launchParameterKind));
|
||||||
|
|
||||||
|
default:
|
||||||
|
return result::InvalidInput;
|
||||||
|
}
|
||||||
|
|
||||||
manager.RegisterService(storageService, session, response);
|
manager.RegisterService(storageService, session, response);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
namespace skyline::service::am {
|
namespace skyline::service::am {
|
||||||
namespace result {
|
namespace result {
|
||||||
|
constexpr Result NotAvailable(128, 2);
|
||||||
|
constexpr Result InvalidInput(128, 500);
|
||||||
constexpr Result InvalidParameters(128, 506);
|
constexpr Result InvalidParameters(128, 506);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "IStorage.h"
|
#include "IStorage.h"
|
||||||
|
|
||||||
namespace skyline::service::am {
|
namespace skyline::service::am {
|
||||||
IStorage::IStorage(const DeviceState &state, ServiceManager &manager, size_t size) : content(size), BaseService(state, manager) {}
|
IStorage::IStorage(const DeviceState &state, ServiceManager &manager, size_t size) : content(size, 0), BaseService(state, manager) {}
|
||||||
|
|
||||||
Result IStorage::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IStorage::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
manager.RegisterService(std::make_shared<IStorageAccessor>(state, manager, shared_from_this()), session, response);
|
manager.RegisterService(std::make_shared<IStorageAccessor>(state, manager, shared_from_this()), session, response);
|
||||||
|
@ -25,7 +25,7 @@ namespace skyline::service::fssrv {
|
|||||||
|
|
||||||
Result IDirectory::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IDirectory::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto entries{backing->Read()};
|
auto entries{backing->Read()};
|
||||||
auto outputEntries{request.inputBuf.at(0).cast<DirectoryEntry>()};
|
auto outputEntries{request.outputBuf.at(0).cast<DirectoryEntry, std::dynamic_extent, true>()};
|
||||||
size_t i{};
|
size_t i{};
|
||||||
|
|
||||||
for (; i < std::min(entries.size(), outputEntries.size()); i++) {
|
for (; i < std::min(entries.size(), outputEntries.size()); i++) {
|
||||||
|
@ -1,48 +1,11 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
#include <kernel/types/KProcess.h>
|
|
||||||
#include "resources/FontChineseSimplified.ttf.h"
|
|
||||||
#include "resources/FontChineseTraditional.ttf.h"
|
|
||||||
#include "resources/FontExtendedChineseSimplified.ttf.h"
|
|
||||||
#include "resources/FontKorean.ttf.h"
|
|
||||||
#include "resources/FontNintendoExtended.ttf.h"
|
|
||||||
#include "resources/FontStandard.ttf.h"
|
|
||||||
#include "IPlatformServiceManager.h"
|
#include "IPlatformServiceManager.h"
|
||||||
|
#include "shared_font_core.h"
|
||||||
|
|
||||||
namespace skyline::service::pl {
|
namespace skyline::service::pl {
|
||||||
struct FontEntry {
|
IPlatformServiceManager::IPlatformServiceManager(const DeviceState &state, ServiceManager &manager, SharedFontCore &core) : BaseService(state, manager), core(core) {}
|
||||||
u8 *data; //!< The font TTF data
|
|
||||||
size_t length; //!< The length of the font TTF data
|
|
||||||
size_t offset; //!< The offset of the font in shared memory
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<FontEntry, 6> fontTable{
|
|
||||||
{
|
|
||||||
{FontChineseSimplified, FontExtendedChineseSimplifiedLength},
|
|
||||||
{FontChineseTraditional, FontChineseTraditionalLength},
|
|
||||||
{FontExtendedChineseSimplified, FontExtendedChineseSimplifiedLength},
|
|
||||||
{FontKorean, FontKoreanLength},
|
|
||||||
{FontNintendoExtended, FontNintendoExtendedLength},
|
|
||||||
{FontStandard, FontStandardLength}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
IPlatformServiceManager::IPlatformServiceManager(const DeviceState &state, ServiceManager &manager) : fontSharedMem(std::make_shared<kernel::type::KSharedMemory>(state, constant::FontSharedMemSize)), BaseService(state, manager) {
|
|
||||||
constexpr u32 SharedFontResult{0x7F9A0218}; //!< The decrypted magic for a single font in the shared font data
|
|
||||||
constexpr u32 SharedFontMagic{0x36F81A1E}; //!< The encrypted magic for a single font in the shared font data
|
|
||||||
constexpr u32 SharedFontKey{SharedFontMagic ^ SharedFontResult}; //!< The XOR key for encrypting the font size
|
|
||||||
|
|
||||||
auto ptr{reinterpret_cast<u32 *>(fontSharedMem->host.ptr)};
|
|
||||||
for (auto &font : fontTable) {
|
|
||||||
*ptr++ = SharedFontResult;
|
|
||||||
*ptr++ = font.length ^ SharedFontKey;
|
|
||||||
font.offset = reinterpret_cast<u64>(ptr) - reinterpret_cast<u64>(fontSharedMem->host.ptr);
|
|
||||||
|
|
||||||
std::memcpy(ptr, font.data, font.length);
|
|
||||||
ptr = reinterpret_cast<u32 *>(reinterpret_cast<u8 *>(ptr) + font.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IPlatformServiceManager::GetLoadState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IPlatformServiceManager::GetLoadState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
constexpr u32 FontLoaded{1}; //!< "All fonts have been loaded into memory"
|
constexpr u32 FontLoaded{1}; //!< "All fonts have been loaded into memory"
|
||||||
@ -52,18 +15,18 @@ namespace skyline::service::pl {
|
|||||||
|
|
||||||
Result IPlatformServiceManager::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IPlatformServiceManager::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto fontId{request.Pop<u32>()};
|
auto fontId{request.Pop<u32>()};
|
||||||
response.Push<u32>(fontTable.at(fontId).length);
|
response.Push<u32>(core.fonts.at(fontId).length);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IPlatformServiceManager::GetSharedMemoryAddressOffset(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IPlatformServiceManager::GetSharedMemoryAddressOffset(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto fontId{request.Pop<u32>()};
|
auto fontId{request.Pop<u32>()};
|
||||||
response.Push<u32>(fontTable.at(fontId).offset);
|
response.Push<u32>(core.fonts.at(fontId).offset);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IPlatformServiceManager::GetSharedMemoryNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
Result IPlatformServiceManager::GetSharedMemoryNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
auto handle{state.process->InsertItem<type::KSharedMemory>(fontSharedMem)};
|
auto handle{state.process->InsertItem<type::KSharedMemory>(core.sharedFontMemory)};
|
||||||
response.copyHandles.push_back(handle);
|
response.copyHandles.push_back(handle);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -6,22 +6,19 @@
|
|||||||
#include <kernel/types/KSharedMemory.h>
|
#include <kernel/types/KSharedMemory.h>
|
||||||
#include <services/serviceman.h>
|
#include <services/serviceman.h>
|
||||||
|
|
||||||
namespace skyline {
|
namespace skyline::service::pl {
|
||||||
namespace constant {
|
struct SharedFontCore;
|
||||||
constexpr u32 FontSharedMemSize{0x1100000}; //!< The total size of the font shared memory
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace service::pl {
|
|
||||||
/**
|
/**
|
||||||
* @brief IPlatformServiceManager is used to access shared fonts
|
* @brief IPlatformServiceManager is used to access shared fonts
|
||||||
* @url https://switchbrew.org/wiki/Shared_Database_services#pl:u.2C_pl:s
|
* @url https://switchbrew.org/wiki/Shared_Database_services#pl:u.2C_pl:s
|
||||||
*/
|
*/
|
||||||
class IPlatformServiceManager : public BaseService {
|
class IPlatformServiceManager : public BaseService {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<kernel::type::KSharedMemory> fontSharedMem; //!< The KSharedMemory that stores the TTF data of all shared fonts
|
SharedFontCore &core;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IPlatformServiceManager(const DeviceState &state, ServiceManager &manager);
|
IPlatformServiceManager(const DeviceState &state, ServiceManager &manager, SharedFontCore &core);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the loading state of the requested font
|
* @brief Returns the loading state of the requested font
|
||||||
@ -55,4 +52,3 @@ namespace skyline {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,4 +0,0 @@
|
|||||||
#### Skyline FOSS Shared Fonts: (Credit to [FearlessTobi/yuzu_system_archives](https://github.com/FearlessTobi/yuzu_system_archives) for font choice)
|
|
||||||
* [FontStandard](FontStandard.ttf.h), [FontKorean](FontKorean.ttf.h), [FontChineseSimplified](FontChineseSimplified.ttf.h) and [FontChineseTraditional](FontChineseTraditional.ttf.h) are using [Open Sans Regular](https://fonts.google.com/specimen/Open+Sans), which is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* [FontNintendoExtended](FontNintendoExtended.ttf.h) is using [Roboto](https://fonts.google.com/specimen/Roboto), which is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* [FontExtendedChineseSimplified](FontExtendedChineseSimplified.ttf.h) is using [Source Sans Pro](https://fonts.google.com/specimen/Source+Sans+Pro), which is licensed under [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL)
|
|
59
app/src/main/cpp/skyline/services/pl/shared_font_core.h
Normal file
59
app/src/main/cpp/skyline/services/pl/shared_font_core.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <os.h>
|
||||||
|
#include <kernel/types/KProcess.h>
|
||||||
|
#include <vfs/os_filesystem.h>
|
||||||
|
|
||||||
|
namespace skyline::service::pl {
|
||||||
|
/**
|
||||||
|
* @brief A persistent object for managing the shared memory utilized by shared fonts
|
||||||
|
*/
|
||||||
|
struct SharedFontCore {
|
||||||
|
static constexpr u32 FontSharedMemSize{0x1100000}; //!< The total size of the font shared memory
|
||||||
|
std::shared_ptr<kernel::type::KSharedMemory> sharedFontMemory; //!< The KSharedMemory that stores the TTF data of all shared fonts
|
||||||
|
|
||||||
|
struct FontEntry {
|
||||||
|
std::string path; //!< The path of the font asset
|
||||||
|
size_t length; //!< The length of the font TTF data
|
||||||
|
size_t offset; //!< The offset of the font in shared memory
|
||||||
|
};
|
||||||
|
|
||||||
|
std::array<FontEntry, 6> fonts{
|
||||||
|
{
|
||||||
|
{"FontChineseSimplified.ttf"},
|
||||||
|
{"FontChineseTraditional.ttf"},
|
||||||
|
{"FontExtendedChineseSimplified.ttf"},
|
||||||
|
{"FontKorean.ttf"},
|
||||||
|
{"FontNintendoExtended.ttf"},
|
||||||
|
{"FontStandard.ttf"},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SharedFontCore(const DeviceState &state) : sharedFontMemory(std::make_shared<kernel::type::KSharedMemory>(state, FontSharedMemSize)) {
|
||||||
|
constexpr u32 SharedFontResult{0x7F9A0218}; //!< The decrypted magic for a single font in the shared font data
|
||||||
|
constexpr u32 SharedFontMagic{0x36F81A1E}; //!< The encrypted magic for a single font in the shared font data
|
||||||
|
constexpr u32 SharedFontKey{SharedFontMagic ^ SharedFontResult}; //!< The XOR key for encrypting the font size
|
||||||
|
|
||||||
|
auto fontsDirectory{std::make_shared<vfs::OsFileSystem>(state.os->appFilesPath + "fonts/")};
|
||||||
|
auto ptr{reinterpret_cast<u32 *>(sharedFontMemory->host.ptr)};
|
||||||
|
for (auto &font : fonts) {
|
||||||
|
*ptr++ = 0x18029a7f;
|
||||||
|
*ptr++ = util::SwapEndianness(font.length ^ 0x49621806);
|
||||||
|
font.offset = reinterpret_cast<u64>(ptr) - reinterpret_cast<u64>(sharedFontMemory->host.ptr);
|
||||||
|
|
||||||
|
std::shared_ptr<vfs::Backing> fontFile;
|
||||||
|
if (fontsDirectory->FileExists(font.path))
|
||||||
|
fontFile = fontsDirectory->OpenFile(font.path);
|
||||||
|
else
|
||||||
|
fontFile = state.os->assetFileSystem->OpenFile("fonts/" + font.path);
|
||||||
|
|
||||||
|
font.length = fontFile->size;
|
||||||
|
fontFile->Read(span<u8>(reinterpret_cast<u8 *>(ptr), font.length));
|
||||||
|
ptr = reinterpret_cast<u32 *>(reinterpret_cast<u8 *>(ptr) + font.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -25,6 +25,7 @@
|
|||||||
#include "visrv/ISystemRootService.h"
|
#include "visrv/ISystemRootService.h"
|
||||||
#include "visrv/IManagerRootService.h"
|
#include "visrv/IManagerRootService.h"
|
||||||
#include "pl/IPlatformServiceManager.h"
|
#include "pl/IPlatformServiceManager.h"
|
||||||
|
#include "pl/shared_font_core.h"
|
||||||
#include "aocsrv/IAddOnContentManager.h"
|
#include "aocsrv/IAddOnContentManager.h"
|
||||||
#include "pctl/IParentalControlServiceFactory.h"
|
#include "pctl/IParentalControlServiceFactory.h"
|
||||||
#include "lm/ILogService.h"
|
#include "lm/ILogService.h"
|
||||||
@ -49,9 +50,10 @@
|
|||||||
namespace skyline::service {
|
namespace skyline::service {
|
||||||
struct GlobalServiceState {
|
struct GlobalServiceState {
|
||||||
timesrv::core::TimeServiceObject timesrv;
|
timesrv::core::TimeServiceObject timesrv;
|
||||||
|
pl::SharedFontCore sharedFontCore;
|
||||||
nvdrv::Driver nvdrv;
|
nvdrv::Driver nvdrv;
|
||||||
|
|
||||||
explicit GlobalServiceState(const DeviceState &state) : timesrv(state), nvdrv(state) {}
|
explicit GlobalServiceState(const DeviceState &state) : timesrv(state), sharedFontCore(state), nvdrv(state) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
ServiceManager::ServiceManager(const DeviceState &state) : state(state), smUserInterface(std::make_shared<sm::IUserInterface>(state, *this)), globalServiceState(std::make_shared<GlobalServiceState>(state)) {}
|
ServiceManager::ServiceManager(const DeviceState &state) : state(state), smUserInterface(std::make_shared<sm::IUserInterface>(state, *this)), globalServiceState(std::make_shared<GlobalServiceState>(state)) {}
|
||||||
@ -83,7 +85,7 @@ namespace skyline::service {
|
|||||||
SERVICE_CASE(visrv::IApplicationRootService, "vi:u")
|
SERVICE_CASE(visrv::IApplicationRootService, "vi:u")
|
||||||
SERVICE_CASE(visrv::ISystemRootService, "vi:s")
|
SERVICE_CASE(visrv::ISystemRootService, "vi:s")
|
||||||
SERVICE_CASE(visrv::IManagerRootService, "vi:m")
|
SERVICE_CASE(visrv::IManagerRootService, "vi:m")
|
||||||
SERVICE_CASE(pl::IPlatformServiceManager, "pl:u")
|
SERVICE_CASE(pl::IPlatformServiceManager, "pl:u", globalServiceState->sharedFontCore)
|
||||||
SERVICE_CASE(aocsrv::IAddOnContentManager, "aoc:u")
|
SERVICE_CASE(aocsrv::IAddOnContentManager, "aoc:u")
|
||||||
SERVICE_CASE(pctl::IParentalControlServiceFactory, "pctl")
|
SERVICE_CASE(pctl::IParentalControlServiceFactory, "pctl")
|
||||||
SERVICE_CASE(pctl::IParentalControlServiceFactory, "pctl:a")
|
SERVICE_CASE(pctl::IParentalControlServiceFactory, "pctl:a")
|
||||||
|
@ -43,15 +43,20 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
|
|||||||
enum class ColorFormat : u32 {
|
enum class ColorFormat : u32 {
|
||||||
None = 0x0,
|
None = 0x0,
|
||||||
R32B32G32A32Float = 0xC0,
|
R32B32G32A32Float = 0xC0,
|
||||||
|
R16G16B16A16Unorm = 0xC6,
|
||||||
|
R16G16B16A16Uint = 0xC9,
|
||||||
R16G16B16A16Float = 0xCA,
|
R16G16B16A16Float = 0xCA,
|
||||||
A2B10G10R10Unorm = 0xD1,
|
A2B10G10R10Unorm = 0xD1,
|
||||||
R8G8B8A8Unorm = 0xD5,
|
R8G8B8A8Unorm = 0xD5,
|
||||||
A8B8G8R8Srgb = 0xD6,
|
A8B8G8R8Srgb = 0xD6,
|
||||||
|
A8B8G8R8Snorm = 0xD7,
|
||||||
R16G16Snorm = 0xDB,
|
R16G16Snorm = 0xDB,
|
||||||
R16G16Float = 0xDE,
|
R16G16Float = 0xDE,
|
||||||
B10G11R11Float = 0xE0,
|
B10G11R11Float = 0xE0,
|
||||||
R32Float = 0xE5,
|
R32Float = 0xE5,
|
||||||
|
R8G8Unorm = 0xEA,
|
||||||
R8G8Snorm = 0xEB,
|
R8G8Snorm = 0xEB,
|
||||||
|
R16Unorm = 0xEE,
|
||||||
R16Float = 0xF2,
|
R16Float = 0xF2,
|
||||||
R8Unorm = 0xF3,
|
R8Unorm = 0xF3,
|
||||||
} format;
|
} format;
|
||||||
|
@ -95,7 +95,13 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
u32 compareMask; // 0x3D7
|
u32 compareMask; // 0x3D7
|
||||||
} stencilBackExtra;
|
} stencilBackExtra;
|
||||||
|
|
||||||
u32 _pad7_[0x13]; // 0x3D8
|
u32 tiledCacheEnable; // 0x3D8
|
||||||
|
struct {
|
||||||
|
u16 width;
|
||||||
|
u16 height;
|
||||||
|
} tiledCacheSize; // 0x3D9
|
||||||
|
|
||||||
|
u32 _pad7_[0x11]; // 0x3DA
|
||||||
u32 rtSeparateFragData; // 0x3EB
|
u32 rtSeparateFragData; // 0x3EB
|
||||||
u32 _pad8_[0x6C]; // 0x3EC
|
u32 _pad8_[0x6C]; // 0x3EC
|
||||||
std::array<type::VertexAttribute, 0x20> vertexAttributeState; // 0x458
|
std::array<type::VertexAttribute, 0x20> vertexAttributeState; // 0x458
|
||||||
|
@ -35,7 +35,7 @@ namespace skyline::vfs {
|
|||||||
} nacpContents{};
|
} nacpContents{};
|
||||||
static_assert(sizeof(NacpData) == 0x4000);
|
static_assert(sizeof(NacpData) == 0x4000);
|
||||||
|
|
||||||
u32 supportedTitleLanguages{}; //<! A bitmask containing the available title entry languages and game icons
|
u32 supportedTitleLanguages{}; //!< A bitmask containing the available title entry languages and game icons
|
||||||
|
|
||||||
NACP(const std::shared_ptr<vfs::Backing> &backing);
|
NACP(const std::shared_ptr<vfs::Backing> &backing);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "os_filesystem.h"
|
#include "os_filesystem.h"
|
||||||
|
|
||||||
namespace skyline::vfs {
|
namespace skyline::vfs {
|
||||||
OsFileSystem::OsFileSystem(const std::string &basePath) : FileSystem(), basePath(basePath) {
|
OsFileSystem::OsFileSystem(const std::string &basePath) : FileSystem(), basePath(basePath.ends_with('/') ? basePath : basePath + '/') {
|
||||||
if (!DirectoryExists(basePath))
|
if (!DirectoryExists(basePath))
|
||||||
if (!CreateDirectory(basePath, true))
|
if (!CreateDirectory(basePath, true))
|
||||||
throw exception("Error creating the OS filesystem backing directory");
|
throw exception("Error creating the OS filesystem backing directory");
|
||||||
|
Loading…
Reference in New Issue
Block a user