yuzu-mirror.github.io/entry/yuzu-applet-overlays/index.html

519 lines
22 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang=" en-us "class="has-navbar-fixed-top">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<meta name="theme-color" content="#404040">
<meta property="og:title" content="New Feature Release - Applet Overlays &middot; yuzu" />
<meta property="og:site_name" content="yuzu" />
<meta property="og:url" content="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/" />
<meta property="og:description" content="Hey there, yuz-ers!
Have you ever thought of enjoying yuzu on your TV, relaxing on your couch, but found our user interface cumbersome?
Thanks to the efforts of our developers Morph and Rei, yuzu has taken a massive step forward in making couch gaming comfy.
Let&rsquo;s dig in!" />
<meta name="description" content="Hey there, yuz-ers!
Have you ever thought of enjoying yuzu on your TV, relaxing on your couch, but found our user interface cumbersome?
Thanks to the efforts of our developers Morph and Rei, yuzu has taken a massive step forward in making couch gaming comfy.
Let&rsquo;s dig in!" />
<meta property="og:type" content="article" />
<meta property="og:image" content="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/banner.png" />
<link rel="icon" href="https://yuzu-mirror.github.io/favicon.ico" />
<link rel="shortcut icon" href="https://yuzu-mirror.github.io/favicon.ico" type="image/x-icon" />
<link rel="canonical" href="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/">
<title>New Feature Release - Applet Overlays - yuzu</title>
<link href="https://fonts.googleapis.com/css?family=Ubuntu|Dosis" rel="stylesheet">
<link href="https://use.fontawesome.com/releases/v6.4.0/css/all.css" rel="stylesheet">
<link rel="stylesheet" href="https://yuzu-mirror.github.io/scss/style.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.css" type="text/css" />
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-112443698-1"></script>
<script type="text/javascript">
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'UA-112443698-1');
</script>
</head>
<body>
<nav class="navbar is-dark is-size-6 is-fixed-top" role="navigation" aria-label="main navigation">
<div class="container">
<div class="navbar-brand">
<a class="navbar-item" href="https://yuzu-mirror.github.io">
<svg xmlns="http://www.w3.org/2000/svg" class="navbar-logo" viewBox="0 0 515.83 163.11"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#ff3c28;}.cls-3{fill:#0ab9e6;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M515.83,23.23v73c0,14.5-2.24,25.24-6.84,32.82-5.92,10.15-16.2,15.32-30.53,15.32s-24.62-5.23-30.58-15.57c-4.56-7.64-6.79-18.42-6.79-32.92V23.23a4.51,4.51,0,0,1,4.51-4.51h2.28a4.51,4.51,0,0,1,4.51,4.51v72.5c0,33.53,14.88,37.4,26.07,37.4,12.14,0,26.08-4.17,26.08-36.71V23.23a4.51,4.51,0,0,1,4.51-4.51h2.27A4.51,4.51,0,0,1,515.83,23.23Z"/><path class="cls-1" d="M421.34,144.4H353.45c-2.35,0-4.72-1.88-4.72-6.08a8.32,8.32,0,0,1,1.33-4.49L410.39,29.36H360.8a4.51,4.51,0,0,1-4.51-4.5V23.28a4.51,4.51,0,0,1,4.48-4.51h.81c58.68-.11,59.11,0,59.66.07a5.19,5.19,0,0,1,4,5.8,8.74,8.74,0,0,1-1.32,3.75L363.33,133.17h58a4.51,4.51,0,0,1,4.51,4.51v2.21A4.51,4.51,0,0,1,421.34,144.4Z"/><path class="cls-1" d="M248.45,23.23v82.06c0,26-11.8,38.44-37.12,39.09h-.12a4.51,4.51,0,0,1-4.51-4.51V137.5a4.51,4.51,0,0,1,4.48-4.5c18.49-.15,26-8.23,26-27.9v-2.37a32.34,32.34,0,0,1-3.34,3.28c-6.39,5.5-14.5,8.29-24.07,8.29-22.86,0-35-12.41-35-35.89V23.23a4.52,4.52,0,0,1,4.51-4.51h2.22a4.52,4.52,0,0,1,4.5,4.51v55c0,7.6,1.82,14.22,5,18.18,3.57,4.56,9.17,6.49,18.75,6.49,10.13,0,17.32-3.76,22-11.5,3.61-5.92,5.43-13.66,5.43-23V23.23a4.52,4.52,0,0,1,4.51-4.51h2.22A4.52,4.52,0,0,1,248.45,23.23Z"/><path class="cls-1" d="M338.12,23.23v73c0,14.5-2.24,25.24-6.84,32.82-5.92,10.15-16.2,15.32-30.53,15.32s-24.62-5.23-30.58-15.57c-4.56-7.64-6.79-18.42-6.79-32.92V23.23a4.51,4.51,0,0,1,4.51-4.51h2.28a4.51,4.51,0,0,1,4.51,4.51v72.5c0,33.53,14.88,37.4,26.07,37.4,12.14,0,26.08-4.17,26.08-36.71V23.23a4.51,4.51,0,0,1,4.51-4.51h2.27A4.51,4.51,0,0,1,338.12,23.23Z"/><g id="g823"><g id="right"><g id="g827"><g id="g833"><path id="path835" class="cls-2" d="M81.56,32.62V163.11a65.25,65.25,0,0,0,0-130.49M94.3,46.91a52.54,52.54,0,0,1,0,101.91V46.91"/></g></g></g><g id="left"><g id="g839"><g id="g845"><path id="path847" class="cls-3" d="M65.24,0a65.25,65.25,0,0,0,0,130.49ZM52.5,14.29V116.2A52.52,52.52,0,0,1,28.12,28.12,52.16,52.16,0,0,1,52.5,14.29"/></g></g></g></g></g></g></svg>
</a>
<div class="burger navbar-burger is-dark" data-target="navMenu">
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="navbar-menu" id="navMenu">
<div class="navbar-start">
<a class="navbar-item px-lg" href="/entry">
Blog
</a>
<a class="navbar-item px-lg" href="/downloads">
Download
</a>
<a class="navbar-item px-lg" href="/wiki/faq">
FAQs
</a>
<a class="navbar-item px-lg" href="/game">
Compatibility
</a>
<a class="navbar-item px-lg" href="/screenshots">
Screenshots
</a>
<a class="navbar-item px-lg" href="https://www.patreon.com/yuzuteam">
Patreon
</a>
<a class="navbar-item px-lg" href="https://profile.yuzu-mirror.github.io">
Profile
</a>
<a class="navbar-item px-lg is-hidden-desktop" href="https://discord.gg/u77vRWY" target="_blank">
<i class="fab fa-discord mr-sm"></i> Discord
</a>
<a class="navbar-item px-lg is-hidden-desktop" href="https://twitter.com/yuzuemu" target="_blank">
<i class="fab fa-twitter mr-sm"></i> Twitter
</a>
<a class="navbar-item px-lg is-hidden-desktop" href="https://github.com/yuzu-mirror/yuzu" target="_blank">
<i class="fab fa-github mr-sm"></i> GitHub
</a>
</div>
<div class="navbar-end">
<a class="navbar-item px-lg is-hidden-touch" href="https://discord.gg/u77vRWY" target="_blank">
<span class="icon">
<i class="fab fa-2x fa-discord"></i>
</span>
</a>
<a class="navbar-item px-lg is-hidden-touch" href="https://twitter.com/yuzuemu" target="_blank">
<span class="icon">
<i class="fab fa-2x fa-twitter"></i>
</span>
</a>
<a class="navbar-item px-lg is-hidden-touch" href="https://github.com/yuzu-mirror/yuzu" target="_blank">
<span class="icon">
<i class="fab fa-2x fa-github"></i>
</span>
</a>
</div>
</div>
</div>
</nav>
<div class="mb-md blog-entry-header single" style="background-image: url('https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/banner_huea1dd56219241918249f8ef0ec893d98_551972_1280x0_resize_q99_bgffffff_box_3.jpg');background-repeat:no-repeat;background-size:contain;background-position:center;"></div>
<div class="has-text-centered">
<div>
<span class="title px-md py-sm">New Feature Release - Applet Overlays</span>
</div>
<div>
<span class="h3 px-md py-sm">
Written by <a href="https://community.citra-emu.org/u/CaptV0rt3x/summary">CaptV0rt3x</a>
on April 03 2021
</span>
</div>
</div>
<div class="container">
<div class="columns is-centered">
<div class="column is-four-fifths">
<section class="section content pt-sm">
<br>
<p>Hey there, yuz-ers!
Have you ever thought of enjoying yuzu on your TV, relaxing on your couch, but found our user interface cumbersome?
Thanks to the efforts of our developers <a href="https://github.com/Morph1984">Morph</a> and <a href="https://github.com/Its-Rei">Rei</a>, yuzu has taken a massive step forward in making couch gaming comfy.
Let&rsquo;s dig in!</p>
<h1 id="what-is-this-about">What is this about?</h1>
<p>For a while now, users have complained that yuzu&rsquo;s couch setup (full-screen, TV, controller) experience isn&rsquo;t as comfortable as it could be.
One pain point was that pop-ups of any kind can&rsquo;t be addressed with a controller.
On top of that, these pop-up windows were separate background processes that wouldn&rsquo;t appear until you exited full-screen mode.
As you can guess, you always had to have a keyboard and mouse handy.</p>
<p>
<div class="columns is-img-preview">
<div class="column has-text-centered">
<a href="./error_old.png" title=" Old error applet">
<img src="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/error_old_hucf490d9216edddf799ccbf12100e1b08_1893328_1024x0_resize_q90_bgffffff_box_3.jpg" alt=" Old error applet"></a>
<p class="has-text-centered is-italic has-text-grey-light"> Old error applet</p>
</div>
</div>
<div class="columns is-img-preview">
<div class="column has-text-centered">
<a href="./error_new.png" title=" New controller friendly error applet">
<img src="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/error_new_hucc6c7b86b81f2ff65c1d0c0dfe7e03e7_559004_1024x0_resize_q90_bgffffff_box_3.jpg" alt=" New controller friendly error applet"></a>
<p class="has-text-centered is-italic has-text-grey-light"> New controller friendly error applet</p>
</div>
</div>
</p>
<p>To fix this once and for all, Rei started work on eliminating all pop-up windows and to make it possible to control all system messages with a controller.
It was during this time that Morph began working on rewriting our software keyboard applet.
And since the software keyboard applet wasn&rsquo;t controller friendly either, they both collaborated and redesigned it from the ground up.</p>
<p>
<div class="columns is-img-preview">
<div class="column has-text-centered">
<a href="./swkbd_old.png" title=" Old software keyboard applet">
<img src="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/swkbd_old_huc6e881e5d57201c17c9050b3ef45d73b_10851_1024x0_resize_q90_bgffffff_box_3.jpg" alt=" Old software keyboard applet"></a>
<p class="has-text-centered is-italic has-text-grey-light"> Old software keyboard applet</p>
</div>
</div>
<div class="columns is-img-preview">
<div class="column has-text-centered">
<video preload="auto" autoplay="autoplay" muted="muted" loop="loop" webkit-playsinline="">
<source src="./swkbd_new.mp4" type="video/mp4">
Your browser doesn't support mp4 video. :(
</video>
<p class="has-text-centered is-italic has-text-grey-light"> New controller friendly software keyboard applet</p>
</div>
</div>
</p>
<h1 id="the-software-keyboard">The Software Keyboard</h1>
<p>As many of you might know, the Switch has a software keyboard that allows players to input text into games.
What you might not know is that there are multiple variants of keyboards implemented within the Switch&rsquo;s Horizon OS.
For example, there is the full-screen keyboard, which pauses games and allows input, and there is the inline keyboard, which allows input while the game is running.</p>
<p>Our old software keyboard implementation was just the bare minimum required by the full-screen variant and, due to its design, was difficult to add support for the other variants.
It also quickly became outdated due to the newer revisions of the applet that shipped with later Switch firmware updates.
Equipped with the knowledge and expertise from previously rewriting two other applets - namely, the browser applet &amp; the controller applet - Morph set out to rewrite the entire software keyboard applet from scratch.</p>
<p>Rei had meticulously designed the new overlays for the keyboard applet and they turned out to be absolutely stunning.
Now, all that was left was to implement the keyboard applet backend and connect it to the frontend — but then came the challenges.</p>
<div class="columns is-img-preview is-bottom-marginless">
<div class="column is-bottom-paddingless">
<a href="./osk_ssbu_line_white.png" title="">
<img src="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/osk_ssbu_line_white_hu10a4a9fda2d0b0b90fc2401684a1d2d3_73062_800x0_resize_q90_bgffffff_box_3.jpg" alt="The new software keyboard layouts for each yuzu theme"></a>
</div>
<div class="column is-bottom-paddingless">
<a href="./osk_ssbu_line_midnight.png" title="">
<img src="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/osk_ssbu_line_midnight_hu96ff7a183ca05854fd0696415b19c464_78369_800x0_resize_q90_bgffffff_box_3.jpg" alt="The new software keyboard layouts for each yuzu theme"></a>
</div>
<div class="column is-bottom-paddingless">
<a href="./osk_ssbu_line_dark.png" title="">
<img src="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/osk_ssbu_line_dark_hu077abc1d4082e197cb507cc585c64164_77745_800x0_resize_q90_bgffffff_box_3.jpg" alt="The new software keyboard layouts for each yuzu theme"></a>
</div>
</div>
<p class="has-text-centered is-italic has-text-grey-light">The new software keyboard layouts for each yuzu theme</p>
<h1 id="challenges">Challenges</h1>
<p>As mentioned earlier, our old implementation was not designed with multi-variant support in mind.
With the rewrite, our foundational goal was to ensure all keyboard variants were supported.
A major challenge was figuring out how the inline keyboard variant worked.
In contrast to the full-screen variant, this one worked asynchronously.</p>
<p>Applets run as separate processes on the Switch, but games have a habit of pausing their processes, invoking the keyboard applet, and making it seem synchronous.
There are several more applets that work asynchronously in addition to the inline keyboard variant.
As such, Morph spent a lot of time and effort on testing how the applet worked on original hardware — figuring out how all the pieces fall into place, making optimizations, and thus slowly perfected the backend implementation.</p>
<p>
<div class="columns is-img-preview">
<div class="column has-text-centered">
<video preload="auto" autoplay="autoplay" muted="muted" loop="loop" webkit-playsinline="">
<source src="./mhgu_line_swkbd.mp4" type="video/mp4">
Your browser doesn't support mp4 video. :(
</video>
<p class="has-text-centered is-italic has-text-grey-light"> Monster Hunter Generations Ultimate - Inline Keyboard in action</p>
</div>
</div>
<div class="columns is-img-preview">
<div class="column has-text-centered">
<video preload="auto" autoplay="autoplay" muted="muted" loop="loop" webkit-playsinline="">
<source src="./swsh_num_swkbd.mp4" type="video/mp4">
Your browser doesn't support mp4 video. :(
</video>
<p class="has-text-centered is-italic has-text-grey-light"> Pokémon Sword/Shield - Numeric Keyboard in action</p>
</div>
</div>
</p>
<p>With the backend in place, a new set of challenges arose due to yuzu&rsquo;s frontend library, <a href="https://www.qt.io/">Qt</a>.
Qt has a <strong>lot</strong> of annoying quirks, such as window positioning, transparency, and more.
These took several days of testing to track down and resolve.
For the frontend, Morph and Rei also had to plan and account for various other things like game specific keyboard scaling, high DPI displays, and higher resolutions.</p>
<p>The final and most important challenge was figuring out how to make the applet controller friendly.
Thanks to the efforts spent in planning and testing at various stages of development, our devs were able to overcome these challenges.</p>
<h1 id="extra">Extra</h1>
<p>Although the overlay dialogs were initially designed with the keyboard applet in mind, the devs soon discovered its potential as a replacement for pop-up windows.
Thanks to this, the error applet has now joined the list of controller friendly applets, with more to come soon.
The error applet is used by games to crash and report back error codes to the user in various scenarios, which was previously done via a pop-up window.</p>
<div class="columns is-img-preview is-bottom-marginless">
<div class="column is-bottom-paddingless">
<a href="./error_white.png" title="">
<img src="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/error_white_hud3bb1ba5ce2bcad704158530826d5151_734789_800x0_resize_q90_bgffffff_box_3.jpg" alt="The new error applet overlays for each yuzu theme"></a>
</div>
<div class="column is-bottom-paddingless">
<a href="./error_midnight.png" title="">
<img src="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/error_midnight_hud595fd048a1e9a938b4f2dce7be224c0_659969_800x0_resize_q90_bgffffff_box_3.jpg" alt="The new error applet overlays for each yuzu theme"></a>
</div>
<div class="column is-bottom-paddingless">
<a href="./error_dark.png" title="">
<img src="https://yuzu-mirror.github.io/entry/yuzu-applet-overlays/error_dark_hu3985d37d183b137d70646b0b6860235a_566637_800x0_resize_q90_bgffffff_box_3.jpg" alt="The new error applet overlays for each yuzu theme"></a>
</div>
</div>
<p class="has-text-centered is-italic has-text-grey-light">The new error applet overlays for each yuzu theme</p>
<h1 id="fin">Fin</h1>
<p>Both the new keyboard applet and the controller friendly error applet are now available in the <a href="https://yuzu-mirror.github.io/help/early-access/">latest Early Access build</a>.
Since these are currently still under development, we would like to hear more about your experiences and any bugs/issues you might encounter.
Please don&rsquo;t hesitate to reach out to us on our Discord server&rsquo;s Patreon support channels to report any findings.
That&rsquo;s all we have for today but, we&rsquo;re sure to be back with more exciting news soon!</p>
<p> 
<h4 style="text-align:center;">
<b>Please consider supporting us on <a href="https://www.patreon.com/yuzuteam">Patreon</a>!<br>
If you would like to contribute to this project, check out our <a href="https://github.com/yuzu-emu/yuzu">GitHub</a>!</b>
</h4>
</p>
</section>
<div class="has-text-centered">
<a class="pagination-next" href="https://community.citra-emu.org/t/387809">Continue the discussion on our forums.</a>
</div>
</div>
<div class="column">
<div class="px-md">
<ins class="adsbygoogle"
style="display:block; margin-left:25px;"
data-ad-client="ca-pub-4126545610079023"
data-ad-slot="6276099127"
data-ad-format="auto"></ins>
<br>
<p class="is-size-6 has-text-centered">Advertisement</p>
</div>
</div>
</div>
<div class="column">
<div class="px-md has-text-centered">
<p class="is-size-6 has-text-centered">Advertisement</p>
<br>
<ins class="adsbygoogle" style="display:inline-block;width:728px;height:100px" data-ad-client="ca-pub-4126545610079023" data-ad-slot="1038554045"></ins>
</div>
</div>
</div>
<div class="container">
<footer class="footer">
<div class="content has-text-centered">
copyright &copy; 2025 yuzu emulator team
</div>
</footer>
</div>
<script src="https://yuzu-mirror.github.io/js/script.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.11.1/baguetteBox.min.js" type="text/javascript"></script>
<script type="text/javascript">
window.addEventListener("DOMContentLoaded", function() {
baguetteBox.run('.is-img-preview');
});
</script>
<script type="text/javascript">
for (var i = 0; i < document.getElementsByClassName('adsbygoogle').length; i++) {
(adsbygoogle = window.adsbygoogle || []).push({});
}
</script>
</body>
</html>