183 lines
12 KiB
Markdown
183 lines
12 KiB
Markdown
+++
|
||
date = "2016-03-09T15:30:00-05:00"
|
||
title = "Citra Progress Report - 2015 P2"
|
||
tags = [ "progress-report" ]
|
||
author = "bunnei"
|
||
forum = 36
|
||
+++
|
||
|
||
This month we bring you the second installment of our two-part progress report on Citra in 2015! With this part, we
|
||
discuss the evolution from Citra being able to barely run a few commercial games at a few frames-per-second, to where
|
||
it is in 2016: Running many retail games at reasonable speeds, some of which are fully playable with near flawless
|
||
graphics! We discuss Citra's new "dyncom" CPU core, the OpenGL renderer, per-pixel lighting, and various bug fixes.
|
||
Lastly, we wrap up with an outlook for 2016, and a special thanks to everyone who has helped make Citra what it is
|
||
today!
|
||
|
||
## Spring 2015: A New CPU, Renderer and More
|
||
|
||
The arms race to get games booting ran into a wall. Often, testing games and getting to crash points would be incredibly
|
||
painful because of how slow the emulator ran. Instead of measuring frames-per-second, testers often referred to
|
||
seconds-per-frame. Donkey Kong Country Returns 3D would sometimes require three realtime seconds to render a single
|
||
in-game frame in the software renderer! It took over 90 minutes to capture all of the footage for a three minute video
|
||
of Super Monkey Ball 3D!
|
||
|
||
{{< youtube t0TGSeQe1wE >}}
|
||
|
||
Within the next few months, [bunnei](https://github.com/bunnei) and [Lioncash](https://github.com/lioncash) replaced
|
||
the old "ARMULATOR" CPU core in Citra with a better implementation that was both several times faster and much more
|
||
accurate. Despite the fact that it was still an interpreter, this new core was still efficient enough that the
|
||
performance implications were huge. With this new core, games that were light on graphics could reach above half-speed
|
||
on very strong processors.
|
||
|
||
Shortly thereafter, a new developer joined the Citra team – [tfarley](https://github.com/tfarley) – with the ambitious
|
||
goal of implementing a hardware renderer using OpenGL. Up until this point, Citra had used a software renderer
|
||
primarily developed by [neobrain](http://github.com/neobrain) to render graphics. While a software renderer is great
|
||
for development and achieving pixel-perfect accuracy, Citra’s GPU emulation had become the major performance
|
||
bottleneck. Even with infinitely fast CPU emulation, the software renderer was so slow that no games would run full
|
||
speed despite this.
|
||
|
||
While the rest of the team continued with other development efforts, [tfarley](https://github.com/tfarley) went on a
|
||
month-long battle developing this new OpenGL renderer. All of this resulted in Ocarina of Time 3D running nearly
|
||
perfect in Citra using OpenGL while running at a fairly decent speed! Below is a very early video of Ocarina of Time,
|
||
before the renderer was completed and merged into CItra's mainline repository.
|
||
|
||
{{< youtube Hj8sPsB5qXQ >}}
|
||
|
||
## Summer: More Accuracy, More Performance
|
||
|
||
With the summer, development slowed down a bit – but several additional improvements were made. By this point, the
|
||
team had already made lots of incremental advances in 3DS emulation, resulting in a significant number of retail games
|
||
booting, such as Super Mario 3D Land, Fire Emblem: Awakening, The Legend of Zelda: A Link Between Worlds, Mario Kart 7,
|
||
and many more.
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlyunknown1.png" center="true" >}}
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlyunknown2.png" center="true" >}}
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlycrush3d.png" center="true" >}}
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlymario3dland.png" center="true" >}}
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlysteeldiver.png" center="true" >}}
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlyluigi.png" center="true" >}}
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlylinkbetweenworlds.png" center="true" >}}
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlymajorasmask.png" center="true" >}}
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlymk7.png" center="true" >}}
|
||
|
||
{{< img src="entry/citra-progress-report-2015-p2/earlyfireemblem.png" center="true" >}}
|
||
|
||
<br></br>
|
||
But there was still one major issue that was blocking many games: video playback. 3DS games use a proprietary format
|
||
known as “MOFLEX” to play video clips, which are commonly used for intro logos, cut scenes, and more. Not only was the
|
||
video format unknown, but any time a MOFLEX video was used, Citra would hang in an infinite loop for unknown reasons.
|
||
However, this issue proved to be no match for our team – within a matter of weeks, Citra developers
|
||
[yuriks](https://github.com/yuriks) and [Subv](https://github.com/Subv) reverse-engineered and implemented all of the
|
||
mechanisms necessary to prevent hanging and play MOFLEX videos!<br></br>
|
||
|
||
{{< figure src="/images/entry/citra-progress-report-2015-p2/3.png"
|
||
alt="Bravely Default"
|
||
title="Bravely Default's intro sequence relies on MOFLEX video support" >}}
|
||
|
||
With many games now running stable with fairly accurate rendering, it became evident that with a bit more speed some
|
||
titles would not only be playable in Citra, but enjoyable to play. On top of this, more speed would make testing even
|
||
easier, so with a huge library of games now working, the task again came to making things faster.
|
||
|
||
The cause of the slowdown was very obvious: Citra’s emulation of 3DS vertex shaders. With emulators like Dolphin and
|
||
PPSSPP, your GPU uses shaders to emulate the target system’s GPU, which does not actually use any shaders of its own.
|
||
The 3DS, on the other hand, has a more modern GPU that natively supports its own shaders – which are not as trivial to
|
||
emulate in the same manner. The approach that we took was similar to CPU emulation – and we were using a pure
|
||
interpreter for the job. As such, the solution was pretty obvious; Even a naively implemented Just-In-Time (JIT)
|
||
compiler would make our shader emulation scream. With that in mind, [bunnei](https://github.com/bunnei) set out to
|
||
implement a vertex shader JIT.
|
||
|
||
While it took several weeks to develop, the difference in speed was very obvious. Vertex heavy games were sometimes two
|
||
or three times as fast, allowing some games like Ocarina of Time 3D to near full speed in many areas!
|
||
|
||
{{< youtube yhLEs4yEmlU >}}
|
||
|
||
## Autumn: Closing out the Year with a Bang!
|
||
|
||
After a brief summer hiatus, development on Citra began to pick up again with autumn 2015. While Citra now had a
|
||
library of games running without severe problems, many still relied on more advanced graphics features that had yet
|
||
to be reverse-engineered. One of these more widely used features is fragment lighting – a feature that enables complex
|
||
lighting calculations to be performed on a per-pixel basis. A major breakthrough was made when hacker and homebrew
|
||
developer fincs made major strides in figuring out the 3DS fragment lighting implementation. Immediately,
|
||
[bunnei](https://github.com/bunnei) began embodying this work into Citra.
|
||
|
||
{{< figure src="/images/entry/citra-progress-report-2015-p2/rotatecube.gif"
|
||
alt="Fragment shader test"
|
||
title="An early fragment lighting demo running in Citra" >}}
|
||
|
||
Despite that it’s not a fully complete implementation of fragment lighting, the results have significantly improved
|
||
Citra’s visuals!
|
||
|
||
{{< figure src="/images/entry/citra-progress-report-2015-p2/moonbefore.png"
|
||
title="It's a super moon!" >}}
|
||
|
||
{{< figure src="/images/entry/citra-progress-report-2015-p2/moonafter.png"
|
||
title="With fragment lighting implemented, the moon became even scarier! H-hurray?" >}}
|
||
|
||
While no more major features were merged into Citra by the turn of the year, [Subv](https://github.com/Subv) came up
|
||
with one final teaser of things to come before letting 2015 come to a close. CROs, the dynamically linked libraries of
|
||
the 3DS (similiar to DLLs on Windows), blocked several very popular 3DS games from booting in Citra, such as Pokemon
|
||
X, Y, Omega Ruby, Alpha Sapphire and Super Smash Bros. for 3DS. While the implementation was far from done, it still
|
||
was able to boot up some of the games that relied heavily on this feature.
|
||
|
||
{{< youtube 30NwGUYmIpU >}}
|
||
|
||
## Citra in 2016
|
||
|
||
With 2016 already upon us, it's shaping up to be a pretty exciting year for Citra! In addition to the many tasks
|
||
discussed in the 2015 progress reports that are still ongoing, we've got several exciting new features to look forward
|
||
to:
|
||
|
||
* [MerryMage](https://github.com/merrymage) has been making some exciting progress on an HLE implementation of the DSP,
|
||
meaning audio support may come sooner than expected!
|
||
* [tfarley](https://github.com/tfarley) has been working on a HW renderer optimization - "texture forwarding" - that
|
||
minimizes copies of textures/framebuffers to/from emulated RAM. The result of this effort will be both a performance
|
||
improvement as well as support for upscaled rendering!
|
||
* [yuriks](https://github.com/yuriks) has plans to rewrite the vertex shader JIT to fix several inherent flaws, which
|
||
will improve accuracy and address the crashing issues, as well as improved memory and IPC emulation in the kernel
|
||
HLE.
|
||
* [Subv](https://github.com/Subv) is still looking into CRO support, as well as mipmapping and scissor testing.
|
||
* [ds84182](http://github.com/ds84182) is currently working on an implementation of Pica's geometry shaders.
|
||
* [bunnei](https://github.com/bunnei) has plans to work on Circle Pad Pro (required for getting Majora's Mask in game),
|
||
CROs, and a JIT compiler for faster CPU emulation.
|
||
* [Lioncash](https://github.com/lioncash) has plans to continue working on ARM11 CPU emulation, improving both accuracy
|
||
and performance.
|
||
|
||
With all of these exciting new features upcoming, it's quite possible that 2016 might be the year that Citra becomes
|
||
official with a v1.0 release!
|
||
|
||
## Special Thanks from Bunnei
|
||
|
||
While working on this article, I found that it was easy to find major changes to write about, but that these really only
|
||
captured a fraction of the progress made in 2015 – as there was work done literally every single day to make Citra what
|
||
it is now. While I wish I could draw attention to every contribution made, that’s just not reasonable to do in one
|
||
article – so instead I’d like to personally thank each person that impacted Citra in the past year:
|
||
[Lioncash](https://github.com/lioncash), [yuriks](https://github.com/yuriks), [neobrain](http://github.com/neobrain),
|
||
[Subv](https://github.com/Subv), [archshift](http://github.com/archshift), [linkmauve](http://github.com/linkmauve),
|
||
[tfarley](https://github.com/tfarley), [purpasmart96](http://github.com/purpasmart96),
|
||
[aroulin](http://github.com/aroulin), [chinhodado](https://github.com/chinhodado),
|
||
[polaris-](https://github.com/polaris-), [zawata](http://github.com/zawata),
|
||
[kevinhartman](http://github.com/kevinhartman), [Cruel](http://github.com/cruel), [Lectem](http://github.com/lectem),
|
||
[jroweboy](http://github.com/jroweboy), [LittleWhite-tb](http://github.com/littlewhite-tb),
|
||
[Normmatt](http://github.com/normmatt), [kemenaran](http://github.com/kemenaran), [rohit-n](http://github.com/rohit-n),
|
||
[Yllodra](http://github.com/yllodra), [xsacha](http://github.com/xsacha), [darkf](http://github.com/darkf),
|
||
[filfat](http://github.com/filfat), [SeannyM](http://github.com/seannym), [uppfinnarn](http://github.com/uppfinnarn),
|
||
[Kingcom](http://github.com/kingcom), [Zaneo](http://github.com/zaneo), [wwylele](http://github.com/wwylele),
|
||
[Zangetsu38](http://github.com/zangetsu38), [Apology11](http://github.com/apology11), [Kloen](http://github.com/kloen),
|
||
[MoochMcGee](http://github.com/moochmcgee), [gwicks](http://github.com/gwicks), [vaguilar](http://github.com/vaguilar),
|
||
[chrisvj](http://github.com/chrisvj), [Sethpaien](http://github.com/sethpaien),
|
||
[Gareth422](http://github.com/gareth422), [JSFernandes](http://github.com/jsfernandes),
|
||
[esoteric-programmer](http://github.com/esoteric-programmer), [martinlindhe](http://github.com/martinlindhe),
|
||
[clienthax](http://github.com/clienthax), [ILOVEPIE](http://github.com/ILOVEPIE), [zhuowei](http://github.com/zhuowei),
|
||
[Bentley](http://github.com/bentley), [mailwl](http://github.com/mailwl), [Disruption](http://github.com/disruption),
|
||
[LFsWang](http://github.com/lfswang), [Antidote](http://github.com/antidote), [ichfly](http://github.com/ichfly).
|
||
|
||
I can’t wait to see what you guys bring for 2016!
|