<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Mikage: A research center for 3DS emulation]]></title><description><![CDATA[Mikage: A research center for 3DS emulation]]></description><link>https://mikage.app/</link><image><url>https://mikage.app/favicon.png</url><title>Mikage: A research center for 3DS emulation</title><link>https://mikage.app/</link></image><generator>Ghost 4.39</generator><lastBuildDate>Fri, 08 Nov 2024 10:47:57 GMT</lastBuildDate><atom:link href="https://mikage.app/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Taming the Beast: A Leap forward for 3DS Homebrew Development]]></title><description><![CDATA[Today, we're releasing a central building block used throughout Mikage: A package management solution for 3DS tools and homebrew development! Learn what this is a tool can do for homebrew and emulator developers, and read about the problems it solves for Mikage development.]]></description><link>https://mikage.app/conan-3ds-announcement/</link><guid isPermaLink="false">6645c00572df8f036a488612</guid><category><![CDATA[Technical]]></category><category><![CDATA[Announcement]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Sun, 16 Jun 2024 18:05:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2024/06/conan-mikage.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2024/06/conan-mikage.png" alt="Taming the Beast: A Leap forward for 3DS Homebrew Development"><p>Today, we&apos;re releasing a central building block used throughout Mikage: A package management solution for 3DS tools and homebrew development! <a href="https://github.com/mikage-emu/conan-3ds">conan-3ds</a> takes care of setting up toolchains and development libraries, with support for side-by-side installation, semi-reproducible builds, and safe updates. While this is a tool for fellow homebrew and emulator developers, we figured it&apos;s a good opportunity to explain a bit more about its background and the problems it solves for Mikage development.</p><h2 id="background">Background</h2><p>During development of our 3DS emulator, we naturally work with a lot of 3DS homebrew for testing, so we rely heavily on various tools such as the <a href="https://devkitpro.org/wiki/devkitARM">devkitARM</a> compiler toolchain, the <a href="https://github.com/3DSGuy/Project_CTR/tree/master/ctrtool">ctrtool</a> info tool, or the <a href="https://github.com/devkitPro/3ds-hbmenu">3DS Homebrew Menu</a>. To test hardware features in isolation, example projects such as <a href="https://github.com/devkitPro/3ds-examples">the devkitPro ones</a> come into play. </p><p>On top of the existing 3DS ecosystem of apps and tools, we also wrote a lot of our own utilities: From our <a href="https://www.youtube.com/watch?v=qvk18bs52tk">automated hardware test suite</a>, a title manager (similar to <a href="https://github.com/Shadowtrance/FBI">FBI</a>), a sophisticated GPU debugging tool, and more. This is where the homebrew libraries <a href="https://github.com/devkitPro/libctru">libctru</a> and <a href="https://github.com/devkitPro/citro3d/">citro3d</a> come in, but also widely used C++ libraries like <a href="https://fmt.dev/">fmt</a> or <a href="https://github.com/catchorg/Catch2">Catch2</a>.</p><p>All of this is to say: There are a lot of components related to 3DS development when creating large, complex software such as Mikage. This opens up some interesting challenges:</p><ul><li>How do you organize all the tools, libraries, and applications on disk? How difficult is it to add new things into the mix?</li><li>How do you ensure applications are built with the correct version of each library? How do you keep track of the required version lists in the first place?</li><li>What do you do if one application requires libctru from 2024 but another won&apos;t built unless using the one from 2018?</li><li>If you update a library with a breaking change, how do you avoid having to make changes to <em>all projects that use it</em> at once?</li><li>What about external collaborators? How do you ensure their build setup is consistent with yours?</li><li>How do you avoid all of this management overhead to blow up to a full-time job?</li></ul><h2 id="enter-package-managers">Enter package managers</h2><p>Fellow software developers will already know the answer: A <a href="https://en.wikipedia.org/wiki/Package_manager">package manager</a>!</p><blockquote>A <strong>package manager</strong> or <strong>package-management system</strong> is a collection of software tools that automates the process of installing, upgrading, configuring, and removing computer programs for a computer in a consistent manner</blockquote><p>We aren&apos;t the first to have this idea: devkitPro offer a similar setup for the 3DS based on <code>pacman</code>. Sadly <a href="https://github.com/mikage-emu/conan-3ds/blob/main/Readme.md#why-another-package-manager-for-the-3ds">it&apos;s not suited</a> to address the problems listed in the beginning however, so we needed to come up with an alternative. After looking into existing options, we found a promising base for our work: <a href="https://conan.io/">Conan</a>, a package manager for C and C++ developers.</p><p>While Pacman operates like a traditional system package manager in the Linux world, Conan is more like Python&apos;s <code>pip</code>. It allows applications to declare a list of dependencies with specific version ranges; it supports side-by-side installation of multiple versions of the same library; and it has fantastic integration into different build systems like CMake and Autotools. A perfect match!</p><p>What we added on top is a number of different 3DS-specific packages, and <a href="https://docs.conan.io/2/examples/extensions.html">Conan extensions</a> to facilitate setup of the compiler toolchain. The result: <a href="https://github.com/mikage-emu/conan-3ds">conan-3ds</a>, a package repository that adds 3DS superpowers to Conan. While we want to focus this post on our motivation for writing this, here&apos;s a sneak preview:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="150" src="https://www.youtube.com/embed/hKkdmQdNSaI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="A new 3DS homebrew build tool: Setup &amp; Usage for conan-3ds"></iframe><figcaption>Compiling 3DS homebrew has never been easier!</figcaption></figure><p>This innocent-looking command <code>conan install-3ds 3ds_examples</code> will install the <a href="https://github.com/devkitPro/3ds-examples">3DS example projects</a>, including all of the heavy-lifting that you didn&apos;t want to think about in the first place: It downloads the devkitARM toolchain and it builds the core dependencies libctru, citro2d, and citro3d. Even ImageMagick is compiled behind the scenes since some examples rely on it. You can also specify specific versions, such as <code>3ds_examples/20170714 --toolchain devkitarm49</code> to build older releases that wouldn&apos;t build with the latest library versions. Pretty cool, huh?</p><p>If you&apos;re intrigued, head over to our <a href="https://github.com/mikage-emu/conan-3ds">source repository</a> for a full usage guide. For this post, let&apos;s continue with the problems this solves for us!</p><h2 id="within-arms-reach-more-than-1000-libraries">Within arm&apos;s reach: More than 1000 libraries</h2><p>One main advantage of Conan is the huge number of C and C++ libraries that are already packaged for it: At the time of writing, <a href="https://conan.io/center">1737 packages</a> are available! Need to add <a href="https://fmt.dev">string formatting</a>, <a href="https://github.com/catchorg/Catch2">unit testing</a>, or <a href="https://zlib.net/">file</a> <a href="https://sourceware.org/bzip2/">decompression</a> to your project? No problem. Even the rather heavyweight Boost libraries work!</p><p>This is a massive upgrade compared to the set of <a href="https://github.com/devkitPro/pacman-packages/tree/master/3ds">previously available packages</a>! Not only does Conan offer more than 30 times as many packages, but the various libraries are more up to date too: The extreme case here is SDL, previously limited to the <em>13-year-old</em> version 1.2. <code>conan-3ds</code> ships the latest version 2.30, released in May of this year!</p><p>Of course, not all of the 1737 packages will be compatible with the 3DS due to platform specifics, but in our experience libraries without strong platform dependencies will just work. Additionally, some packages will work fine if specific platform-specific components are disabled. If you find anything that can easily be fixed, be sure to let us know so we can ship the right package settings by default!</p><h2 id="the-right-match-for-a-lone-library-version">The right match for a lone library version</h2><p>How hard could it be to build old homebrew apps from 2018? In an ideal world, the <code>libctru</code> and <code>citro3d</code> libraries used by most 3DS homebrew would only ever add new features when releasing new versions. Old homebrew (written against old versions of these base libraries) would continue to compile fine even with newer versions then. In theory, a 3DS application that uses an old citro3d version for 3D graphics should be able to move to a newer core libctru library or a more recent devkitARM toolchain without a problem. </p><p>In practice, sadly the 3DS library ecosystem hasn&apos;t been so reliable. devkitARM, libctru, and citro3d are heavily intertwined with each other: If you update one of the three, you generally have to update all of them. Conversely if you&apos;re trying to build an <em>older</em> homebrew app, you will generally need to match up older versions as well - and with so many years passed, it&apos;s not easy to figure out which citro3d versions can be used with the ancient libctru 1.6.0!</p><p><code>conan-3ds</code> addresses this by writing down the exact version ranges needed for libraries and their dependencies. Here&apos;s how <a href="https://github.com/mikage-emu/conan-3ds/blob/e72f2409f1f9bdfe313ea183e2be9984083256de/packages/citro3d/conanfile.py#L15-L25">citro3d declares</a> its libctru dependencies:</p><pre><code class="language-python">def requirements(self):
    if self.version &gt;= &apos;1.7.0&apos;:
        self.requires(&quot;libctru/[&gt;=2.1.0]&quot;)
    elif self.version &gt;= &apos;1.6.1&apos;:
        self.requires(&quot;libctru/[&gt;=2.0.0 &lt;2.1.0]&quot;)
    elif self.version &gt;= &apos;1.3.0&apos;:
        self.requires(&quot;libctru/[&gt;=1.5.1 &lt;2.0.0]&quot;)</code></pre><p>Manually finding out the compatible ranges was rather painful, but now that it&apos;s done others won&apos;t have to repeat the effort. Thanks to this list, we can have confidence that when building old software, we&apos;ll always combine the right library versions.</p><h2 id="russian-update-roulette">Russian update roulette</h2><p>It&apos;s one thing to take care of old, unmaintained apps, but other issues come up with actively developed software. Imagine you&apos;re working on a 3DS app and a new libctru version gets released with a cool new feature: You update the dependency, make some tweaks to your code, and it all works. That is, <em>until</em> you realize there was an API change that actually <em>breaks</em> all the other projects you&apos;ve been working on. You either have to fix <em>all</em> your projects, or move back to the old libctru version.</p><p>Updating dependencies has been an all-or-nothing deal that 3DS homebrew developers are all too familiar with. While pacman made updating libraries easier, it made this problem worse since there is no option for downgrades (once you updated, you were stuck!). Due to the sheer number of projects we touched during Mikage development, this often led to <em>days</em> of unplanned follow-up work. Updates became a big, unpredictable, irreversible risk.</p><p>With Conan, we win a powerful feature to combat the problem: Side-by-side installation of multiple versions of the same library. When using multiple projects in parallel, each can use their own copy of libctru and other libraries as needed, allowing you to selectively opt into newer package versions individually. If something doesn&apos;t work out, you can just move back to the old version without affecting the other projects.</p><p>The best part? Since each homebrew app declares which library versions are required, all of this happens automatically. There&apos;s no need to juggle library versions yourself. This is how <code>conan-3ds</code> can build any of the 3DS homebrew examples <a href="https://github.com/mikage-emu/conan-3ds/blob/e72f2409f1f9bdfe313ea183e2be9984083256de/packages/3ds_examples/conanfile.py#L27-L52">from 2015 to 2024</a> against matching old versions of the base libraries without a sweat.</p><h2 id="frozen-in-time-semi-reproducible-builds">Frozen in time: Semi-reproducible builds</h2><p>Ideally, app authors would <em>eventually</em> update their dependencies to the latest versions, but in practice that doesn&apos;t happen for various reasons. For Mikage, this posed a big problem when we tried debugging old homebrew applications: Building from source seemed impossible because the involved libctru versions were so old. But updating would&apos;ve effectively required a rewrite of the app, at which point it wouldn&apos;t have been useful for debugging the original issue.</p><p>Once again, side-by-side installation comes to the rescue: All we need to figure out now is what libctru version an app was written against, and conan-3ds will ensure to combine it with the correct versions of other libraries. We also have version checks <a href="https://github.com/mikage-emu/conan-3ds/blob/a5362a2e3e04967d67a7596ddcb754a586dace2e/packages/libctru/conandata.yml#L5-L6">on devkitARM itself</a> in place, since particularly ancient libctru versions won&apos;t build on more recent compiler versions.</p><p>As a stress test (and because we actually needed to test a very specific thing!), we went as far and checked out an ancient version of <code>3ds_examples</code> from August 2015 along with one of the earliest libctru releases ever. The result? It works!</p><p>We refer to this as <em>semi-reproducible builds</em>. This plays on the practice of reproducible builds, which has much stronger bit-by-bit requirements that we don&apos;t currently aim for - but it&apos;s such a big step forward compared to the status quo that we think it&apos;s a suitable analogy.</p><h2 id="the-road-ahead">The road ahead</h2><p><code>conan-3ds</code> has been in use in Mikage for longer than you might think. Over the years, we went through several iterations to add features and to make usage easier. We&apos;re finally at a point where we think the system is robust enough for others to experiment with. While we&apos;ve had some help testing, this initial release is still anticipated to have rough edges. Contributions to make it even better than today are hence absolutely welcome!</p><p>Did you add more versions for recently released libraries? Did you get a new package from Conan Center working by tweaking a few settings? Did you try out conan-3ds in a homebrew app of yours? Are you interested in using Conan on the Nintendo Switch? We want to hear about your experience! And while we can&apos;t turn this side-project into a full-time job, by working together we can smoothen things out for everyone.</p><p>As far as Mikage is concerned, the next thing we&apos;re pushing to release is our <a href="https://www.youtube.com/watch?v=qvk18bs52tk">graphics test suite</a>, which makes heavy use of the Conan infrastructure and hence had to wait for this initial code drop. Stay tuned!</p><h2 id="credits">Credits</h2><p>We&apos;d like to thank a number of individuals without whom this undertaking would not have possible (listed in no particular order):</p><ul><li>leseratte, for kindly hosting an archive of <a href="https://wii.leseratte10.de/devkitPro/devkitARM/">prebuilt compiler toolchains</a> and for giving us permission us to have <code>conan-3ds</code> fetch builds directly from their server</li><li>The Conan team, for building a powerful package manager</li><li>The Conan Center maintainers, for providing so many packages out-of-the-box</li><li>The various people who kindly tested the project during development</li></ul><p>Furthermore, thanks to our Sponsor-level supporters on <a href="https://www.patreon.com/mikage">Patreon</a>, including:</p><ul><li>Francisco Garcia</li><li>Mr. Madness</li><li>Pretendo Network</li><li>Thidguy</li></ul>]]></content:encoded></item><item><title><![CDATA[Progress Update: The unsung Heroes of 3DS Emulation]]></title><description><![CDATA[Seemingly mundane tasks often turn out to be anything but trivial to implement: Here are the cornerstones of an emulator that doesn't merely work, but feels right.]]></description><link>https://mikage.app/the-unsung-heroes-of-3ds-emulation/</link><guid isPermaLink="false">659c46d2e14abb037a591405</guid><category><![CDATA[Progress]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Tue, 23 Jan 2024 16:15:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2024/01/mariokart2.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2024/01/mariokart2.png" alt="Progress Update: The unsung Heroes of 3DS Emulation"><p>It&apos;s time for one of these again! We&apos;re seeing a lot of curiosity about what&apos;s taking so long to get Mikage out of the door. Let&apos;s clear up some dust of mystery that often surrounds emulator development: Many assume there&apos;s a straightforward path to bringing games from one platform to another. In practice, it&apos;s far from simple.</p><p>In this update, we wanted to highlight some of the seemingly mundane tasks that turn out to be anything but trivial to implement in an emulator. Being small in scope but immense in technical depth, these things don&apos;t make headlines: Yet they are the cornerstone of creating an emulator that doesn&apos;t merely work, but <em>feels</em> right.</p><p>We&apos;ll get back to big, flashy features and compatibility highlights another day. For a moment, let&apos;s put those aside and take a journey through the small, intricate puzzles that make up the backbone of 3DS emulation.</p><h2 id="bootstrapping-a-virtual-3ds">Bootstrapping a Virtual 3DS</h2><p>Being focused on excellent compatibility right out of the box, Mikage requires a number of different system files that a real 3DS normally works with. For a long time, this involved a convoluted mix of dumping files from a console, decrypting them by hand, and putting them in the correct locations. Doing this from scratch would often take <em>days. </em>Clearly, that wasn&apos;t the user experience we intended for production.</p><p>During initial development, it wasn&apos;t clear which files were needed in the first place, and how the user should get this data in the first place. Making the wrong choices here means users won&apos;t be able to get the emulator working, or they would be bothered with adding new files after each update. Now that the emulator core has become sufficiently mature, we&apos;ve settled for a good approach that has been working well in our experience so far. But implementing this smoother onboarding process would still require a mixture of new emulator features, additional interfaces in the frontend, and a well-integrated setup GUI.</p><p>The elephant in the room is decryption support: Virtually all 3DS system files are encrypted with one of 4 increasingly complicated schemes (called <em>Secure1</em> - <em>Secure4</em>). We&apos;ve based the cryptographic algorithms themselves on the powerful Crypto++ library to produce more reliable results with less work, however building an understanding of the encryption schemes themselves in face of lacking documentation about them took the most time here.</p><p><em>Another</em> can of worms opens up if you consider decryption <em>keys</em> themselves. What format should the keys be stored in? Which of the over 50 keys do we need? What tools should we provide for dumping them? Luckily, just as we were about to tackle this, developer Steveice10 published <a href="https://github.com/citra-emu/citra/pull/6396">a GodMode9 script</a> for exactly this purpose. We tried it out: The dumping process is super easy for anyone with a hacked 3DS, and the dumped data includes everything we need for accurate 3DS emulation.</p><p>With crypto keys and decryption algorithms in place, we can load title installation files to set up 3DS system files. This requires implementing support for reading CIA files - a container format that&apos;s simple on its own but which wraps a set of <em>other</em> files in different formats. Implementing support for all of them wasn&apos;t terribly difficult, but in combination it adds up quickly, especially if you need to flesh out all the edge cases.</p><p>Now that we had all these tech-heavy things implemented, all that was left was to bundle it all up in a nice user interface that automates the process. Our new setup wizard will handle each of the steps above for you. If you hadn&apos;t read this blog post, you&apos;d never guess how much is happening behind the scenes!</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/v4RhdFR9oS0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Prototype GUI: First-time setup &amp; system title bootstrap"></iframe><figcaption>Our new first-time setup GUI in action!</figcaption></figure><p>It&apos;s worth noting none of this was feasible back when we started work on Citra, which led to a really poor experience: Games wouldn&apos;t launch unless dumped with special tools we had to develop from scratch (<a href="https://github.com/neobrain/braindump">braindump</a>, later <a href="https://github.com/citra-emu/uncart">uncart</a>); data from physical consoles (e.g. Miis) couldn&apos;t be imported; and many features were outright not available (Amiibos, system apps, ...). With the benefit of hindsight <em>and</em> easy methods for dumping the required keys, designing Mikage as decrypting-by-default yields a much better experience that supports all features you&apos;ll ever want to touch without needing to go through annoying extra setup.</p><h2 id="dont-panic-unless-its-about-sound">Don&apos;t panic! Unless it&apos;s about Sound...</h2><p>In the last progress update, we&apos;ve been showing off our promising initial audio support. It has been moving forward well and has seen general optimizations since, notably a big speed-up to the &quot;warm-up&quot; required for the DSP emulator upon the first launch of a game. But all that aside, we want to highlight one issue in particular here, which is buggy audio emulation.</p><p>Imagine this scene: You&apos;ve been eagerly playing your favorite 3DS game for hours at a time. You&apos;ve <em>just</em> made it to the door leading to the final boss. You walk through the door in anticipation, and all of a sudden the sound in your earphones becomes... deafening. The audio is painfully loud and distorted beyond recognition. You rush to turn down the volume, but it&apos;s too late. With your ears still ringing, you&apos;re left wondering what just happened. What&apos;s clear though is this glitch was so intense that it ruined the entire experience for you. This almost happened to us during development:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2024/01/mikage_audio_hiccup.png" class="kg-image" alt="Progress Update: The unsung Heroes of 3DS Emulation" loading="lazy" width="1080" height="670" srcset="https://mikage.app/content/images/size/w600/2024/01/mikage_audio_hiccup.png 600w, https://mikage.app/content/images/size/w1000/2024/01/mikage_audio_hiccup.png 1000w, https://mikage.app/content/images/2024/01/mikage_audio_hiccup.png 1080w" sizes="(min-width: 720px) 720px"><figcaption>Just looking at this is scary enough: We&apos;ll spare you the real audio sample!</figcaption></figure><p>While ideally we&apos;d fix whatever underlying bugs cause this problem in the first place, emulator bugs are just a part of reality: We&apos;ll never be able to rule out that after 2 hours of gameplay some sort of subtle integer overflow will cause such issues. As far as we know, virtually all emulators take this as a fact and hence refer to a &quot;Use at your own risk&quot; disclaimer. Potentially causing lasting damage to your ears isn&apos;t what we&apos;re here for though, so instead we&apos;re going the extra mile and adding a layer of protection to detect cases were the audio engine clearly went off course. A &quot;panic mode&quot;, so to speak, that immediately lowers all volume to prevent the worst.</p><p>Audio processing is a very specific field on its own, so we&apos;ve been asking for help on <a href="https://social.treehouse.systems/@mikage/110768934044843695">Mastodon</a>: Within just a day, plenty of people more knowledgeable in the field than us reached out to help us figure out how to approach this important problem. While we haven&apos;t gotten around actually implementing the panic mode itself, we&apos;ve got it fairly well-mapped out now, making the effort much more predictable. For the time being, this allows us to keep improving the audio emulation itself again. Thanks again to everyone who contributed their knowledge to help us move forward here!</p><h2 id="the-art-of-displaying-pictures">The Art of Displaying Pictures</h2><p>Emulating the complex 3D graphics pipeline implemented in an embedded GPU like the PICA200 is a tremendous challenge with lots of side tasks. Even ignoring all this complexity, just <em>getting rendered images to the screen</em> ended up being a massive rabbit hole.</p><p>Think about it: Ideally emulation should run at roughly 60 FPS to match the refresh rate of a 3DS display, but in practice this isn&apos;t always the case. What happens if the monitor is configured for 144 Hz? What if the audio engine lags behind the core emulation, or if there are temporary frame drops? Handling any of these poorly will give you stuttery audio, frame lags, or desynchronized audio/video. While we&apos;ve yet to solve the issue in a fully satisfying way, we put together a framework for <em>asynchronous presentation</em> that&apos;ll fix the most egregious types of problems while allowing for more fine-tuning later. There&apos;s a lot of unexplored territory here even among giants like Dolphin. If you&apos;re interested in technical details, the redream folks have <a href="https://redream.io/posts/improving-audio-video-synchronization-multi-sync">outlined many useful ideas</a> in far more detail than we could cover here.</p><p>In addition to this, we&apos;ve restructured our Vulkan code behind the scenes to allow sharing rendering code between the emulator core and the frontend. Our goal was to avoid the immersion-breaking effect you have in most other emulators, where opening the GUI to change some emulator setting throws you into a completely different interface. Mikage&apos;s experience on the other hand feels much more streamlined thanks to the closer interplay between GUI and emulation. We&apos;re probably the first emulator for a modern console to do this, so stay tuned to see what this enables in practice.</p><h2 id="leave-it-as-you-found-it">Leave it as you found it</h2><p>Every good thing comes to an end, including a good emulation session. But what <em>does</em> actually happen in an emulator when the user hits the stop button? This isn&apos;t a trivial matter if you consider the many emulated components running in parallel, each optimized to handle countless operations per second. But adding exit checks everywhere would add costly overhead for something that happens only once. Sometimes it&apos;s the only option, such as when the emulated GPU has already shut down while the Display subsystem was still waiting for new frames to arrive. Finding each of these dependencies was tricky enough on its own.</p><p>In the majority of cases, we&apos;re instead using C++ exceptions to exit out of hot loops without impacting emulation performance or requiring complex code refactorings. However we must be careful when throwing exceptions in a coroutine or from just-in-time compiled code (... or the latter running in the former), as these environments can&apos;t easily propagate exceptions to their parent. It can be done, but there&apos;s some fun trickery involved (look up std::exception_ptr if you&apos;re interested in technical details!).</p><p>With that in place, we&apos;ve successfully stopped the emulator and are presented with the main user interface again. There&apos;s more problems to face once the user decides to play <em>another</em> game. The UI might still carry state about the emulation core that wasn&apos;t properly reset. This is relatively easy to fix but can be somewhat time-consuming. Fortunately, we&apos;ve designed our emulator with a focus on localizing state and use C++&apos;s resource management features extensively, so we don&apos;t have the same issues in our emulator core that many other projects often face.</p><p>Finally, there&apos;s quality-of-life issues to worry about: Emulator bugs are no fun for anyone, but at least we want to display a friendly popup and return to the UI instead of crashing the entire program. After all, there&apos;s no such thing as a bug-free emulator, so we&apos;d like to counter an unpleasant surprise with a somewhat more comforting error message to tell the user what happened.</p><h2 id="big-features-next">Big features next!</h2><p>Many more things happened in 2023 that we&apos;ll outline in our next update, from new features, major compatibility improvements, and new developer tools. For this one, we wanted to do things a little bit different. It&apos;s easy to underestimate how seemingly little things blow up to fundamental problems that require extensive research work. This is a common pattern in emulation, but we&apos;re pleased with the solutions we&apos;ve discovered, even if we can only implement so many of them with our time constraints.</p><p>Despite frequent request, we&apos;re not eager to release Mikage just for the sake of it. Most other 3DS emulator releases have been met with lukewarm responses. Simply dropping some code on GitHub doesn&apos;t automatically foster a community around the project. For us, this underlines how important defining a clear and practical value-add is.</p><p>We&apos;ve been listening closely to community feedback to see where that value-add sits, and we&apos;re continuously putting in the effort to get there. Sadly, a small but vocal (and not always well-intentioned) part of our community has taken this extra-care as reason to question the project&apos;s purpose in general. As much as we appreciate the eagerness to try out Mikage, this kind of criticism is not constructive and does not help us improve the project. Other conversations have been much more fruitful. From other emulator developers, game programmers, content creators, homebrew people, 3DS enthusiasts, and others: The folks that truly care about the 3DS platform are those who inspire us, motivate us to keep going, and help us refine the gap Mikage is here to fill.</p><p>As usual, thanks for reading, and until next time!</p><p><em>Special thanks to the following people, who generously supported Mikage at Sponsor-level on <a href="https://www.patreon.com/mikage">Patreon</a>:</em></p><ul><li><em>Francisco Garcia</em></li><li><em>Mr. Madness</em></li><li><em>Pretendo Network</em></li><li><em>Rodrigo Copetti</em></li></ul>]]></content:encoded></item><item><title><![CDATA[Louder and faster: A belated Year in Review!]]></title><description><![CDATA[Wonder what we've been up to since our reboot in 2022? Here's a wild mix of improvements, from compatibility fixes to major performance uplifts and more!]]></description><link>https://mikage.app/year-in-review-2022/</link><guid isPermaLink="false">64ad9ce04fe03604b1c4dcc4</guid><category><![CDATA[Progress]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Mon, 17 Jul 2023 21:30:48 GMT</pubDate><media:content url="https://mikage.app/content/images/2023/07/20230120_menu_9_0_0_appicons-copy.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2023/07/20230120_menu_9_0_0_appicons-copy.png" alt="Louder and faster: A belated Year in Review!"><p>How time flies! It&apos;s been over a year since our <a href="https://mikage.app/time-to-renew-3ds-emulation/">project reboot in 2022</a>. We&apos;ve been sending around occasional updates on <a href="https://twitter.com/MikageEmu">Twitter</a>/<a href="https://www.youtube.com/c/MikageEmu/videos">YouTube</a>/<a href="https://social.treehouse.systems/@mikage">Mastodon</a> to log our progress, but after such a while we wanted to also write a more bigger-picture overview of what we&apos;ve been up to.</p><p>Strap in, because 2022 has seen a wild mix of improvements, from compatibility fixes to major performance uplifts and more: Perhaps most important on the list are the PC port of Mikage and the beginnings of audio emulation. Without further ado, let&apos;s get into it!</p><h1 id="its-time-you-listened">It&apos;s time you listened...</h1><p>... is what we&apos;d say if there had been anything to listen to. Alas, Mikage has notoriously been silent due to not emulating the 3DS audio hardware. For good reason: It would have to be done <em>eventually</em>, but we knew it was going to take at least a few months of dedicated work.</p><p>In July 2022 we finally decided to tackle the issue with a first prototype: An audio backend based on <a href="https://github.com/wwylele/teakra">Teakra</a>, a low-level and accuracy-focused approach by former Citra developer wwylele. Lo and behold, in just a few days we turned complete silence to close-to-perfect audio output! The only issue? At 5 frames per second, this accuracy-focused library wasn&apos;t practical for real-time gameplay. Nevertheless, it provided us with a crucial reference point for DSP emulation.</p><p>The real challenge was to make it fast now, which led us to writing our own LLE DSP emulator. After more than 3 months of dedicated work, we finally got to a state fast enough for fullspeed emulation, all while matching the original Teakra prototype in compatibility. Along the journey, we found a lot of neat performance tricks and developed really cool DSP debugging tools to ensure great emulation accuracy. A whole blog post could be dedicated to this topic alone - which in fact we&apos;re planning to do! For now we&apos;ll just let the results speak for themselves. We&apos;re really glad the hard work paid off!</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/mZ1ErCGtzgY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="I can&apos;t keep silent anymore! &#x1F50A; VVVVVV for 3DS emulated with Sound &#x1F50A;"></iframe><figcaption>A first preview of fullspeed audio support, illustrated with the 3DS port of VVVVVV</figcaption></figure><h1 id="a-sense-of-feeling-at-home">A sense of feeling at HOME</h1><p>Mikage has always been about creating an authentic experience that fully preserves the 3DS: Not just the games, but the platform as a whole. Admittedly this vague idea was easy to shrug off as hot air, but in 2022 we could finally show what this authentic experience looks like:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/Wpm-ql1Lyas?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Emulated HOME Menu: Launching Super Mario 3D Land! #shorts"></iframe><figcaption>HOME Menu: The hub greeting you after turning on the console</figcaption></figure><p>That&apos;s right! The 3DS system interface (&quot;HOME Menu&quot;) emulated in its full glory. And not just that, you can even run the initial system setup! How cool is it that your first run of Mikage is just like the first boot of a new console?</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/J9QYk_00E5A?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Like old times: The first run of your virtual 3DS!"></iframe><figcaption>Initial system setup, just like the first boot of a new console</figcaption></figure><p>From Mikage&apos;s perspective, there is a lot of little elements that each required individual work. Whether it was launching games, entering the settings app, the software keyboard, mii selector applets, or one of so many other things: All these aspects added up to months of work, which we&apos;ve collected in an exhaustive overview video. Almost every second, something really cool is happening under the hood. Perhaps most impressively, this shows off Mikage&apos;s capability for multi-process emulation: Each of Mii Maker, HOME Menu, Software Keyboard, and the Mii Selector are dedicated programs that run in parallel to each other!</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/MXFZ-lqE4hs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="System apps showcase: Let&apos;s make a Mii in our 3DS emulator!"></iframe><figcaption>Multi-process emulation and applet support: A showcase of emulated system software!</figcaption></figure><p>We implemented support for somewhat rarely used 3DS controls as well: The 3D slider, the HOME button, and the Power button. (Yes, that&apos;s right: <a href="https://twitter.com/MikageEmu/status/1585327847211945985">You can turn off your virtual 3DS</a>.)</p><h1 id="at-the-speed-of-light">At the speed of light</h1><p>As far as an authentic experience goes, one aspect that&apos;s so obvious it&apos;s rarely spoken out loud is performance. Emulating the HOME Menu with audio is cool and all, but it&apos;s nothing like the real console if you can count the frames as they show up on screen. Mikage&apos;s GPU emulation code hadn&apos;t received much optimization work to this point, being focused much more on getting things rendered correctly than fast. In fact the vast majority of the graphics pipeline was still implemented on the CPU-side, so it was time to move more parts of it to the host GPU.</p><hr><p>Our first attack point was the 3DS vertex shader engine: It was an obvious waste of precious CPU time on a task that GPUs were practically made to process faster. But the latter can&apos;t easily be used without translating the low-level shader bytecode of the 3DS GPU to common shader languages like GLSL or SPIR-V. The big difficulty here is the somewhat esoteric control flow instructions used by the 3DS, which must be remapped to a convential control flow graph. If you&apos;re interested in the technical details, Mees Delzenne has actually written an entire <a href="https://theses.liacs.nl/pdf/2018-2019-DelzenneMJ.pdf">Bachelor thesis</a> on this topic!</p><p>For Mikage, we&apos;ve independently built our own control flow analyzer, from which it&apos;s straightforward to build a GLSL/SPIR-V equivalent to the original 3DS shader. Since getting this right is critical, we also created a mighty debugging interface that allows showing the 3DS shader bytecode side-by-side to our reconstructed control-flow-graph and other representations. This has proven very useful, since these shaders can be mind-bogglingly complex! </p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2023/07/2020_05_13_shader_graph_4.png" width="1458" height="959" loading="lazy" alt="Louder and faster: A belated Year in Review!" srcset="https://mikage.app/content/images/size/w600/2023/07/2020_05_13_shader_graph_4.png 600w, https://mikage.app/content/images/size/w1000/2023/07/2020_05_13_shader_graph_4.png 1000w, https://mikage.app/content/images/2023/07/2020_05_13_shader_graph_4.png 1458w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2023/07/2020_05_17_shader_graph_5.png" width="1823" height="762" loading="lazy" alt="Louder and faster: A belated Year in Review!" srcset="https://mikage.app/content/images/size/w600/2023/07/2020_05_17_shader_graph_5.png 600w, https://mikage.app/content/images/size/w1000/2023/07/2020_05_17_shader_graph_5.png 1000w, https://mikage.app/content/images/size/w1600/2023/07/2020_05_17_shader_graph_5.png 1600w, https://mikage.app/content/images/2023/07/2020_05_17_shader_graph_5.png 1823w" sizes="(min-width: 720px) 720px"></div></div></div><figcaption>Get a grasp on even the most complex shaders - thanks to control flow analysis and a pretty graph visualizer!</figcaption></figure><p>One further nifty design trick is that we&apos;ve strongly decoupled the control flow analysis from the actual shader generation. This helps us handle some corner cases of 3DS shaders that <em>can&apos;t</em> be emulated on the host GPU: Instead of falling back to an excruciatingly slow CPU interpreter path, we recompile these shaders to an internal bytecode representation that&apos;s <em>designed to be fast</em> to process on the CPU. Accurate control flow analysis was crucial for this to work, and thanks to it the worst 3DS shaders now won&apos;t have any noticeable impact on emulator performance. All this works without any platform-specific JIT code generation, so it equally benefits all devices (PC and Android)!</p><hr><p>One other key optimization is <em>flushless rendering</em>, wherein Mikage avoids writing back rendered images to emulated memory and instead keeps them on the host GPU as long as possible. This saves unnecessary work caused by copying around data, enables the host CPU to process more non-graphics emulation work in parallel to the GPU rendering, and provides an efficient mechanism for handling changes in texture formats (<em>format reinterpretation</em>).</p><p>A similar approach is found in what Citra calls <em>texture forwarding</em>, though Mikage features a somewhat more sophisticated system that tracks <em>ownership</em> of each part of emulated memory. This ownership information allows us to omit any unnecessary data copying until the point where the owner changes (e.g. because the emulated game reads directly from a framebuffer). At the same time, it&apos;s a useful safety net that double-checks each GPU resource is in the exact state we expect it to be. This paid off quickly by catching important bugs just by investigating each time the tracking system was yelling at us. Going the extra mile to add validation code is an often underestimated yet highly effective approach to emulation!</p><hr><p>These two major optimizations combined yielded impressive results: We&apos;ve been able to run our evergreen testing game <em>The Legend of Zelda: Ocarina of Time 3D</em> consistently at full native frame rate! Further optimization work is ongoing for more complex games, but it&apos;s reassuring that we&apos;ve now reached this milestone for such a popular title.</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/6NqM6mh_FL4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="A new beginning&#x2026;? The Legend of Zelda: Ocarina of Time 3D &#x2014; revisited!"></iframe><figcaption>No more slideshows! Ocarina of Time 3D finally runs at the full 30 native frames per second (FPS shown in the video are internal)</figcaption></figure><h1 id="no-one-is-left-in-the-dark">No one is left in the dark</h1><p>Fragment lighting was a major blocker for most games to display anything. Some games don&apos;t care if you just don&apos;t emulate lights, but for most games this will leave all the objects fully black! The reason we didn&apos;t implement fragment lighting initially was that it&apos;s a highly complex hardware feature with tons of configurable knobs. Our plan is to get this right by writing hardware tests that verify all the different corner cases. But for the time being, just implementing a very minimal subset is enough to at least render <em>some</em> graphics:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2023/07/2022_03_27_mariokart3.png" class="kg-image" alt="Louder and faster: A belated Year in Review!" loading="lazy" width="800" height="480" srcset="https://mikage.app/content/images/size/w600/2023/07/2022_03_27_mariokart3.png 600w, https://mikage.app/content/images/2023/07/2022_03_27_mariokart3.png 800w" sizes="(min-width: 720px) 720px"><figcaption>Let there be light: There&apos;s kinks to work out, but it&apos;s better than a blank screen!</figcaption></figure><h1 id="do-you-guys-not-have-phones">Do you guys not have phones?</h1><p>Anyone who&apos;s tried Android development before knows: It&apos;s kind of a pain. Iteration times are very slow, debugging is an awful experience, and mobile graphics drivers are royal bugfests. Hence despite Mikage being announced as an Android app, our primary development environment has always been on an internal PC version.</p><p>We never planned on releasing this internal PC build: There&apos;s hundreds of tasks we have to juggle simultaneously during development, so adding 3 more GPU drivers (AMD/Nvidia/Intel) and a new CPU architecture (x86) into the mix wouldn&apos;t have helped us get anything done. Making Mikage ready for PC wouldn&apos;t take egregious amounts of time, but other fires were simply more important.</p><p>Until one day, on a whimp we gave it a shot after all:</p><!--kg-card-begin: html--><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Hi there &#x1F60F; <a href="https://t.co/xt1fLmOYzt">pic.twitter.com/xt1fLmOYzt</a></p>&#x2014; Mikage (@MikageEmu) <a href="https://twitter.com/MikageEmu/status/1497240892373184518?ref_src=twsrc%5Etfw">February 25, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><!--kg-card-end: html--><p>Most of the work that went into this was on the Vulkan renderer by going through all validation layer problems that cropped up on AMD/Intel GPUs. We also found a fun memory leak in the Steam Overlay that we added a workaround for. On the CPU side, we&apos;ve added the excellent <a href="https://github.com/merryhime/dynarmic/">dynarmic</a> recompiler as a backend for faster CPU emulation on x86.</p><p>We also added controller support - which even works on Android for both wired and bluetooth devices!</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/GFItV0OF5KA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="I traded my Limbs for a Gamepad: Rayman for the 3DS emulated on PC and Android!"></iframe><figcaption>When using the keyboard just doesn&apos;t feel right: Controller support!</figcaption></figure><p>Finally, all this is bundled in a new GUI that we&apos;re going to show off in its full glory another day. We&apos;ve chosen a powerful tech stack that is rather unique among emulators, so we&apos;ll have some very Mikage-exclusive features to offer. We&apos;ll have to ask for your imagination to guess the full potential from the small glimpses we&apos;ve given so far, but we&apos;ll have more to show later :)</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2023/07/2022_11_25_layout_editor.png" class="kg-image" alt="Louder and faster: A belated Year in Review!" loading="lazy" width="800" height="960" srcset="https://mikage.app/content/images/size/w600/2023/07/2022_11_25_layout_editor.png 600w, https://mikage.app/content/images/2023/07/2022_11_25_layout_editor.png 800w" sizes="(min-width: 720px) 720px"><figcaption>Layout editing has never been more convenient. Wait until you see this in motion!</figcaption></figure><h1 id="the-time-it-takes-to-build-rome">The time it takes to build Rome</h1><p>With the bigger-picture issues like performance and audio support out of the way, we went through a couple of games in our library and made sure they don&apos;t just <em>somewhat boot</em> but actually run great in Mikage. Emulating some new minor configuration here, fixing a small but game-breaking bug there. Other than the already mentioned changes to the GPU core and the new audio support, practically <em>all</em> of Mikage&apos;s subsystems have received changes: From the ARM CPU emulation core, our kernel system call handling, the service HLE code, YUV video decoding, GPU DMAs, and the filesystem emulation.</p><p>Individually each of these changes had little effect overall. It&apos;s like the heads of a Hydra, where fixing one emulator bug makes you notice two others. But improving each game bit by bit, letting the work bake and add up over <em>months</em>, we could finally reap the fruit that made games suitable for presentation. We couldn&apos;t individually list all the changes we made (there&apos;s too many), but we&apos;re really proud that we can feature so many well-working games thanks to them!</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2023/07/2022_03_27_mariokart5.png" width="800" height="480" loading="lazy" alt="Louder and faster: A belated Year in Review!" srcset="https://mikage.app/content/images/size/w600/2023/07/2022_03_27_mariokart5.png 600w, https://mikage.app/content/images/2023/07/2022_03_27_mariokart5.png 800w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2023/07/220410_ingame2.png" width="400" height="480" loading="lazy" alt="Louder and faster: A belated Year in Review!"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2023/07/mikage_220321_animalcrossing.png" width="400" height="480" loading="lazy" alt="Louder and faster: A belated Year in Review!"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2023/07/2022_03_27_vvvvvv.png" width="400" height="480" loading="lazy" alt="Louder and faster: A belated Year in Review!"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2023/07/mikage_220315_zeldamm3.png" width="400" height="480" loading="lazy" alt="Louder and faster: A belated Year in Review!"></div></div></div><figcaption>A small selection of games now compatible with Mikage</figcaption></figure><h1 id="a-look-ahead">A look ahead</h1><p>That&apos;s all up to the beginning of 2023. We&apos;re really proud of the progress we&apos;ve made: Countless hours, 400 git commits, and more than 25000 new lines of code. Of course these metrics must be taken with a grain of salt, but they do illustrate the scope of our work really well.</p><p>This new phase came with a shift in development philosophy: Our original plan when announcing the project in 2019 was to create a product that can sustain full-time development of a high-quality 3DS emulator. As history showed, <a href="https://mikage.app/good-bye-friends/">that didn&apos;t work out</a>. Ever since the reboot, development is driven by what sparks our passion instead: Working on advanced tech and cool emulator features while pursuing technical challenges that others shied away from. All bundled under the umbrella of a great emulator project.</p><p>Today Mikage is all about pushing the envelope, and it&apos;s really been a breath of fresh air. We can focus on the stuff that excites us without feeling the pressure to please everyone&apos;s expectations. Yet, our <a href="https://www.patreon.com/mikage">Patreon page</a> has seen more support than ever. Seeing other people share the same enthusiasm as us is probably the biggest source of motivation there could be.</p><p>Thanks so much for your support. We can&apos;t wait to share what we&apos;ve been up to since the start of 2023!</p>]]></content:encoded></item><item><title><![CDATA[It's time to renew 3DS emulation: We're back!]]></title><description><![CDATA[It's official: Mikage is returning! We picked development back up again, and here's what's new: Supercharged performance, improved compatibility, and a fresh new PC port!]]></description><link>https://mikage.app/time-to-renew-3ds-emulation/</link><guid isPermaLink="false">625e87eb26f4dd3373aa7b24</guid><category><![CDATA[Announcement]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Tue, 03 May 2022 17:52:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2022/04/mikage_220315_zeldamm_cropped.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2022/04/mikage_220315_zeldamm_cropped.png" alt="It&apos;s time to renew 3DS emulation: We&apos;re back!"><p>Despite continued progress, the signs were not good for Mikage in 2020: Our Patreon campaign wasn&apos;t running too well, various Android-builds of Citra pulled most attention away from us, and then there was that whole pandemic thing (woops). Even our biggest milestone to that point, Mikage running <a href="https://www.youtube.com/watch?v=w7fls3C1ZiE">Super Mario 3D Land</a>, couldn&apos;t change that people were (understandably) occupied with other matters. And thus we had to admit that continued development could not be funded in a sustainable way.</p><p>But forward to 2022 and the tables have turned: Citra&apos;s shortcomings have become more present in people&apos;s minds, and its various Android builds have not been as actively developed as many hoped. Is it time for another contender after all? Maybe! Canceling all the exciting work items that had been in the pipeline in 2020 never quite felt right anyway.</p><p>Which is why I&apos;m happy to announce: Mikage development has resumed! We&apos;ve silently (or not so silently for the <a href="https://twitter.com/MikageEmu/status/1497240892373184518">Twitter</a> folks) been picking things up again back in February and made big leaps forward already. Curious what&apos;s in store for you? Superboosted performance (allowing 60 FPS gameplay in many titles!) and a new port of the emulator to PC! Here&apos;s a sneak preview of the new shader recompiler and other goodies:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/6NqM6mh_FL4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>60 FPS real-time game play with Mikage in <em>The Legend of Zelda: Ocarina of Time 3D</em></figcaption></figure><p>Of course we also worked on game compatibility, thus extending the set of compatible titles a lot compared to the limited selection supported previously! Here are just a few of them:</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2022/04/mikage_220321_animalcrossing.png" width="400" height="480" loading="lazy" alt="It&apos;s time to renew 3DS emulation: We&apos;re back!"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2022/04/mikage_220315_zeldamm3.png" width="400" height="480" loading="lazy" alt="It&apos;s time to renew 3DS emulation: We&apos;re back!"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2022/04/220410_titlescreen2.png" width="400" height="480" loading="lazy" alt="It&apos;s time to renew 3DS emulation: We&apos;re back!"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2022/04/2022_03_27_vvvvvv.png" width="400" height="480" loading="lazy" alt="It&apos;s time to renew 3DS emulation: We&apos;re back!"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2022/04/20220416_ingame3.png" width="400" height="480" loading="lazy" alt="It&apos;s time to renew 3DS emulation: We&apos;re back!"></div></div></div><figcaption>Mikage&apos;s ever-improving compatibility: From big titles to indie games and old classics!</figcaption></figure><p>And all that is just the tip of the iceberg. In 2022, Mikage is going full in on preserving the <em>full experience</em> of the 3DS platform. There&apos;s so much to talk about, and you&apos;re probably asking yourself: What does it all lead up to? Right now we just wanted to say we&apos;re alive and kicking again, but we&apos;ll have more announcements for you in the future. To stay in the loop make sure to follow our progress on <a href="https://twitter.com/MikageEmu">Twitter</a> and <a href="https://www.youtube.com/channel/UCZvKZL-VpZWYcyV0Vy5N6kw">YouTube</a>, and spread the word that the 3DS emulation landscape is once again changing big time!</p>]]></content:encoded></item><item><title><![CDATA[Good Bye, Friends [2022 Update: We're back!]]]></title><description><![CDATA[2022 UPDATE: MIKAGE IS NO LONGER ON HIATUS! Previous version of this announcement:

