BIN
site/content/entry/yuzu-progress-report-2018-p1-1/banner.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
238
site/content/entry/yuzu-progress-report-2018-p1-1/index.md
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
+++
|
||||||
|
date = "2018-07-14T08:00:00+05:30"
|
||||||
|
title = "Progress Report 2018 Part 1"
|
||||||
|
author = "CaptV0rt3x"
|
||||||
|
forum = 33660
|
||||||
|
+++
|
||||||
|
|
||||||
|
It's been a bumpy ride. We have had lots of stuff happen to yuzu and we are excited to share that
|
||||||
|
with you. Let's get started!
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
|
||||||
|
After months of research and countless hours of coding, the developers who gave you [Citra](https://citra-emu.org),
|
||||||
|
an emulator for the Nintendo 3DS, now bring to you yuzu – an experimental emulator for the Nintendo
|
||||||
|
Switch. yuzu is based off of Citra's code, with many changes tailored towards the Switch made. It
|
||||||
|
gives me great pleasure to welcome you all into the world of yuzu.
|
||||||
|
|
||||||
|
## Backstory
|
||||||
|
|
||||||
|
The Switch is the 7<sup>th</sup> major video game console from Nintendo. As the Wii U had struggled
|
||||||
|
to gain external support, leaving it with a weak software library, Nintendo opted to use more standard
|
||||||
|
electronic components to make development for the console easier.
|
||||||
|
|
||||||
|
[bunnei](https://github.com/bunnei), the lead developer of Citra, saw that the Switch hacking scene
|
||||||
|
was very active and that there were signs of the Switch's operating system, called _Horizon_, being
|
||||||
|
based on the 3DS's operating system. The Switch hacking communities ([ReSwitched](https://reswitched.tech/)
|
||||||
|
and [Switchbrew](http://switchbrew.org)) had many people working on hacking and documenting the system.
|
||||||
|
[bunnei](https://github.com/bunnei), being a _huge Nintendo fan_, was very excited at the prospect
|
||||||
|
of an emulator for Switch. Using the available documentation, [bunnei](https://github.com/bunnei)
|
||||||
|
worked on yuzu privately for a few months before other Citra developers joined him. They made some
|
||||||
|
progress and finally went public on 14 January, 2018.
|
||||||
|
|
||||||
|
{{< gifv
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/homebrew.mp4|Before (Colors are wrong)"
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/homebrew_work.mp4|After (fixed)"
|
||||||
|
>}}
|
||||||
|
|
||||||
|
{{< imgs
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/homebrew_game.png|Very first homebrew on yuzu, Space Game !!"
|
||||||
|
>}}
|
||||||
|
|
||||||
|
## Baby Steps
|
||||||
|
|
||||||
|
yuzu shares the same common and core code, with much of the same OS (operating system) HLE, with Citra
|
||||||
|
(as both OSs are similar). For the uninitiated, with HLE (high level emulation), parts of the OS are
|
||||||
|
re-implemented in the emulator, which the emulated game can call directly. This contrasts with low-level
|
||||||
|
emulation (LLE), where the hardware is emulated, and the real OS bits are run within the emulator.
|
||||||
|
Initially, [bunnei](https://github.com/bunnei) worked hard to get the Citra code base working for
|
||||||
|
Switch emulation. He updated the core emulation and Citra's memory management to work with 64-bit
|
||||||
|
addresses (as Citra emulates 32-bit apps), did lots of OS HLE, added a loader for the Switch games
|
||||||
|
/ homebrew, and integrated [Unicorn](http://www.unicorn-engine.org/) into yuzu for CPU emulation.
|
||||||
|
Unicorn was chosen at that time and not [Dynarmic](https://github.com/MerryMage/dynarmic) (which is
|
||||||
|
used in Citra) because the Switch has an ARMv8 CPU (64-bit) and dynarmic only had support for ARMv6
|
||||||
|
at that time. He got some basic SVC (Supervisor Call) implementation hooked up to begin booting some
|
||||||
|
homebrew applications and very simple games. At this time, there was no graphical output yet.
|
||||||
|
|
||||||
|
Later, [Subv](https://github.com/Subv), another Citra veteran, joined him and together they both got
|
||||||
|
framebuffer rendering support for basic homebrew. It was at this point that yuzu was announced publicly
|
||||||
|
and went open-source. As the project became open-source, many developers and reverse engineers joined
|
||||||
|
the team and as of today, yuzu is able to run 12 games. This fast paced progress is a result of the
|
||||||
|
highly active Switch hacking scene. When bunnei first started Citra (in 2014), the 3DS was already
|
||||||
|
3 years old, homebrew was barely starting to happen, and game dumps were still encrypted. Contrary
|
||||||
|
to this, Switch has a much more active hacking scene, much earlier on in the console's life-cycle
|
||||||
|
(few months). It is believed that, fueled by the successes with 3DS hacking, a lot of the same teams
|
||||||
|
and people have started working on the Switch hacking as well.
|
||||||
|
|
||||||
|
{{< imgs
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/puyo_boot.png|First game rendering triangles (actually SEGA logo) !!"
|
||||||
|
>}}
|
||||||
|
|
||||||
|
## Pit Crew & Their Efforts So Far
|
||||||
|
|
||||||
|
***Rivalry of scholars advances wisdom***. This proverb is highly accurate in terms of emulators. The
|
||||||
|
clash of knowledge between peers helps mutual growth. During its early days, Citra had a peer too,
|
||||||
|
[3dmoo](https://github.com/plutooo/3dmoo). In the case of Switch emulation, we have [Ryujinx](https://github.com/gdkchan/Ryujinx).
|
||||||
|
Our developers have worked with [gdkchan](https://github.com/gdkchan) (he main developer of Ryujinx) on
|
||||||
|
reverse engineering (RE), figuring out how games work, and how the Switch GPU works.
|
||||||
|
|
||||||
|
[Subv](https://github.com/Subv) worked on initial framebuffer rendering support, and then went on to
|
||||||
|
do lots of OS reverse engineering and bug fixes. Lately, [bunnei](https://github.com/bunnei) and him
|
||||||
|
have been working on GPU emulation. [ogniK](https://github.com/ogniK5377) (from the [ReSwitched](https://reswitched.tech/)
|
||||||
|
team) also joined us and is one of our RE experts. He has done a lot of Switch OS RE, which helps us
|
||||||
|
to get yuzu booting games further. He has contributed a lot, mostly in audio, kernel, and services.
|
||||||
|
|
||||||
|
[shinyquagsire](https://github.com/shinyquagsire), another Citra developer, came forward and implemented
|
||||||
|
user input and various other things. [Lioncash](https://github.com/lioncash) and [MerryMage](https://github.com/merrymage)
|
||||||
|
worked tirelessly on adding ARMv8 support to dynarmic, and thanks to their efforts we are now using
|
||||||
|
[dynarmic](https://github.com/MerryMage/dynarmic) for CPU emulation. Apart from these people, there
|
||||||
|
are more than a dozen contributors for yuzu who have worked on minor things. It's because of their
|
||||||
|
invaluable efforts that yuzu now proudly boasts it's ability to boot several commercial games like ARMS,
|
||||||
|
Splatoon 2, One Piece Unlimited Red Deluxe, Cave Story+, and many more. As of now, a few games are
|
||||||
|
actually playable on yuzu – Binding of Isaac, Sonic Mania, Stardew Valley, etc.
|
||||||
|
|
||||||
|
## Reverse Engineering (RE)
|
||||||
|
|
||||||
|
The RE process of yuzu is very similar to that of Citra. We collaborate with the hacking communities,
|
||||||
|
for documenting the workings of Switch and do some RE ourselves as well. It's a mix of learning and
|
||||||
|
implementing things ourselves, using community documentation to validate or guide our process. The
|
||||||
|
fact that the Switch is based on off-the-shelf Tegra SoC does not necessarily make the process easier,
|
||||||
|
because, similar to the PICA200 (3DS GPU), the Maxwell GPU architecture isn't publicly documented.
|
||||||
|
|
||||||
|
{{< imgs
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/setup.jpg|ogniK's janky RE setup"
|
||||||
|
>}}
|
||||||
|
|
||||||
|
That said, there are more resources and non-Switch related projects ([Nouveau](https://nouveau.freedesktop.org/wiki/),
|
||||||
|
[envytools](https://github.com/envytools/envytools), etc.) that we can use. Switch's GPU is many times
|
||||||
|
more advanced/powerful than 3DS', and so are the challenges in its RE. RE on the OS HLE side of things
|
||||||
|
has otherwise been the same and is moving at the same pace. We currently have a graphics renderer,
|
||||||
|
based off of Citra's graphics renderer, which uses OpenGL 4.1.
|
||||||
|
|
||||||
|
Mind you, yuzu is at a very young stage in its development. As such, any progress we make would be
|
||||||
|
only possible if we have a proper direction. Right now, most of our development is being done in a
|
||||||
|
trial-and-error manner. Simply put, we are working on making games boot and then we fix our implementations
|
||||||
|
based on further RE and any other new found info.
|
||||||
|
|
||||||
|
## OS emulation
|
||||||
|
|
||||||
|
The Switch's OS (operating system), called Horizon, is based on the 3DS's OS. This was a silver lining,
|
||||||
|
as it meant that Citra's OS HLE code could be largely reused. A point to remember, is that both Citra
|
||||||
|
and yuzu are high level emulators. In both of these, we are trying to implement the software rather
|
||||||
|
than the hardware of the consoles.
|
||||||
|
|
||||||
|
As an emulator, the first necessity in yuzu would be to load the Switch game dumps. So, [bunnei](https://github.com/bunnei/)
|
||||||
|
started working on a loader and file system service for yuzu. Citra's loader and file system frameworks
|
||||||
|
were reused and modified heavily to support Switch game dump files ([here](https://github.com/yuzu-emu/yuzu/pull/123)).
|
||||||
|
Further fixes and improvements to the loader were done by ogniK, Rozelette, gdkchan, and shinyquagsire.
|
||||||
|
|
||||||
|
Next, we would need a way for games to read or load save data. [Subv](https://github.com/Subv) believed
|
||||||
|
that the save data in the Switch has a similar behavior as the save data in the 3DS. He implemented the
|
||||||
|
file system and save data behaviors, which allowed games to read and write files to the save data directory.
|
||||||
|
([here](https://github.com/yuzu-emu/yuzu/pull/216)). This implementation allowed us to boot further
|
||||||
|
in "Puyo Puyo Tetris" and "Cave Story".
|
||||||
|
|
||||||
|
{{< imgs
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/cavestory_boot.png|First boot - Cave Story+"
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/cavestory_work.png|Now - Cave Story+"
|
||||||
|
>}}
|
||||||
|
|
||||||
|
{{< imgs
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/tetris.png|First boot - Puyo Puyo Tetris"
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/tetris_work.png|Now - Puyo Puyo Tetris"
|
||||||
|
>}}
|
||||||
|
|
||||||
|
Often, the best way to debug or RE any functionality is to use homebrew. For the uninitiated, homebrew
|
||||||
|
is a popular term used for applications that are created and executed on a video game console by hackers,
|
||||||
|
programmers, developers, and consumers. The good folks at Switchbrew created `libnx`, a userland library
|
||||||
|
to write homebrew apps for the Nintendo Switch. To support homebrew apps, written using libnx, our
|
||||||
|
developers bunnei and shinyquagsire made various fixes and finally yuzu now supports loading libnx apps.
|
||||||
|
|
||||||
|
The Switch's OS uses a lot of 'services' to provide the games with functionality which allows it to do
|
||||||
|
things like getting user input, audio output, graphics output, etc. However since the Switch hasn't
|
||||||
|
been completely reverse engineered, we still don't know how to implement some of these services.
|
||||||
|
Currently, some service calls, which we are fairly confident can be ignored, are being stubbed. Stubbing
|
||||||
|
means that these services return `ok` with no errors, so that the games think that the function
|
||||||
|
succeeded and it can continue on without getting back any valid data. As the games boot further and
|
||||||
|
further, we need to start intercepting these function calls and provide a more meaningful response.
|
||||||
|
|
||||||
|
Switch IPC (Inter-process communication) is how the OS communicates between the various services running.
|
||||||
|
This was much more robust and complicated than the 3DS's, for a lot of reasons. First of all, it does
|
||||||
|
lot more validation on responses. This means that both our service HLEs or stubs need to have the
|
||||||
|
responses be exactly what it expects with exactly right number of output parameters at right offsets,
|
||||||
|
results have to be at right offsets, data needs to be at right offsets, and a couple of other magic
|
||||||
|
fields need to be present.
|
||||||
|
|
||||||
|
{{< imgs
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/stardew.png|First boot - Stardew Valley"
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/stardew_2.png|in-game - bugs"
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/stardew_work.png|Now - Stardew Valley"
|
||||||
|
>}}
|
||||||
|
|
||||||
|
In addition to this, we have a couple of different command modes, a typical IPC request response, and
|
||||||
|
something called a _Domain_. Once a IPC session is opened to a service, the game can use this command
|
||||||
|
to turn that session into what's called a Domain. This is a more efficient way to do lots of service
|
||||||
|
calls. Our implementations were mostly iterations of learning how the IPC worked and implementing it.
|
||||||
|
After facing many issues and fixing them, we finally got things working. We then wrote a wrapper code
|
||||||
|
around this, which allows us to implement service functions without needing intricate knowledge of
|
||||||
|
how the IPC system works.
|
||||||
|
|
||||||
|
A lot of our work is based on background research the ReSwitched team did with their Switch
|
||||||
|
debug emulators, [CageTheUnicorn](https://github.com/reswitched/CageTheUnicorn) (python) and [Mephisto](https://github.com/reswitched/mephisto)(C-lang).
|
||||||
|
These emulators were designed for debugging and they implemented the Switch IPC and did most of the
|
||||||
|
work to figure that out. We thank [daeken](https://github.com/daeken) and [mission20000](https://github.com/mission20000),
|
||||||
|
authors of CageTheUnicorn and Mephisto respectively, as without their initial help and their work, we
|
||||||
|
wouldn't have gotten as far as we have.
|
||||||
|
|
||||||
|
The Nvidia services configure the video driver to get the graphics output. Nintendo re-purposed the
|
||||||
|
Android graphics stack and used it in the Switch for rendering. We had to implement this even to get
|
||||||
|
homebrew applications to display graphics. The Switch is very different from older systems, where we
|
||||||
|
could find a physical or virtual address of the framebuffer in memory and start writing to it to get
|
||||||
|
quick output. Here, we actually have to configure the OS to create a render surface and we can start
|
||||||
|
writing to it. Even the simplest homebrew had to implement this graphics layering for rendering. Subv
|
||||||
|
did most of the work to get the initial framebuffer working.
|
||||||
|
|
||||||
|
Coming to Kernel OS threading, scheduling, and synchronization fixes, most of the OS HLE for yuzu was
|
||||||
|
ported from Citra's OS implementation. As the Switch RE progressed and we learned things, we made
|
||||||
|
multiple fixes to yuzu's OS implementation. The Switch's scheduler is almost identical (if not
|
||||||
|
identical) to the 3DS's. We had to make several changes to support Switch's different synchronization
|
||||||
|
primitives but the rest if it (thus far) has been very similar and has used a similar SVC interface.
|
||||||
|
Hence we've reused Citra's code here as well.
|
||||||
|
|
||||||
|
{{< imgs
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/1-2-switch.png|First boot - 1-2-Switch"
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/1-2-switch_jap.png|Wrong Language"
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/1-2-switch_work.png|Now - 1-2-Switch"
|
||||||
|
>}}
|
||||||
|
|
||||||
|
{{< imgs
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/boi_2.png|First boot - The Binding of Issac"
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/boi.png|in-game - first renders"
|
||||||
|
"/images/entry/yuzu-progress-report-2018-p1/boi_work.png|Now - The Binding of Issac"
|
||||||
|
>}}
|
||||||
|
|
||||||
|
As we now have some games booting, the next step along the line would be adding HID (user input support).
|
||||||
|
shinyquagsire worked on getting initial HID support and made further fixes along the way. HID services
|
||||||
|
maps some shared memory region to which the games can read to, get user input state and gamepad input
|
||||||
|
writes to this. yuzu now supports handheld inputs with analog sticks and buttons. We still have a lot
|
||||||
|
to implement in HID, like support for all 9 controllers, rumble, LEDs, layouts etc., and its going to
|
||||||
|
take a bit of additional work to get it all implemented. As much of this has already been RE'd, this
|
||||||
|
is a great place for new developers to make contributions!
|
||||||
|
|
||||||
|
Currently Audio HLE is in progress, but we do not support audio playback (_yet!_). ogniK did a lot of
|
||||||
|
reverse engineering on the `AudRen` service (Audio renderer) which most games use for audio output.
|
||||||
|
There is another service called `AudOut` service, which homebrew and a few games use for audio output.
|
||||||
|
It's a much simpler service and the homebrew community figured this out. We haven't implemented this
|
||||||
|
as not many games use this. ogniK did most of the work on `AudRen` service and he pretty much figured
|
||||||
|
out how it works. This is a major breakthrough as most complicated games we have seen so far were
|
||||||
|
getting stuck, either hanging or deadlocking because they were waiting for proper `AudRen` state to
|
||||||
|
be set. ogniK's work on this helped us go further in a few other games.
|
||||||
|
|
||||||
|
Apart from the work mentioned above, we have also had minor fixes which helped us boot further in
|
||||||
|
games like Super Mario Odyssey, 1-2-Switch, and The Binding of Issac.
|
||||||
|
|
||||||
|
***Stay tuned for the next part of this report....***
|
||||||
|
|
||||||
|
<h3 align="center">
|
||||||
|
<b><a href="https://github.com/yuzu-emu/yuzu/">Contributions are always welcome !</a></b>
|
||||||
|
</h3>
|
BIN
site/content/entry/yuzu-progress-report-2018-p1-1/summary.png
Normal file
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 800 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 2.2 MiB |
BIN
site/static/images/entry/yuzu-progress-report-2018-p1/boi.png
Normal file
After Width: | Height: | Size: 634 KiB |
BIN
site/static/images/entry/yuzu-progress-report-2018-p1/boi_2.png
Normal file
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 266 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 166 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 39 KiB |
BIN
site/static/images/entry/yuzu-progress-report-2018-p1/setup.jpg
Normal file
After Width: | Height: | Size: 1,021 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 156 KiB |
After Width: | Height: | Size: 147 KiB |
BIN
site/static/images/entry/yuzu-progress-report-2018-p1/tetris.png
Normal file
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 720 KiB |