The 3DS community has spoken: There is no sufficient demand to fund development of a high-quality 3DS emulator for Android. Public Mikage development is put on an indefinite hiatus. This is a good-bye letter.]]></description><link>https://mikage.app/good-bye-friends/</link><guid isPermaLink="false">5f37bf4aff4e4e12d9472adf</guid><category><![CDATA[Announcement]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Sat, 15 Aug 2020 17:13:50 GMT</pubDate><media:content url="https://mikage.app/content/images/2020/08/matt-hardy-unsplash-80.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2020/08/matt-hardy-unsplash-80.jpg" alt="Good Bye, Friends [2022 Update: We&apos;re back!]"><p>I&apos;m sure some of you are getting ready to object; no sufficient demand for a 3DS emulator? Let me elaborate.</p><p><em>UPDATE: Since the release of this post, development has been picked up again. Expect more news in the future!</em></p><h1 id="how-did-we-get-here">How did we get here?</h1><p>Mikage&apos;s mission was simple: A high-quality emulator that &quot;just works&quot; with minimal configuration yet excellent performance, bundled in a pleasant-to-use interface. DraStic but for the 3DS. The core premise to enable all of this: Full-time funding of an experienced professional who previously worked on gold-standard projects such as Dolphin and PPSSPP.</p><p>How do you even approach this? One typical way is ads. Another one is microtransactions. And then there&apos;s rebundling existing projects (hello MMJ). While (regrettably) widely accepted in the community, it was important to me that Mikage would do without any such shady compromises.</p><p>Many criticized Mikage&apos;s Patreon approach, but the truth is: Nobody came up with something better. Even ignoring &quot;Just do X&quot;-esque suggestions that clearly didn&apos;t consider the numbers involved in the first place, proposals like &quot;Just put it on the Play Store&quot; or &quot;Just use ads&quot; weren&apos;t an option. Doing things ethically has been of upmost priority to me, culminating in a 7-digit investment offer I received from a VC company - which I declined.</p><p>If Mikage&apos;s success depended on breaking my ethical code, it wasn&apos;t <em>really</em> a success in my book. If the honest approach wasn&apos;t going to work out, then so be it.</p><p>And well, that&apos;s where we are: It would be a lie to claim the Patreon campaign brought in any significant income that enabled me to work on Mikage any longer than without. Frankly, considering all the marketing overhead it has been a negative investment. I&apos;ve been working on 3DS emulation <em>pro bono</em> for several years now, and it&apos;s been enough.</p><h1 id="a-turning-point">A turning point</h1><p>Since 2020, response to the various progress reports and other updates visibly declined, and so it became clear the Patreon route just wasn&apos;t going to cut it. Even the biggest milestone to that point, <a href="https://www.youtube.com/watch?v=w7fls3C1ZiE">Super Mario 3D Land being functionally playable</a>, brought in virtually no new supporters. Imagine spending a whole month on preparing such a big announcement, and all you get out of it is 100 bucks.</p><p>The truth is, everybody wants a great 3DS emulator, but the fewest are willing to contribute towards a mere promise, no matter how convincing the argument. It doesn&apos;t help that the Android market is diluted with so many cheap $1 apps (most developed in few weeks) that emulators frankly can&apos;t be sold at fair prices. No matter if Mikage had been priced at $15, $50, or $200 - you&apos;ll bet either of them would&apos;ve triggered massive outcries.</p><p>Then, [vaguely waves hands around] happened, so Mikage development at least was a nice way to spend the whole social distancing thing. Much to the benefit of Mikage&apos;s performance: Optimizing its GPU core significantly yielded a 3x frame rate improvement in e.g. the Zelda games, which are actually fully playable at 60 FPS on PC hardware now. I also got a couple of new games running in a playable state, notably <em>Animal Crossing: New Leaf</em>.</p><p>But it&apos;s no use.</p><h1 id="what-s-next">What&apos;s next?</h1><p>Mikage is a closed chapter for me now. It was one of the most challenging projects I&apos;ve tackled in my career, and I&apos;m glad about all the lessons it taught me and the technologies I had a chance to pick up along the way. Ultimately though with the commercial prospects written off, the project has served its purpose as far as personal interests go.</p><p>Under the hood, Mikage is a genuine masterpiece of software engineering. This goes beyond the &quot;my code is so nice and clean&quot; you&apos;ll hear any excited developer say: Where Mikage really shines is the technical foresight about long-term problems and its sophisticated solutions to address them, resulting in a powerful infrastructure to find and debug emulation issues quickly, ultimately making for a better user experience due to fewer game bugs. Imagine your game is broken, but instead of spending weeks of debugging the problem, the emulator essentially tells you were the problem lies right away.</p><p>One of my long-term plans for Patreon had been to fund blog posts to actually talk about this infrastructure and other elements of Mikage&apos;s code architecture, similar to Dolphin&apos;s Progress Reports but on a more technical level. If I kept the Patreon running I could write one of these about every 3 months - let me know if that&apos;s something you&apos;d be interested in seeing!</p><p>Before I close I do want to apologize for the late statement on this, particularly to my patrons who up to this very point have supported me despite the lack of updates in the last few weeks. I had written several versions of this article but just never quite found the right words. Since I obviously couldn&apos;t deliver on my promise, please shoot me a Patreon PM if you&apos;d like your recent pledges refunded. Of course I wish there were a more satisfying outcome here, but that&apos;s the least I can do.</p><p>Meanwhile, I&apos;ve moved on to my next journey: <a href="https://twitter.com/fail_cluez/status/1288128556485283843">Open-source graphics drivers for Linux</a>, the kind of thing I dreamed of doing as a teenager but never imagined would actually happen. I&apos;m incredibly excited about this opportunity to improve the Linux gaming experience for gamers around the world.</p><p>It&apos;s been a fun ride, emulation community. Thanks for having me.</p><p>All the best!</p>]]></content:encoded></item><item><title><![CDATA[A Retrospective: Super Mario 3D Land]]></title><description><![CDATA[March's big news: Mikage can now run Super Mario 3D Land! Here's how we went from fixing error messages over to garbled rendering to almost perfect game visuals.]]></description><link>https://mikage.app/retrospective-super-mario-3d-land/</link><guid isPermaLink="false">5eb9532a1355230c78d9e907</guid><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Tue, 12 May 2020 22:46:52 GMT</pubDate><media:content url="https://mikage.app/content/images/2020/05/thumbnail.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2020/05/thumbnail.jpg" alt="A Retrospective: Super Mario 3D Land"><p>March&apos;s big news: Mikage can now run Super Mario 3D Land! Perhaps you&apos;ve already seen our <a href="https://youtu.be/w7fls3C1ZiE">gameplay video</a> about it; what the video didn&apos;t show is just how much sophisticated work went into that title alone, so we figured it&apos;s a good time to show you the various steps of iteration from error messages over to garbled rendering to almost perfect game visuals.</p><h2 id="in-the-beginning-there-was-nothing">In the Beginning, there was Nothing</h2><p>The first sign of life Super Mario 3D Land showed in Mikage was back in July 2019: A title logo with just-kinda the right colors. One fix in the code that handles RGB565 framebuffer data transfers (<em>&quot;display transfers&quot;</em>) later, it&apos;s rendering fine:</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/05/2019_07_08_titlescreen_sm3dl-1.png" width="400" height="480" loading="lazy" alt="A Retrospective: Super Mario 3D Land"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/05/2019_08_10_titlescreen_sm3dl_rgb565fix-3.png" width="400" height="480" loading="lazy" alt="A Retrospective: Super Mario 3D Land"></div></div></div><figcaption>First signs of life in Super Mario 3D Land</figcaption></figure><p>While this achievement looks simple on the surface, getting a game to draw anything is really the biggest hurdle from a development perspective: After all, how do you debug a game that simply doesn&apos;t do anything?</p><h2 id="a-title-screen">A Title Screen</h2><p>Of course, a blocker was found quickly, and so the game didn&apos;t make it past the initial setup dialogs. There were some obvious and some <a href="https://mikage.app/development-update-4/#progress-on-super-mario-3d-land">not-so-obvious features</a> not implemented in Mikage. Eventually though, we succeeded and got this beauty of a title screen:</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2020/05/2019_08_28_titlescreen_sm3dl-1.png" class="kg-image" alt="A Retrospective: Super Mario 3D Land" loading="lazy"></figure><p>All the rendering glitches notwithstanding, what&apos;s really cool about this picture is what&apos;s happening on the top screen behind the game logo: Look closely, it&apos;s actually rendering the 3D graphics properly! For instance the geometry of the block in the top right corner is completely fine.</p><p>Debugging issues with 3D geometry can be a royal pain, so seeing it just work meant that fixing the rendering for good was within close reach. But there was another roadblock that had to be dealt with first...</p><h2 id="command-processor-fixes">Command Processor Fixes</h2><p>Shortly after entering the title screen, the game would randomly freeze up for no apparent reason. This hadn&apos;t always been the case, but at some point it just started doing so.</p><p>SM3DL likes to keep the 3DS GPU busy while doing processing on the CPU, and hence schedules a <em>lot</em> of work using command lists that call other command lists. Technically there&apos;s just one a primary list that calls smaller, secondary lists, which then return back to the primary one after processing. However, &#xA0;since there&apos;s no equivalent of a call stack, all return offsets are hardcoded in the command lists themselves, and hence it&apos;s equivalently just one huge pile of nested command lists calls.</p><p>My first command processor implementation struggled with this: While handling secondary command lists using a C++ function call each worked for most games, for SM3DL it leads to such deep recursion that the game eventually ran out of stack space.</p><p>Luckily, this was the only thing that caused unpredictable crashes in the game - after fixing my implementation to use a non-recursive algorithm, the game was rock-solid!</p><h2 id="fast-forward">Fast Forward</h2><p>A couple of weeks later, many more fixes had landed, most notably the <a href="https://mikage.app/progress-report-august-december-2019/#rendertargetcache-revamp">Render Target Cache Revamp</a>. Some of the graphics fixes were fixed to the point you could recognize the 3D geometry better now:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/05/2019_11_23_titlescreen_sm3dl_2_cropped.png" class="kg-image" alt="A Retrospective: Super Mario 3D Land" loading="lazy"><figcaption>No more glitchy blue graphics! But oh no, where did the floor go?</figcaption></figure><p>Super cool! Somehow the geometry is missing colors though, and we somehow lost all environment graphics along the way. A couple of days later I at least managed to make the characters render properly:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/05/2019_11_24_titlescreen_sm3dl_2_cropped.png" class="kg-image" alt="A Retrospective: Super Mario 3D Land" loading="lazy"><figcaption>Seeing your character is good enough to play the game, right? :)</figcaption></figure><h2 id="stencil-support">Stencil Support</h2><p>So what&apos;s up with the missing environment graphics? Luckily, I stumbled upon a <a href="https://github.com/citra-emu/citra/issues/1039">Citra issue</a> from back in the day that shows a screenshot resembling Mikage&apos;s output very closely. As the issue points out, the background will be rendered in grey unless a feature called stencil testing is implemented.</p><p>Adding support for stencil testing was a bit involved, taking a full day or two. But it is a good example of how one change can make the difference between almost nothing working at all and an essentially playable game:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/05/2020_01_04_titlescreen_sm3dl_stencil_2_cropped-1.png" class="kg-image" alt="A Retrospective: Super Mario 3D Land" loading="lazy"><figcaption>Wow! The perfectly rendered environment was just hidden by missing stencil testing support</figcaption></figure><h2 id="meanwhile-on-the-bottom-screen">Meanwhile, on the Bottom Screen</h2><p>You&apos;d think with the top screen graphics being essentially perfect at this point, the 2D bottom screen graphics would just work easily, but nope. Due to missing support for decoding textures in the RG8 format, the UI elements displayed in a weird overlaid fashion. After extending the texture decoder, the bottom screen renders fine too!</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/05/2020_01_04_titlescreen_sm3dl_stencil_2.png" width="401" height="480" loading="lazy" alt="A Retrospective: Super Mario 3D Land"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/05/2020_01_04_titlescreen_sm3dl_stencil_2_fixedbottom.png" width="401" height="480" loading="lazy" alt="A Retrospective: Super Mario 3D Land"></div></div></div><figcaption>Thanks to RG8 texture support (right side), the bottom screen looks much better!</figcaption></figure><h2 id="applet-fixes">Applet Fixes</h2><p>We&apos;re getting there; the title screen displays just fine, Mario is running across the screen, all the objects show up just fine. But then you press A to select a save file, and argh - the game freezes up for no apparent reason! What&apos;s worse, the prototyping branch of Mikage&apos;s source code worked just fine. </p><p>When your work-in-progress fixes things it wasn&apos;t meant to, ironically that often uncovers yet more work to do: What fixed the issue, and why? Is it a proper fix or did I just accidentally change emulation behavior? What&apos;s left for a proper solution? Granted, at least it gave me a starting point for debugging the lockups, and eventually I found the culprit: Emulation of Nintendo&apos;s <em>applet</em> system.</p><p>On the 3DS, the applet system manages the various applications that run on the system (primarily the active game, but also the Home Menu and the browser), and it also manages the transition from one to another (such as when Home Menu launches a title). Game emulation requires only a small subset of this system, but it turns out Mikage&apos;s early implementation was a bit too simple. Given this opportunity for sorting things out, I decided to move a full rewrite on the priority list to fully support applets.</p><p>... which wasn&apos;t such an easy task, it turned out: Info on the applet system is scattered among many different places, each of which only contains a piece of the picture: Between 3dbrew, libctru sources, and Citra, no source does a really good job of conveying the underlying ideas. Piecing it all together into a coherent architecture took a lot of work, but luckily also means that Mikage&apos;s implementation is rock-solid now and won&apos;t run into major issues anytime soon. Meanwhile, the applet system also paves the way for other exciting work I&apos;ll be addressing in a future Progress Report.</p><h2 id="unimplemented-features">Unimplemented features</h2><p>Of course, that wasn&apos;t all - at any point of progress, there&apos;s a &quot;boring&quot; period of watching Mikage try to run the game and fail quickly due to the game using a feature not yet implemented in the emulator. This happens <em>a lot: </em>Mikage tries really hard to detect &quot;unexpected&quot; configurations, and immediately errors out instead of &quot;hoping for the best&quot; like many other projects do.</p><p>So really, sometimes it&apos;s just all about running the game and implementing whatever feature Mikage is complaining about. If you look at the <a href="https://mikage.app/changelog/v0_4.html">changelogs</a>, many of the fixes listed there are about this. A missing system module interface, a graphics rendering configuration, or an unimplemented CPU instruction.</p><p>Granted, tackling these things one by one instead of implementing features all in one go usually doesn&apos;t make a difference in 90% of the games I test, but for the other 10% it easily saves <em>days</em> of debugging time. And it gives me confidence that the supported features are &quot;correct enough&quot;, meaning there are no glaring issues that could require a major rewrite.</p><p>Of course, there&apos;s the occasional exception to ensure Mikage keeps visibly progressing, such as for purely cosmetic features like <em>fragment lighting</em>, as required by Super Mario 3D Land.</p><h2 id="success-">Success &#x1F389;&#x1F389;&#x1F389;</h2><p>Finally, we&apos;re done: The game is functionally playable! It&apos;s always a thrill to watch the intro cutscene, crossing fingers that the emulator doesn&apos;t hit <em>yet</em> another missing feature, and eventually make it through for good. This is the point where it&apos;s time to take a break, pat yourself on the back, and just enjoy the game for a moment.</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/05/Screenshot_20200410_164014.png" width="400" height="240" loading="lazy" alt="A Retrospective: Super Mario 3D Land"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/05/Screenshot_20200410_164221.png" width="400" height="480" loading="lazy" alt="A Retrospective: Super Mario 3D Land"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/05/Screenshot_20200410_164252.png" width="400" height="240" loading="lazy" alt="A Retrospective: Super Mario 3D Land"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/05/Screenshot_20200410_164458.png" width="400" height="480" loading="lazy" alt="A Retrospective: Super Mario 3D Land"></div></div></div></figure><h2 id="oh-no-more-problems-">Oh no, more Problems!</h2><p>Of course, the job is never really done. While the game has been functional since January, not all is perfect: </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/05/2020_04_22_etc1_fix_before_cropped-1.png" class="kg-image" alt="A Retrospective: Super Mario 3D Land" loading="lazy"><figcaption>Looks like the mail has been through a rough shipping!</figcaption></figure><p>... and then there&apos;s this hilarious problem with the ground geometry ...</p><figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/COwZqM_o49E?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>... and let&apos;s just not talk about this one ...</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/05/2020_04_22_mario_glitch_face_cropped-1.png" class="kg-image" alt="A Retrospective: Super Mario 3D Land" loading="lazy"><figcaption>Uhm, Mario, are you alright?</figcaption></figure><h2 id="cliffhanger">Cliffhanger</h2><p>Of course, I knew releasing a video with these glaring issues wouldn&apos;t be particularly impressive. Hence stay tuned for the next Progress Report to see how I fixed them ;)</p><p>I hope you enjoyed this little digression from the usual program. As usual, thanks for your support and stay safe!</p>]]></content:encoded></item><item><title><![CDATA[Gameplay video: Super Mario 3D Land]]></title><description><![CDATA[<p>Yes! You&apos;re reading that right: Super Mario 3D Land is now (functionally) playable on Android via Mikage :)</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/w7fls3C1ZiE?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>I&apos;ll publish a write-up of this exciting development progress next week, and I&apos;ll also push the next alpha release soon so you can try the game out</p>]]></description><link>https://mikage.app/mikage-gameplay-video-super-mario-3d-land/</link><guid isPermaLink="false">60e6f1a4226ab9048c5b0cd1</guid><category><![CDATA[Gameplay Video]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Sat, 18 Apr 2020 16:23:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2021/07/thumbnail.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2021/07/thumbnail.jpg" alt="Gameplay video: Super Mario 3D Land"><p>Yes! You&apos;re reading that right: Super Mario 3D Land is now (functionally) playable on Android via Mikage :)</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/w7fls3C1ZiE?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>I&apos;ll publish a write-up of this exciting development progress next week, and I&apos;ll also push the next alpha release soon so you can try the game out for yourself.</p><p>Until then, stay safe!</p>]]></content:encoded></item><item><title><![CDATA[Development Update 10: A teaser!]]></title><description><![CDATA[<p>It&apos;s been a while since I announced new titles that now work in Mikage, so I figured I&apos;d make up for that by announcing a big one ;)</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164014.png" width="400" height="240" loading="lazy" alt></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164044.png" width="400" height="240" loading="lazy" alt></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164128.png" width="400" height="240" loading="lazy" alt></div></div></div></figure><p>Super Mario 3D Land is now functionally playable! Yes, you read that right - it gets past the title</p>]]></description><link>https://mikage.app/development-update-10-a-teaser/</link><guid isPermaLink="false">60e6f024226ab9048c5b0caf</guid><category><![CDATA[Development Update]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Fri, 10 Apr 2020 15:49:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2021/07/Screenshot_20200410_164014-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164014-1.png" alt="Development Update 10: A teaser!"><p>It&apos;s been a while since I announced new titles that now work in Mikage, so I figured I&apos;d make up for that by announcing a big one ;)</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164014.png" width="400" height="240" loading="lazy" alt="Development Update 10: A teaser!"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164044.png" width="400" height="240" loading="lazy" alt="Development Update 10: A teaser!"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164128.png" width="400" height="240" loading="lazy" alt="Development Update 10: A teaser!"></div></div></div></figure><p>Super Mario 3D Land is now functionally playable! Yes, you read that right - it gets past the title screen, plays back the entire intro sequence, and you can actually play the game.</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164221.png" class="kg-image" alt="Development Update 10: A teaser!" loading="lazy"></figure><p>Suffice to say I&apos;m extremely happy with this result. It was actually back in January that I realized how close the game was to getting ingame (bearing major artifacts), but then things improved bit by bit until eventually the game rendered almost perfectly!</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164252.png" width="400" height="240" loading="lazy" alt="Development Update 10: A teaser!"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164301.png" width="400" height="240" loading="lazy" alt="Development Update 10: A teaser!"></div></div></div></figure><p>Other than two small (but very important) bug fixes, all changes required to get this game into this state were about implementing new things (most notably stencil testing, but lots of minor stuff too). This is a good thing: Rather than spending my time fixing code I&apos;ve already written, Mikage&apos;s solid foundation allows us to add more comprehensive emulation and progress towards broader game compatibility.</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164458.png" width="400" height="480" loading="lazy" alt="Development Update 10: A teaser!"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2021/07/Screenshot_20200410_164656.png" width="400" height="480" loading="lazy" alt="Development Update 10: A teaser!"></div></div></div></figure><p>I&apos;ll prepare a video of Super Mario 3D Land in action over the weekend, but I figured I&apos;d share the news here first :)</p>]]></content:encoded></item><item><title><![CDATA[Mikage Progress Report: January + February 2020]]></title><description><![CDATA[<p>We have another update in store, this time with major optimization work going on and of course the obligatory compatibility improvements. Let&apos;s dive right in!</p><h2 id="aarch64-jit-for-super-fast-cpu-emulation">AArch64 JIT for super-fast CPU emulation</h2><p>Every emulator project has to start somewhere, and in terms of CPU emulation that&apos;s usually</p>]]></description><link>https://mikage.app/progress-report-january-february-2020/</link><guid isPermaLink="false">5e7a20c91355230c78d9e76c</guid><category><![CDATA[Progress]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Tue, 24 Mar 2020 17:29:05 GMT</pubDate><media:content url="https://mikage.app/content/images/2020/03/2020_01_07_titlescreen_sd_subwars_top-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2020/03/2020_01_07_titlescreen_sd_subwars_top-1.png" alt="Mikage Progress Report: January + February 2020"><p>We have another update in store, this time with major optimization work going on and of course the obligatory compatibility improvements. Let&apos;s dive right in!</p><h2 id="aarch64-jit-for-super-fast-cpu-emulation">AArch64 JIT for super-fast CPU emulation</h2><p>Every emulator project has to start somewhere, and in terms of CPU emulation that&apos;s usually an interpreter core: Easy to get early results from, with little complexity, and adaptable when surprising hardware behavior is discovered. The big weakness of interpreters is performance: Emulating every 3DS CPU instruction with a C++ function call flat out isn&apos;t going to run at great speeds.</p><p>A more performant solution is called Just-In-Time binary translation (commonly abbreviated to JIT in emulation circles), where you disassemble and recompile functions executed by an emulated game to equivalent binary code that can be executed on the target device (i.e. your phone). This method of CPU emulation can provide massive speedups (up to 10x) depending on the situation, so logically I assigned high priority to the JIT on Mikage&apos;s roadmap.</p><p>That said, writing a JIT is a complex undertaking, certainly not something you can pull off in a couple of days and immediately collect fruits of labor from. It takes dedicated experimentation and research over several weeks, and then there are still several components that need to be written independently. I announced my early tinkering with JITting back when the project was <a href="https://mikage.app/hello-mikage/">announced</a>, having been working secretly on it until it was ready for a general showcase.</p><p>And finally, it&apos;s here: The first JIT-enabled Mikage release shipped in February! The translation process doesn&apos;t cover the entire ARM instruction set yet, so it will be another couple of weeks until all comercial games benefit from the JIT. But the potential is very visible in <em>yeti3DS</em> and <em>Retro City Rampage DX</em> - the former getting a mind-blowing 650% framerate improvement! See for yourself:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="480" height="270" src="https://www.youtube.com/embed/edHTV80ELhY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>yeti3DS runs at 7.5 times the interpreter&apos;s framerate now!</figcaption></figure><p>Of course, this JIT is just the basis to build on, and it will be refined and extended over the coming weeks to make sure the speedups translate to all other titles as well.</p><p>If you&apos;re curious about the inner workings of this new JIT, I shared a more technical overview in <a href="https://mikage.app/development-update-9/">Development Update 9</a>.</p><h2 id="interpreter-speedups">Interpreter speedups</h2><p>In preparing the JIT, I had to rework the interpreter&apos;s instruction dispatcher so it could be used as a fallback by the JIT for instructions it doesn&apos;t cover yet. The new dispatcher replaces some ugly logic with a much neater approach that also happens to improve performance a little.</p><p>If you&apos;ve seen my professional work, you&apos;ll know I&apos;m a big proponent of applying C++ <em>metaprogramming</em> when a good chance comes about. In this case, going through the cumbersome process of decoding ARM instructions manually was very error-prone and led to unnecessary branching within the code that would lead to slow interpretation. There is now a simple table that describes the various ARM opcodes, and we have the C++ compiler conveniently generate a lookup table from that, which can be used to map a CPU instruction&apos;s binary encoding to the interpreter&apos;s instruction handler. Very convenient and fast :)</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/03/2020_01_07_arm_meta.png" class="kg-image" alt="Mikage Progress Report: January + February 2020" loading="lazy"><figcaption>This new dispatch table allows for cleaner and faster CPU emulation</figcaption></figure><h2 id="new-challenger-approaching-steel-diver-sub-wars">New challenger approaching: <em>Steel Diver: Sub Wars</em></h2><p><em>Steel Diver: Sub Wars</em> now reaches the title screen! Other than many small fixes, I uncovered two major bugs:</p><ul><li>When emulating IPC requests, Mikage considered it an error when a game provided a zero-sized buffer. After all, if you&apos;re asking the system to do work, why would you request no data to be returned? Well, my educated guess is that it was just the easier thing to do in the game&apos;s source code, so the programmers just opted for leaving these seemingly pointless requests in. It took some creativity to find a clean way of supporting zero-sized buffers, but these games now won&apos;t error out anymore.</li><li>During startup, Steel Diver requests a memory transfer (&quot;DMA&quot;) from a seemingly unknown memory address. It turns out this was a bug in the GSP emulation, where DMAs were assumed to refer to memory with process-agnostic virtual-to-physical address mapping. By referring to the game&apos;s own memory space instead, the input memory address is recognized properly and hence the DMA runs through just fine now. Ironically, Citra got this wrong too: They implemented what was easiest (and correct, in the common case) and eventually concluded it was incorrect behavior, leaving <a href="https://github.com/citra-emu/citra/blob/62e6c147ae6e02cad3a892f05878f13c9fa596fe/src/core/hle/service/gsp/gsp_gpu.cpp#L498" rel="nofollow noopener">a note in the source code</a> suggesting to move to the wrong behavior in the future.</li></ul><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2020/03/2020_01_07_titlescreen_sd_subwars_top.png" class="kg-image" alt="Mikage Progress Report: January + February 2020" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2020/03/2020_01_23_menu_sd_subwars_cropped.png" class="kg-image" alt="Mikage Progress Report: January + February 2020" loading="lazy"></figure><p>As you can guess, these issues by no means only affected Steel Diver. I&apos;ll have more news in the next Progress Report about other titles :)</p><h2 id="better-graphics-in-zelda-oot3d-others">Better graphics in Zelda OoT3D &amp; others</h2><p><em>The Legend of Zelda: Ocarina of Time 3D</em> and <em>Nano Assault EX</em> got a nice update to their visuals: You might have noticed various objects to look a bit <em>dull</em> or <em>boring</em> compared to how they look on hardware. And indeed, this was because Mikage didn&apos;t implement a feature called <em>texture combiner scalers</em>!</p><p>Adding support for this feature luckily wasn&apos;t too difficult and the games now look fantastic. See for yourself:</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2020/03/2020_01_02_ingame_oot3d_tevscalers.png" class="kg-image" alt="Mikage Progress Report: January + February 2020" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2020/03/2020_01_07_ingame_nanoassault_tevscalers-1.png" class="kg-image" alt="Mikage Progress Report: January + February 2020" loading="lazy"></figure><h1 id="what-s-next">What&apos;s next?</h1><p>There&apos;s a big stream of reveals coming up, especially in terms of compatibility! Various new titles are just around the corner of being functionally playable in the next version. I&apos;m also super excited to finally announce a feature that actually has been part of Mikage ever since its early days, but for which there had never been a good chance to show it off... until very recently ;)</p><p>Meanwhile, the optimization work continues, of course. More refinements to the JIT are in progress, and there&apos;s a lot of optimizations in the pipeline for the Vulkan renderer.</p><p>That&apos;s it for now though - stay tuned for next months! Be safe, and remember to wash your hands and stay inside &#x270C;&#xFE0F;</p>]]></content:encoded></item><item><title><![CDATA[Development Update 9: Massive speedups!]]></title><description><![CDATA[<figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/edHTV80ELhY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>Compatibility improvements and fixed rendering glitches aside: What good is an emulator if everything is a slideshow? I promised to tackle the framerate issues a while ago, and the first major step towards doing so has now been completed: An AArch64 JIT.</p><p>This may come as a surprise, but I</p>]]></description><link>https://mikage.app/development-update-9/</link><guid isPermaLink="false">60e6ef79226ab9048c5b0c9a</guid><category><![CDATA[Development Update]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Thu, 13 Feb 2020 14:13:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2021/07/2020_01_07_yeti3DS-1.png" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/edHTV80ELhY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><img src="https://mikage.app/content/images/2021/07/2020_01_07_yeti3DS-1.png" alt="Development Update 9: Massive speedups!"><p>Compatibility improvements and fixed rendering glitches aside: What good is an emulator if everything is a slideshow? I promised to tackle the framerate issues a while ago, and the first major step towards doing so has now been completed: An AArch64 JIT.</p><p>This may come as a surprise, but I actually started focusing to work on this major feature back in December already, and quietly implemented feature by feature. A proper JIT requires a lot of infrastructure until it starts giving the desired speed benefits, and I didn&apos;t want to weaken the hype by announcing it in a preliminary state. Now that the pieces have fallen together, let&apos;s see what the JIT has in store for us!</p><h3 id="ir-generator">IR Generator</h3><p>At a whopping 2000 lines of code, this is the heart of the JIT: It turns ARM assembly code into an Intermediate Representation (IR) which is later compiled down to AArch64 code (or x86 on the internal development version). Mikage uses LLVM IR for this purpose, since that allows us to leverage all existing, industry-proven infrastructure around the LLVM project.</p><p>We are off to a good start: The instructions already covered by translation are the simple arithmetic ones (mov, add, ...), memory accesses (ldr, pop, ...), branches (bl, bx, ...), and some floating point operations (vneg, vmul, ...).</p><p>On top of that, there is a Thumb layer that takes care of converting Thumb instruction into something the IR generator understands. That saves us from having to translate two instruction sets at basically no cost!</p><p>There are many ARM instructions <em>not yet</em> supported by this IR generator, but luckily that need not prevent us from achieving good results.</p><h3 id="inline-interpreter-fallback">Inline Interpreter Fallback</h3><p>One critical metric for good JIT performance is the length of blocks, i.e. groups of instructions that are translated and later executed in one go. If your blocks are very short (few instructions), the overhead of translation and of the generated function prologues/epilogues will be larger than if you&apos;d run the interpreter.</p><p>Considering the sparse set of instructions translated currently, this is a real problem, and I didn&apos;t want to delay the release of the JIT just because it&apos;d run too slow without implementing the entire ARM instruction set.</p><p>There is a good solution though: Whenever the JIT hits an unknown instruction, a fallback to the interpreter core is emitted right inside the block. This allows translation to just continue afterwards without costly context switches!</p><p>A prerequisite for this approach is that the interpreter fallback may never do any control flow. Imagine the instruction branched to another address, yet what follows in the emitted block still refers to the old point of execution! So the compromise was to implement all <em>control flow instructions</em> in the JIT before this approach could be implemented, including lesser obvious ones such as `mov pc, r1` or `add pc, 40`. Luckily, that work has been done now and the interpreter fallback works superbly.</p><h3 id="analysis-prepass">Analysis Prepass</h3><p>Even with large JIT blocks, there is a big problem: Compilation latency. Each block is compiled individually, which for most games could lead to thousands of separate JIT invocations during bootup alone!</p><p>To avoid this issue, Mikage performs <em>control flow analysis</em> before invoking the JIT. It goes through all ARM instructions in the block it&apos;s about to translate, gathers a list of all branches to other blocks, and repeats the process for those blocks too. This gives the JIT gets a very clear picture about how blocks are connected and hence it can compile them all in one go. This is a massive improvement - instead of way too many separate translation processes, you&apos;ll just get a single one that compiles thousands of blocks at once.</p><p>This approach also has a few nice side benefits: For one, jumps from one block to another (such as loops, conditionals, etc) can now be translated into plain branches in the generated assembly code, where previously it needed to be an expensive function call. Furthermore, the backend can now perform control-flow optimizations such as inlining. The result of these two is the same: Much shorter and faster output assembly, and hence better performance!</p><h3 id="background-compilation">Background compilation</h3><p>Alas, while grouping blocks reduced <em>total</em> latency. It worsed <em>perceived</em> latency a lot: After all, compiling 8000 blocks at once takes a while! You wouldn&apos;t want to wait half a minute to even wait for the loading logo of your game. Something had to be done about this.</p><p>Luckily, Mikage already has a CPU engine that does not suffer from latency issues at all: The interpreter. Of course though, the whole reason I&apos;m working on the JIT is that the interpreter is <em>too slow</em>. But maybe we can have the best of two worlds?</p><p>Indeed we can! When execution hits an uncompiled block, Mikage won&apos;t immediately translate it. Instead, it <em>queues</em> the block start address for translation on a <em>background thread</em>. It doesn&apos;t really care how long that thread needs to compile the block: It temporarily uses the interpreter until execution hits a block that has already been compiled. This allows execution to continue even though the JIT is still busy.</p><p>During bootup, this means you&apos;ll notice things running significantly slower, but it&apos;s much better than the complete standstill you&apos;d have seen before. More importantly during gameplay, you can barely notice any compilation latency at all anymore.</p><h3 id="conditional-flags-management">Conditional Flags Management</h3><p>The ARM instruction set supports conditionally executing functions based on the results of a previous operation. For instance, an error handling function might be conditionally called depending on whether an error code compares equal to 0 or not. Emulating this naively implied having to decode and re-encode the conditional execution flags (&quot;NZCV&quot;) after every instruction that potentially touched them.</p><p>Suffice to say, this caused the generated assembly code to blow up quite a bit. Instead, each of the flags is managed by a dedicated IR variable now, all of which are initialized on function entry and encoded back to the NZCV flags on function exit.</p><h3 id="constant-read-optimization">Constant Read Optimization</h3><p>Memory accesses are complicated: Due to virtual memory, you can&apos;t just translate data writes in the emulated CPU to writes in the generated assembly code. Implementing the entire virtual address translation logic in assembly would be very laborious, so instead Mikage&apos;s JIT replaces memory accesses with calls to a C++ function that deals with them.</p><p>That can be very slow though; each call to C++ is a costly context switch, where the host CPU state has to be saved to memory and restored after, since the JIT can&apos;t know which registers the C++ function might modify. This is doubly concerning considering that any access to constants requires a read from memory. To reduce the cost of this effect, ReadMemory32 calls are optimized in a post-processing phase: If the read address is known to be in read-only memory, the JIT can conveniently bake the value at that address right into the generated IR instead of emitting a full-blown ReadMemory32 function call.</p><h3 id="first-results">First Results</h3><p>The video above shows before/after footage for yeti3DS, my primary benchmark for the JIT work. This may be somewhat counter-intuitive: Why optimize simple homebrew applications when proper games struggle most? The reason is that yeti3DS specifically is a very CPU-intense application since its 3D graphics are rendered without the GPU. This means CPU-side speedups translate almost equivalently into speedups in the entire emulation, without the GPU slowing us down.</p><p>And it shows: yeti3DS used to be a slideshow, running at few frames per second. One 650% improvement later we are at 50-60!</p><p>Official games of course also see a speedup, but are quickly limited by GPU emulation now. Still, Retro City Rampage DX sees a significant framerate improvement of 60%.</p><h3 id="future-prospects">Future Prospects</h3><p>Hopefully this writeup gives you a good overview of the problems I&apos;ve faced while working on the JIT. With the ground work we&apos;re in a good position for further speedups, which we&apos;ll see once the IR generator covers the ARM instruction set more comprehensively (especially in terms of floating point math).</p><p>Some elements, such as the background compilation, also give Mikage an edge over Citra: If you ever tried out any of the unofficial Citra builds with a JIT, you&apos;ll notice very heavy microstuttering. Background compilation eliminates that issue from the picture.</p><p>For the next month, I&apos;m working on optimizing some of the bottlenecks in GPU emulation such as the texture cache. Stay tuned!</p>]]></content:encoded></item><item><title><![CDATA[Mikage Progress Report: August - December 2019]]></title><description><![CDATA[<p>Hello again, it&apos;s been a while! I&apos;m sure many of you wondered what we&apos;ve been up to since there&apos;s been somewhat of a radio silence around Mikage. Suffice to say the project is alive and kicking, with hundreds of hours spent on</p>]]></description><link>https://mikage.app/progress-report-august-december-2019/</link><guid isPermaLink="false">5e32b555d2c5e70ad24b4776</guid><category><![CDATA[Progress]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Sat, 01 Feb 2020 15:33:03 GMT</pubDate><media:content url="https://mikage.app/content/images/2020/01/2020_01_30_report2-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2020/01/2020_01_30_report2-1.png" alt="Mikage Progress Report: August - December 2019"><p>Hello again, it&apos;s been a while! I&apos;m sure many of you wondered what we&apos;ve been up to since there&apos;s been somewhat of a radio silence around Mikage. Suffice to say the project is alive and kicking, with hundreds of hours spent on development since last progress report, and clearly too few on marketing :)</p><p>So what <em>have</em> we been up to? We achieved lots of user-visible progress such as fixed rendering issues and new functional games, and more importantly we sorted out a number of critical technical challenges under the hood.</p><h3 id="new-games-">New games!</h3><p>Let&apos;s get to the gist most of you will care about: What content did we manage to get running in Mikage? Among various titles reaching title screens or at least booting up, two games - <em>Nano Assault EX</em> and <em>Cave Story 3D</em> - make it past the openings and are functionally playable now! We&apos;ve released gameplay videos for both of these, so make sure to give them a watch if you haven&apos;t already.</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/01/2019_11_19_ingame_nanoassault_4_cropped.png" width="400" height="240" loading="lazy" alt="Mikage Progress Report: August - December 2019"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/01/2019_11_24_ingame_cave_story_3d_cropped-1.png" width="400" height="240" loading="lazy" alt="Mikage Progress Report: August - December 2019"></div></div></div><figcaption>New games supported in Mikage: Nano Assault EX and Cave Story 3D!</figcaption></figure><p>There wasn&apos;t any one individual, big fix that made this possible, but it&apos;s rather various big groundwork items being finished (such as the Render Target Cache revamp mentioned below) plus the accumulation of many small iterations and bug fixes, such as for instance:</p><ul><li>Implementing more configurations of the GPU&apos;s pixel pipeline, e.g. alpha blend modes or depth testing functions</li><li>Implementing texture combiner features such as the <em>texture combiner buffer</em></li><li>Supporting more FS features such as reading the game icon via the SelfNCCH archive or copying file handles (&quot;link files&quot;)</li><li>Adding 3DS configuration blocks for parental controls and EULA version</li></ul><figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/8C7fIyWifaA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>In fact, bringing up new games is straightforward in Mikage: Start the game, check the logs to see what functionality is used, and implement what&apos;s not yet emulated. The typical hour-long debugging sessions other emulator developers go through is largely unnecessary, partly because the 3DS platform is rather well understood by now, but I also like to attribute this success to good design in Mikage&apos;s emulation core: Instead of blindly accepting &quot;weird&quot; states of emulation, it&apos;ll loudly complain as soon as anything smells fishy. While sometimes a bit tedious, this prevents small inaccuracies from trickling through layers over layers of abstraction and causing unretraceable butterfly effects, and instead makes nailing down critical issues straightforward. This approach easily saved tons of hours of debugging work and allows us to focus on improving the emulator instead of fixing old, unresolved bugs!</p><figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/Rq-nUhonntU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>There has been progress on other titles too, notably <em>Super Mario 3D Land</em>. We&apos;re now reaching the title screen with the characters rendering just fine. The landscape still has some issues that I need to look at - my suspicion is that missing stencil support is the culprit. In fact, back in August I <em>did</em> have the landscape geometry rendered albeit in a corrupted framebuffer, so it&apos;s just a matter of getting it presented to the screen properly!</p><p>Another title that&apos;s showing signs of life is <em>Bravely Default</em>: We can boot the game and even start it; unfortunately playing the game won&apos;t be much fun quite yet since the top screen just stays black. I haven&apos;t had time to dig into this, so it will be interesting to figure out what exactly is going on here.</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/01/2019_11_24_titlescreen_sm3dl_2_cropped.png" width="400" height="240" loading="lazy" alt="Mikage Progress Report: August - December 2019"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/01/2019_11_19_titlescreen_bravelydefault_cropped.png" width="400" height="240" loading="lazy" alt="Mikage Progress Report: August - December 2019"></div></div></div><figcaption>Emulation progress of Super Mario 3D Land and Bravely Default</figcaption></figure><p>Finally, it&apos;s not always about the latest and shiny games, but there&apos;s also many homebrew applications Mikage needs to support. Most <a href="https://github.com/devkitPro/3ds-examples">3ds-examples</a> are now supported, and even <a href="https://github.com/smealum/portal3DS/">portal3ds</a> makes it to the title screen:</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2020/02/2019_11_24_portal3ds_cropped.png" class="kg-image" alt="Mikage Progress Report: August - December 2019" loading="lazy"></figure><h3 id="bug-fixes">Bug fixes</h3><p>It&apos;s not always about getting new games to boot - often, fixing smaller bugs in games that already work uncovers subtle issues that would&apos;ve been harder to debug in a game that outright refuses to render anything at all.</p><p>One issue that always bugged me out was the missing flame effect around the title screen logo of <em>The Legend of Zelda: Ocarina of Time 3D</em>. Thanks to Mikage&apos;s software renderer I knew the issue was with the Vulkan renderer. But it took me a rather lengthy debugging session to finally figure out the problem: The pixel shaders generated for the AddThenMultiply texture combiner operation were wrong! Instead of <code>(min(255, (rgb_in1 + rgb_in2)) * rgb_in3</code>, it said <code>min(255, (rgb_in1 + rgb_in2) * rgb_in3)</code> - note the misplaced parenthesis! The unmodified sum of <code>rgb_in1</code> and <code>rgb_in2</code> entered the multiplication instead of having it clamped first! With that issue fixed, I finally got to see the flame effect work just fine and, as a pleasant surprise, it also made the intro animation in Nano Assault EX show up!</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/02/2019_12_11_oot_flames_vulkan_previous-1.png" width="400" height="240" loading="lazy" alt="Mikage Progress Report: August - December 2019"></div><div class="kg-gallery-image"><img src="https://mikage.app/content/images/2020/02/2019_12_11_oot_flames_vulkan-1.png" width="400" height="240" loading="lazy" alt="Mikage Progress Report: August - December 2019"></div></div></div><figcaption>Thanks to the AddThenMultiply fix, the flame effect around the OoT3D logo shows up properly, making for perfect title screen emulation!</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/02/nano_fix.png" class="kg-image" alt="Mikage Progress Report: August - December 2019" loading="lazy"><figcaption>Finally we know who developed Nano Assault EX!</figcaption></figure><p>Another fun glitch are the intro logos in Cubic Ninja, which are supposed to fade in smoothly upon starting the game, but just instantly popped up when ran in Mikage. This issue affected even the software renderer, making it even more puzzling what was going on. On the other hand, reproducing the issue in the software renderer allowed me to very closely inspect every step of the rendering pipeline. Things just didn&apos;t add up: The emulator rendered things just like it was supposed to! Eventually, this was one of the few cases where comparing against Citra actually helped - running both Mikage&apos;s and Citra&apos;s software renderer in lockstep for individual pixels allowed me to catch unexpected differences in the logo rendering. Eventually, I found the root cause: The GPU register definitions for two alpha blending where off!</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/02/cn_fix.png" class="kg-image" alt="Mikage Progress Report: August - December 2019" loading="lazy"><figcaption>The embarrassingly simple fix for Cubic Ninja&apos;s intro logos</figcaption></figure><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="459" height="344" src="https://www.youtube.com/embed/6w_wjwceWIM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>Cubic Ninja&apos;s intro animation fading in properly</figcaption></figure><h3 id="rendertargetcache-revamp">RenderTargetCache revamp</h3><p>Mikage&apos;s Render Target Cache is responsible for matching raw framebuffer configurations to render targets used on the phone GPU. Ideally such a system avoids unnecessary round trips from GPU memory to emulated 3DS RAM, and this sort of caching is critical for getting any performance benefits out of hardware (Vulkan) rendering over software. Meanwhile, getting it <em>right</em> is essential to bug-free emulation without rendering glitches. In fact, Citra&apos;s early hardware renderer was <em>plagued</em> by caching issues like this, so it was important to me to address this early on.</p><p>Thanks to the work I put into the testing framework (see below), it wasn&#x2019;t too stressful to come up with a reliable rewrite of this component. As a result, not only is the RenderTargetCache itself much more readable, but I was also able to resolve various compatibility issues: Nano Assault picked up an old render target previously, causing it to crash shortly after due to an invalid viewport setup. The <a href="https://mikage.app/3ds-examples/both_screens.3dsx" rel="nofollow noopener">both_screens</a> homebrew example now renders the bottom screen as you&#x2019;d expect:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/01/2019_11_10_both_screens_rendertargetcache_revamp.png" class="kg-image" alt="Mikage Progress Report: August - December 2019" loading="lazy"><figcaption>The early render target cache struggled with this simple demo - the new one not so much!</figcaption></figure><p>Finally, the RenderTargetCache revamp removes the need for many annoying workarounds that harmed performance. Of course, the bottleneck is still largely CPU emulation, so don&apos;t expect this to do miracles to your frame rate yet. But at least the GPU now won&#x2019;t hold us back anymore either.</p><h3 id="testing-an-emulator">Testing an emulator</h3><p>Testing emulators is particularly interesting: On the one hand you want to verify your emulator is doing what it&apos;s supposed to do, and you want to ensure already verified behavior doesn&apos;t unintentionally break in a future change. This aspect of testing is absolutely <em>critical</em> to ensure emulator development keeps moving forward. Without tests, you&apos;ll run into a state where any fix you make to get a game running breaks 5 others because things become unpredictable. On the other hand, you also want a <em>research platform</em> to run against physical 3DS consoles to make sure your understanding of the emulated system is correct in the first place. Mikage&apos;s testing framework serves both of these requirements.</p><p>Unfortunately there&apos;s not much to show of the tests themselves - after all, for a correct emulator the whole point of tests is to just run through silently and pass. But <em>if</em> they do fail, such as when you&apos;re researching how a particular hardware feature works, this is the kind of output you get: </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/02/2020_02_01_fs_tests.jpg" class="kg-image" alt="Mikage Progress Report: August - December 2019" loading="lazy"><figcaption>Example of Mikage&apos;s filesystem tests failing during a research phase</figcaption></figure><p>As you&apos;ll imagine, this sort of information is very helpful during development: Quickly pinning down what line of the test sources caused an issue, including information such as C++ exception information, allows for quick iteration cycles and makes writing tests a smooth experience.</p><p>One case I applied this powerful framework on is Mikage&apos;s OpenLinkFile implementation: Link files are used to open a second &quot;view&quot; onto an already opened file on the 3DS. This is a feature many games - notably Bravely Default and Nano Assault - use internally, and they won&apos;t let you get past boot unless you implement it. But doing so posed a bit of a challenge: I didn&#x2019;t know what things games were allowed to do with them specifically, and so supporting link files properly could&#x2019;ve required either a minor adjustment or a costly rewrite. And I didn&apos;t want to just support the bare minimum required to boot games just to find another game that&apos;ll have me rewrite it all a month later!</p><p>And this is where the testing framework came to the rescue: The first thing I found was that link files only really are supported in the SelfNCCH archive (as opposed to e.g. save data or SD card contents), hence massively reducing the scope of things to test. SelfNCCH can easily be accessed from 3DS homebrew, so writing tests was straightforward in the case, and in the process I also ported the existing FS tests (which previously only checked save file archives) to cover SelfNCCH, too.</p><p>Long story short: Having tested link files on actual hardware, I can now confidently say that a simple tweak is enough to support them properly. Basing this on a scientific research process feels much better than taking a leap of faith and crossing fingers nothing will break because of it!</p><h3 id="a-new-homebrew-toolchain">A new homebrew toolchain</h3><p>3DS homebrew is a valuable tool for emulator development - not only is it really easy these days to write your own 3DS application to test your emulator with, but there already is a plethora of demos to check your emulator works with! In particular, the <a href="https://github.com/devkitPro/3ds-examples">3ds-examples</a> project covers a lot of the elementary 3DS GPU features, from basic 3D rendering to fragment lighting, up to procedural textures. Unfortunately though, not all is perfect.</p><p>Let me tell you the story of when I tried to build the 3ds-examples project for testing:</p><ul><li>I went to GitHub, downloaded the sources, and typed <code>make</code> to build the library. It doesn&apos;t work: <code>citro3d.h not found</code> is what it says</li><li>Turns out it now depends on the <a href="https://github.com/fincs/citro3d">citro3d</a> library: So I go to GitHub again, download citro3d, type in <code>make</code> to build <em>that</em> library, and luckily that works out fine</li><li>Going back to <em>3ds-examples</em> though, the <code>make</code> command still fails, now with errors related to citro3d: It turns out the project was written against an old version of citro3d, incompatible with the newer version I had just downloaded</li><li>There&apos;s no mention about what version exactly was used, so I go back and make an educated guess; after downloading and attempting to compile the old version, well... it turns out the old citro3d version doesn&apos;t build with the latest 3DS toolchain</li></ul><p>The bottom line is: To build 3ds-examples, you need to downgrade all your base libraries to versions nobody ever wrote down. It was at that point that I realized this system is too fragile to be used for Mikage!</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mikage.app/content/images/2020/01/2019_11_02_devkitneo_deptree.png" class="kg-image" alt="Mikage Progress Report: August - December 2019" loading="lazy"><figcaption>A graph of libraries needed to build 3ds-examples: Imagine keeping all of those in sync on your own!</figcaption></figure><p>Unfortunately, package management for C++ in general is rather meager: Every library may use its own build system, and there&apos;s no standardized way of declaring dependencies in a project. Luckily things are changing, and with <a href="https://conan.io/">Conan</a> there is now a feasible candidate for a C++ package manager. It&apos;s already in use by Mikage to manage dependencies such as SDL and boost across Linux and Android with ease. So back in October I started an experiment: What if we could manage 3DS libraries using Conan?</p><p>Suffice to say it wasn&apos;t quite so easy; figuring out a good way to bootstrap the toolchain itself and bundle it as a Conan package wasn&apos;t quite as straightforward as I had hoped, because <code>gcc</code> and <code>binutils</code> expect to be installed in a well-defined, global location, whereas Conan uses its own paths in the user&apos;s home folder based on hashes of the package configuration. Still though, eventually I managed to get something functional, and built on top of that. Among others, there&apos;s now packages for:</p><ul><li>a cross-compiling <code>gcc</code> targeting the 3DS&apos;s ARM11 processor</li><li><em>ctrulib</em>, the base library for 3DS homebrew</li><li><em>citro2d/citro3d</em> to render using the GPU</li><li><em>picasso</em>, tex3ds, and other tools often used to build 3DS homebrew</li><li><em>ctrtool</em>, a program to inspect 3DS application images (CCI, CXI, etc)</li><li><em>3ds-examples</em>, a suite of demo applications for 3DS functionality</li></ul><p>For now this system is merely sitting on my hard disk for use in Mikage&apos;s internal 3DS tools, but these package recipes can be useful for 3DS homebrew development too; if there&apos;s sufficient community interest I&apos;m definitely up for publishing those Conan packages in the future.</p><h3 id="open-sourcing-mikage-s-serialization-framework">Open-sourcing Mikage&apos;s serialization framework</h3><p>Serialization is the task of turning blocks of binary data into meaningful objects such as C++ structures, and vice-versa. This comes up when reading 3DS-specific file formats (such as CXI or CIA), when decoding parameters for high-level emulation of services, when interpreting command buffers for GPU emulation, and generally whenever the emulator core needs to access data structures contained in the emulated 3DS&apos;s memory.</p><p>Considering how common this task is, I grew tired of reinventing the wheel for every component it came up in. To automate all of this redundant work, I created <em>blobify</em> as part of Mikage. blobify uses advanced C++ techniques to automate serialization tasks as much as possible, and it has proven to be a very effective tool at that. To allow others to benefit from this, I decided to spend a couple of weeks on extracting blobify from Mikage&apos;s source code and turning it into a proper library that can be used in other projects, too.</p><p>I released the fruits of this work earlier today on <a href="https://github.com/neobrain/blobify">GitHub</a>. This reiterates my dedication to open-source development, and is a first (if small) step towards open-sourcing Mikage as a whole.</p><h3 id="stickers-and-36c3">Stickers and 36c3</h3><p>Hackers and security researchers gathered at the <em>36th Chaos Communication Congress</em> (or <em>36c3</em> for short) at the end of December - and it&apos;s become somewhat of a tradition for emulator developers in Europe to meet up there too! It&apos;s been a blast to meet old and new friends alike, and I can&apos;t wait to go to 37c3 in 2020. If you haven&apos;t seen it in action yet, I definitely recommend trying it out! Plus, see what cool merch you&apos;re missing out on ;)</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2020/01/2019_12_13_stickers.JPG" class="kg-image" alt="Mikage Progress Report: August - December 2019" loading="lazy"></figure><h2 id="what-s-next">What&apos;s next?</h2><p>Despite all this progress, there&apos;s lots of work left to be done! As usual, I&apos;m planning on extending the set of supported games: With the bulk of the essential 3DS features emulated by now, bringing up new games has become a task of a few days rather than a few weeks, so compatibility will improve a lot over the next few months.</p><p>With that base line, improving performance has become an increasingly important target. Mikage&apos;s internal Linux build is already running games at 60 FPS, but performance on Android is far from playable at the moment. Luckily, my experiments with a Just-in-Time recompiling CPU emulator have concluded, and I&apos;m planning on boosting GPU performance using optimizations to the texture cache and the shader processor (akin to what Citra is doing but with some special sauce).</p><p>And with that, stay tuned for future updates!</p><p>Until next time!</p>]]></content:encoded></item><item><title><![CDATA[Development Update 8: Bug fixes and speedups]]></title><description><![CDATA[<p>It&apos;s this time of the month again! If you haven&apos;t seen yet, I uploaded a new gameplay video showing off <a href="https://mikage.app/gameplay-video-cave-story-3d/">Cave Story 3D</a> earlier this month. But of course I didn&apos;t stop there, and in fact this month we got another title working in</p>]]></description><link>https://mikage.app/development-update-8/</link><guid isPermaLink="false">60e6ee76226ab9048c5b0c76</guid><category><![CDATA[Development Update]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Tue, 07 Jan 2020 18:26:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2021/07/2019_11_19_ingame_steeldiver_2-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2021/07/2019_11_19_ingame_steeldiver_2-1.png" alt="Development Update 8: Bug fixes and speedups"><p>It&apos;s this time of the month again! If you haven&apos;t seen yet, I uploaded a new gameplay video showing off <a href="https://mikage.app/gameplay-video-cave-story-3d/">Cave Story 3D</a> earlier this month. But of course I didn&apos;t stop there, and in fact this month we got another title working in Mikage.</p><h3 id="steel-diver-sub-wars-enters-its-title-screen">Steel Diver: Sub Wars enters its title screen</h3><p><em>Steel Diver: Sub Wars</em> now reaches the title screen! Other than many small fixes, I uncovered two major bugs:</p><ul><li>When emulating IPC requests, Mikage considered it an error when a game provided a zero-sized buffer. After all, if you&apos;re asking the system to do work, why would you request no data to be returned? Well, it turns out game programmers sometimes just don&apos;t mind, so that&apos;s precisely what they did. It took some creativity to find a clean way of supporting zero-sized buffers, but these games now won&apos;t error out anymore.</li><li>During startup, Steel Diver requests a memory transfer (&quot;DMA&quot;) from a seemingly unknown memory address. It turns out this was a bug in the GSP emulation, where DMAs were assumed to refer to memory with process-agnostic virtual-to-physical address mapping. By referring to the game&apos;s own memory space instead, the input memory address is recognized properly and hence the DMA runs through just fine now. Ironically, Citra got this wrong too: They implemented what was easiest and eventually concluded it was incorrect behavior, leaving <a href="https://github.com/citra-emu/citra/blob/62e6c147ae6e02cad3a892f05878f13c9fa596fe/src/core/hle/service/gsp/gsp_gpu.cpp#L498" rel="nofollow noopener">a note in the source code</a> suggesting to move to the wrong behavior in the future.</li></ul><p>As you can guess, these issues by no means only affected Steel Diver. I&apos;ll have more news next month about other titles :)</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/2019_11_19_ingame_steeldiver_2.png" class="kg-image" alt="Development Update 8: Bug fixes and speedups" loading="lazy"></figure><h3 id="gpu-texture-combiner-scalers">GPU texture combiner scalers</h3><p><em>The Legend of Zelda: Ocarina of Time 3D</em> and <em>Nano Assault EX</em> got a nice update to their visuals: You might have noticed various objects to look a bit <em>dull</em> or <em>boring</em> compared to how they look on hardware. And indeed, this was because Mikage didn&apos;t implement a feature called <em>texture combiner scalers</em>!</p><p>Adding support for this feature luckily wasn&apos;t too difficult and the games now look fantastic. See for yourself:</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/2020_01_02_ingame_oot3d_tevscalers.png" class="kg-image" alt="Development Update 8: Bug fixes and speedups" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/2020_01_07_ingame_nanoassault_tevscalers.png" class="kg-image" alt="Development Update 8: Bug fixes and speedups" loading="lazy"></figure><h3 id="new-cpu-interpreter-dispatcher">New CPU Interpreter dispatcher</h3><p>This is actually the preparation for another big feature, but implementing it went hand-in-hand with replacing some ugly logic with a much neater approach that also happens to improve performance a little.</p><p>C++ metaprogramming comes in handy again: Instead of going through the cumbersome process of decoding ARM instructions manually, there is now a simple table that describes the various ARM opcodes, and we have the C++ compiler conveniently generate a lookup table from that:</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/2020_01_07_arm_meta.png" class="kg-image" alt="Development Update 8: Bug fixes and speedups" loading="lazy"></figure><p>A quick benchmark on the CPU-heavy yeti3DS application yielded a 19% framerate improvement, which is a nice side effect for a change that wasn&apos;t even geared towards optimization!</p><h3 id="usat-emulation-fix">USAT emulation fix</h3><p>While working on the new dispatcher, I stumbled upon the cause of a long-standing bug that had been haunting me for a while: The incorrect rendering of the walls in yeti3DS!</p><p>It turns out the interpreter decoded the argument to the USAT instruction incorrectly. It&apos;s one of those things that&apos;s super easy to overlook when glancing over the source code - until you double-check against the ARM manuals and realize the decoding logic has been wrong all along.</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/2020_01_07_yeti3DS.png" class="kg-image" alt="Development Update 8: Bug fixes and speedups" loading="lazy"></figure><h3 id="looking-forward">Looking forward</h3><p>With all the fixes recently and so many new games being close to fully functional, it&apos;s finally time to make Mikage produce more than just a beautiful slide-show. I&apos;ll been working on this behind the scenes for a while now, and you&apos;ll see the first fruits of that work next month.</p><p>Stay tuned ;)</p>]]></content:encoded></item><item><title><![CDATA[Gameplay video: Cave Story 3D]]></title><description><![CDATA[<p>Hey folks!</p><p>First of all - happy new year! Mikage has kicked off 2020 with some really cool progress, but more on that later this month ;)</p><p>As for today, I figured it&apos;s time for another video, and I already teased Cave Story 3D back in <a href="https://mikage.app/development-update-7/">Development Update 7</a></p>]]></description><link>https://mikage.app/gameplay-video-cave-story-3d/</link><guid isPermaLink="false">60e6ed8b226ab9048c5b0c5d</guid><category><![CDATA[Gameplay Video]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Fri, 03 Jan 2020 17:04:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2021/07/thumbnail-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2021/07/thumbnail-1.png" alt="Gameplay video: Cave Story 3D"><p>Hey folks!</p><p>First of all - happy new year! Mikage has kicked off 2020 with some really cool progress, but more on that later this month ;)</p><p>As for today, I figured it&apos;s time for another video, and I already teased Cave Story 3D back in <a href="https://mikage.app/development-update-7/">Development Update 7</a> so why not? Here you can see me playing the game (well, trying to) to show off what&apos;s now possible with December&apos;s emulation fixes.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/Rq-nUhonntU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>There&apos;ll be more things to come in January - notably a new alpha release and, of course, another Development Update. Until then!</p>]]></content:encoded></item><item><title><![CDATA[Development Update 7: Fixing all the things!]]></title><description><![CDATA[<p>Another month, another update - let&apos;s see what December had in it for us :)</p><h3 id="new-games-">New Games!</h3><p>The big news comes first: Mikage runs another game, Cave Story 3D! Turns out after a couple of small additions and the fixes mentioned later, this game pretty much just worked out</p>]]></description><link>https://mikage.app/development-update-7/</link><guid isPermaLink="false">60e6eb57226ab9048c5b0c1c</guid><category><![CDATA[Development Update]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Wed, 11 Dec 2019 07:45:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2021/07/cave_story_3d-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2021/07/cave_story_3d-1.png" alt="Development Update 7: Fixing all the things!"><p>Another month, another update - let&apos;s see what December had in it for us :)</p><h3 id="new-games-">New Games!</h3><p>The big news comes first: Mikage runs another game, Cave Story 3D! Turns out after a couple of small additions and the fixes mentioned later, this game pretty much just worked out of the box. And for what it&apos;s worth, both the original Cave Story <em>and</em> Cave Story 3D are supported ;)</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/cave_story_3d.png" class="kg-image" alt="Development Update 7: Fixing all the things!" loading="lazy"></figure><p>I&apos;ve also given an old homebrew release a shot, smea&apos;s <a href="https://github.com/smealum/portal3DS/">portal3DS</a>. A couple of GPU features are missing to make it playable, but the menu screen is rendering mostly fine so far!</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/portal3ds.png" class="kg-image" alt="Development Update 7: Fixing all the things!" loading="lazy"></figure><h3 id="fixing-all-the-things-onto-perfect-graphics-">Fixing all the things: Onto Perfect Graphics!</h3><p>It&apos;s not always about getting new games to boot - often, fixing smaller bugs in games that already work uncovers subtle issues that would&apos;ve been harder to debug in a game that outright refuses to render anything at all.</p><p>Cubic Ninja is a good example of this: It was one of the first games supported in Mikage back in July 2019, but its opening screen would instantly pop up rather than smoothly fading in. I decided to look into the issue, and found this:</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/cn_fix.png" class="kg-image" alt="Development Update 7: Fixing all the things!" loading="lazy"></figure><p>Turns out I mixed up the GPU register definition for some of the alpha blend modes! Having fixed that issue, Cubic Ninja&apos;s intro now plays just fine:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="150" src="https://www.youtube.com/embed/6w_wjwceWIM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>A similarly subtle, but ultimately really simple issue to fix was the intro logo rendering in Nano Assault EX: I had misplaced some parentheses in the shader generated when rendering this effect, leading the computation of the AddThenMultiply texture combiner operation to return the wrong result. Voila, we finally know who created the game!</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/nano_fix.png" class="kg-image" alt="Development Update 7: Fixing all the things!" loading="lazy"></figure><p>Meanwhile, remember the <a href="https://mikage.app/development-update-5/">flame effect</a> on the title screen of The Legend of Zelda OoT 3D that was working just fine in the software renderer? The Nano Assault fix made this flame effect work in Vulkan too! A great example of how fixing a bug in one game can resolve seemingly unrelated issues in other games in one go.</p><figure class="kg-card kg-image-card"><img src="https://mikage.app/content/images/2021/07/oot_flames_vulkan.png" class="kg-image" alt="Development Update 7: Fixing all the things!" loading="lazy"></figure><h3 id="happy-holidays-">Happy Holidays!</h3><p>That&apos;s it, folks - plenty of good progress! I&apos;m planning on having the next alpha release in January, but I&apos;ll upload another gameplay video soon to make the waiting a bit easier on you. Until then, enjoy your holidays and have a great start into the new year! :)</p><p></p><p>This post was originally posted on 11 December 2019 for patrons, and released publicly on 16 January 2020.</p>]]></content:encoded></item><item><title><![CDATA[Gameplay video: Nano Assault EX]]></title><description><![CDATA[<p>As a followup to yesterday&apos;s <a href="https://mikage.app/development-update-6/">Development Update</a>, I recorded some gameplay footage to show off in more detail how great Nano Assault already runs in Mikage.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/8C7fIyWifaA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>Like I mentioned before, I&apos;m super happy to have a game with such complex graphics work in the emulator already.</p>]]></description><link>https://mikage.app/gameplay-video-nano-assault-ex/</link><guid isPermaLink="false">60e6f2e0226ab9048c5b0cec</guid><category><![CDATA[Gameplay Video]]></category><dc:creator><![CDATA[neobrain]]></dc:creator><pubDate>Wed, 20 Nov 2019 21:12:00 GMT</pubDate><media:content url="https://mikage.app/content/images/2021/07/thumbnail.png" medium="image"/><content:encoded><![CDATA[<img src="https://mikage.app/content/images/2021/07/thumbnail.png" alt="Gameplay video: Nano Assault EX"><p>As a followup to yesterday&apos;s <a href="https://mikage.app/development-update-6/">Development Update</a>, I recorded some gameplay footage to show off in more detail how great Nano Assault already runs in Mikage.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/8C7fIyWifaA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>Like I mentioned before, I&apos;m super happy to have a game with such complex graphics work in the emulator already. Hope you enjoy :)</p>]]></content:encoded></item></channel></rss>