[HN Gopher] Emulating Nintendo Switch Games on Linux ___________________________________________________________________ Emulating Nintendo Switch Games on Linux Author : podiki Score : 139 points Date : 2020-07-24 14:47 UTC (8 hours ago) (HTM) web link (boilingsteam.com) (TXT) w3m dump (boilingsteam.com) | ikeboy wrote: | Some googling turns up https://github.com/PrincessAkira/road-to- | yuzu-without-switch, which doesn't require access to a switch. | Disclaimer: haven't tried this myself. | PaulBGD_ wrote: | Just a warning, this method is considered piracy. Not that I'm | placing judgement on anyone who goes his route. | popinman322 wrote: | Yeah, if you file a bug with Yuzu, or join their chat | channels and request support, and there's any hint that you | didn't use your own switch you'll be banned instantly. They | really do have a 0 tolerance policy. | saagarjha wrote: | Most projects of this sort are fairly touchy about that | kind of thing, because they're at the risk of being canned | if it seems like they are promoting piracy. | BurningCycles wrote: | For good reason, this is an emulator for a current-gen | system, and from what I've seen on Youtube, a lot of games | are fully playable. | | Companies are likely not that bothered by legacy systems | being emulated, but this is the current Nintendo flagship | console. Thankfully the Switch seems to be selling | amazingly, which should mean Nintendo don't really care | that much. | | Another factor is that you will likely need a pretty beefy | PC to play games in full speed, and compatible controllers. | ghostpepper wrote: | Not to mention that a significant portion of the value | prop of the switch is its unique hardware, and the | ability to seamlessly transfer an in-progress game | between your TV and handheld. | [deleted] | crispyporkbites wrote: | That's a lot of steps upfront to avoid any hint of piracy, but | you're almost certainly breaking the license agreement by dumping | the cartridge, so what's the point in trying to avoid piracy. | | Just because you bought a cartridge with a binary and a license | to execute that binary on a switch doesn't mean you have the | legal right to back it up and play it on your PC. | SifJar wrote: | Probably more to do with morality than lethality. Pretty | subjective, but there are definitely plenty of people who are | morally opposed to piracy but have no problem with illegal | backups/rips/dumps of stuff they have legally purchased. | saagarjha wrote: | > Just because you bought a cartridge with a binary and a | license to execute that binary on a switch doesn't mean you | have the legal right to back it up and play it on your PC. | | Do you in fact! As long as it is _your_ cartridge and you | backed it up yourself, you can legally emulate it. (You cannot | use someone else 's dump, nor can you share yours.) | gambiting wrote: | Depends where you live,but in a lot of places the ability to | make backups of your own digital media is enshrined in law. And | in EU "license agreements" are usually worth as much as toilet | paper, especially if they are implied rather than explicit | (like, saying "by using this software you agree to this | agreement" is essentially worthless, you can agree to literally | anything and it won't hold up in court) | ddevault wrote: | Of these two emulators, Ryujinx is almost certainly never going | to achieve a good level of performance, because they chose to | write it in C# of all languages. Take my advice: if you're going | to write an emulator, do it in C or C++, preferrably C. Ryujinx | is a mind bogglingly massive amount of wasted effort. | b0b_d0e wrote: | The other sibling comments were talking about general C++ vs C# | performance, but I wanna get into some emulation specific | context here that's missing. I was one of the contributors to | the yuzu project since it was first started, and so I'm fairly | familiar with the challenges of switch emulation, albeit I'm | not going to pretend like I was one of the all-star devs | responsible for making the magic happen. (I've recently stopped | contributing to the project in order to pursue other interests, | so i'm going to keep the information here general and not | specific in case somethings changed in the last month.) | | Let's start off by breaking the core performance portions of | emulation into a few broad categories. There's CPU emulation, | for running the actual guest exe, Kernel and OS emulation for | handling the system calls that games make, and GPU emulation | for translating the guest's GPU work into modern graphics API | that your PC can use. Now let's compare how language overhead | will affect each of these main scopes. | | CPU Emulation - Both yuzu and Ryujinx use JIT compilation to | recompile the guest ARMv8 instructions into x64 at runtime. The | specifics of the two emulators JITs are pretty different, and | it'd be cool to go into more details, but the mile high view is | a comparison of C# vs C++ isn't going to have much of an effect | on the runtime difference. At least not near as much | performance gap between techniques and optimization levels that | the JIT is capable of. The goal of JIT compilation for CPU code | is to remove as much interpreter overhead as possible, so if | your choice of programming language is slowing down the JIT, | that suggests that you have somewhere else to improve in the | JIT ;) | | Kernel/OS - This is the area that will have the largest | performance difference between implementation languages, but | with the major caveat that Kernel and OS emulation requires the | least amount of processing power out of the 3 categories | mentioned here. The Kernel and OS are responsible for managing | and scheduling threads, handling network connections, and etc, | but really most of these things have fairly low impact on final | application performance in comparison to CPU and GPU emulation. | As a side note, emulators aren't the only groups interested in | switch OS/Kernel work. The open source Atmosphere custom | firmware for the switch is working through recreating an open | source kernel/os for the switch, and the two emulators benefit | from their work too. (See the licensing exemptions here | https://github.com/Atmosphere-NX/Atmosphere#licensing) | | GPU Emulation - This is probably the trickiest part of Switch | emulation, and once again, it comes down to how you emulate it, | and not the language you use to write the emulator. The biggest | performance differences between the GPU emulation of the two | emulators will boil down to technique differences, and not the | programming language. GPU emulation performance can be roughly | broken into two parts, the "actual" gpu running time, and the | state management/conversion. There's only so much an emulator | can do about the actual GPU running time since at some level, | you are going to need to run the game's GPU code, but the other | half is a whole lotta code to avoid doing more work, and much | of the GPU performance optimizations goes here. Things like | managing the game's GPU memory, avoiding changing or querying | GPU state unless necessary, converting nvidia shader ASM into | SPIR-V or GLSL, and so on, are not generally going to be | bottlenecked on the emulator's language of choice, but on the | algorithms and designs that you use. Also a side note, the | average comment about how "easy" switch emulation is because of | "off the shelf nvidia parts" really misunderstands just how | much work goes into this part. Switch emulation benefits | greatly from the open source nvidia reverse engineering efforts | from teams like nouveau, and others working on open source GPU | acceleration on the switch like | https://github.com/devkitPro/deko3d but also a great deal of | effort from the switch emu devs themselves, writing tests cases | to run on the switch to find edge cases and document behavior. | It definitely is not easy work. | | At the end of the day, every drop of performance counts, but | some drops are much much larger than others. As such, the | advantages of any language's performance characteristics will | be heavily offset by the design choices the emulator uses. The | creator of ryujinx is very comfortable with C#, and with good | development practices, there's no intrinsic reason that one | cannot achieve good performance in a C# emulator. And if one | decides that it's worth the tradeoff to do some extra work for | performance in exchange for a more comfortable development | environment, then I say let them do what they want. | | Shoutouts to both the yuzu and Ryujinx teams for all their hard | work. I loved working on emulators a lot, and highly recommend | anyone who's interested in contributing to give it a shot, its | a really challenging and rewarding kind of project where | there's _always_ something new to learn about in a broad array | of subjects. | jeroenhd wrote: | As sibling comments indicate, the overhead of C# isn't what it | used to be and certainly isn't comparable to other languages | like Python/Ruby/PHP. | | Of course, there's always performance left on the table when | you write in a language like C# or Java (and even a little | performance matters a lot when it comes to emulation), but the | memory safety that C# can provide over C++ can save the | developers a lot of debugging. | | I think such an application can perform perfectly well in a | hardware generation or two and until that point compatibility | matters more than speed anyway; that's where ease of | development will shine. Running an unplayable game well is not | a very interesting project for end users. | | When the project reaches significant compatibility, other | emulators can take ideas from its code and port them to | C/C++/Rust/assembly if they desire to do so. | banachtarski wrote: | C# is consistently a worse performer than most javascript | runtimes currently, and it's not much better than Python, | Ruby, and PHP. | | It's not just that. Basic patterns in C# are known to have | pathological performance problems (implicit boxing, implicit | heap allocations) that you simply don't run into programming | in C or C++. These are things that tank performance in day- | to-day programming that do not show up in carefully tuned | benchmarks. | | Source: Helped profile lots of C# games (not IL2CPP with | Unity, although that's pretty bad IMO as well), not pleased | with what I saw. | askingforproof wrote: | > C# is consistently a worse performer than most javascript | runtimes currently | | This is a bold claim. Please provide evidence that the most | current .NET implementation (.NET Core 3.1) is slower than | any JavaScript implementation. | | This doesn't pass the smell test since you're comparing an | ahead-of-time statically typed approach to a dynamic | scripting language, both of which have had highly tuned JIT | implementations, both of which are using garbage | collection. You can implement things poorly in C#, sure, | but you're making a much stronger claim of consistently | poor performance. | | Saying 'dude trust me' is not a source. | ddevault wrote: | >Of course, there's always performance left on the table when | you write in a language like C# or Java (and even a little | performance matters a lot when it comes to emulation), but | the memory safety that C# can provide over C++ can save the | developers a lot of debugging. | | It really doesn't matter how much headache it saves you in | debugging. The problem simply cannot be solved at the | required level of performance if you use C#. | | >When the project reaches significant compatibility, other | emulators can take ideas from its code and port them to | C/C++/Rust/assembly if they desire to do so. | | The only legitimate use of this project is as a research bed | for future emulators, so I agree with you there. | CJefferson wrote: | Are any significant current emulators written in C? | | The main emulators off the top of my head, MAME, bsnes (and the | related higan) and dolphin, are all in C++. | ddevault wrote: | qemu, a dozen gameboy emulators, dosbox, the 9front emulators | (NES, SNES, GB, GBA, C64, 2600), xemu, z80e, and many, many | more. Lots of the C++ emulators you're familiar with have the | performance critical parts written in C as well, excepting | some newer emulators which leverage something like LLVM for | JIT emulation. | b0b_d0e wrote: | redream is a Dreamcast emulator written in C only. libretro | (the core API behind Retroarch) and Retroarch itself are | primarily C. mupen64plus is in C, although the common 3rd | party plugins and frontends are not always in C. | faheywf wrote: | Why are you so certain? It seems that even a decade ago C# | performance wasn't far off from C++, if not slightly faster[0]. | | [0] https://journal.stuffwithstuff.com/2009/01/03/debunking-c- | vs... | ddevault wrote: | Building contrived tests which "prove" the performance of C# | in the face of mountains of evidence to the contrary is on a | much different scale from emulating an entire complicated | hardware system. | chrisoverzero wrote: | The editor ate your links to the evidence. Can you repost | them? | lukevp wrote: | Why the hate on C#? Are you perhaps thinking of languages like | Ruby and Python and grouping them into the same bucket as C#? | This[0] shows an example of C# vs C++ having a 10% performance | gap on ray tracing. There is also no reason that extremely | performance sensitive parts couldn't be rewritten in Rust or C | or C++ and called from C# over a FFI. | | [0]: https://mattwarren.org/2019/03/01/Is-CSharp-a-low-level- | lang... | bananaface wrote: | C# is garbage collected. _Even if_ the performance potential | was as high to begin with (it 's not), that's a non-starter | for heavy games because you need to be able to control & | predict the performance spikes that GC creates. That's even | more important for an emulator, which needs _more_ | predictability than a regular game. | striking wrote: | There are a number of ways to control the GC in comfortable | ways in C#. https://adamsitnik.com/Array-Pool/ comes to | mind, especially for games. So you can lean into GC when | possible, and switch to an unmanaged approach when you are | seeing perf issues. | [deleted] | Jach wrote: | There are more things in Garbage and Collection, | bananaface, than are dreamt of in your philosophy. | | http://gchandbook.org/ | | https://www.cs.rice.edu/~javaplt/411/15-spring/Readings/wil | s... | | https://web.archive.org/web/20191108025442/http://home.pipe | l... | | https://web.archive.org/web/20191008134612/http://home.pipe | l... | | https://web.archive.org/web/20191231120253/http://home.pipe | l... | | https://en.wikipedia.org/wiki/Fragmentation_(computing) | JeanSebTr wrote: | Yes. But C# also supports struct which are stack allocated. | | C# allows to optimise memory allocation when that matters | and to rely on the GC for less critical parts. | [deleted] | jerf wrote: | Emulation involves a lot of large byte arrays and static | structs that your code updates a lot to represent the | hardware. It isn't necessarily creating a ton of objects | all the time. I do not have specifics on hand for these | emulators but it's not hard to imagine that they could well | be running the GC for a few microseconds every few minutes | or something [1]. It is a _very_ different type of program | than a traditional game, or, indeed, almost any other kind | of program. | | There does seem to be this odd semi-subconscious idea in | the "GCs aren't appropriate for any high-performance" world | that they intrinsically work by stopping the world for 50ms | several times per second or something, but that does not | have to be the case. | | [1]: I actually have a number of servers in Go that run on | about this schedule. If you eliminated 100% of my GC cost | for these servers, I wouldn't care at all, or even notice. | b0b_d0e wrote: | > Emulation involves a lot of large byte arrays and | static structs that your code updates a lot to represent | the hardware | | Things work a bit differently for "modern" emulators, | where the emulators recreate the kernel/OS at a high | level. In these emulators, the games will call into the | system, and the kernel will be expected to do all thats | necessary for the call. In the high level approach, this | means that if a call allocates, so does the emulator | (edit: note that this is a simplified view, as both | emulators map a 4GB page that they work in for the guest | system memory, but theres still a ton of side allocations | that happen "outside" of the guest kernel). There is a | lot of work that goes on in this layer of emulation, and | theres going to be objects that the emulator allocates | and later destroys. Process tables, thread lists, | scheduler information, timing events, kernel | synchronization primitives like mutexs, and so on to name | some. I'm not intimately familiar with Ryujinx to make | any statements about how they handle GC of course, but | its something that they'll need to take into | consideration. That said, there's plenty of other things | like JIT compilation, shader compilation, caches filling | up, and on and on that all also cause micro stuttering, | so its not uncommon for even C or C++ emulators to have | annoying pauses too. | wtetzner wrote: | > preferrably C | | Why? | ddevault wrote: | C++ is a bad programming language used by bad programmers to | write bad programs. The only reason I mention it at all is | because it _can_ achieve the level of performance necessary | for an emulator. | saagarjha wrote: | You can do better than that, Drew. | VRay wrote: | Easy there, Linus | 1tCKV3QfIo wrote: | Cniles don't want to invest in modern C++. | TAForObvReasons wrote: | Next step: emulating nintendo switch games on linux on their | nintendo switch. Switchroot (https://download.switchroot.org/) | makes Ubuntu (based on L4T) and android releases available for | running on older switches. | b0b_d0e wrote: | fail0verflow did this exact thing when they first got linux | working on the switch actually! | https://twitter.com/fail0verflow/status/988543541403160576 It'd | be a pain and a half to get a "proper" fast port with CPU | emulation (either some lightweight JITing or natively running | the code with hooks on SVC and such) and a GPU backend for the | switch graphics. Not nearly simple enough to attract someone to | do it on a whim with no other reason that to say it happened | haha | entropicdrifter wrote: | It sure feels like an ARM based Switch Emulator should | eliminate a lot of the complexity that comes with the emulation | process | KMnO4 wrote: | That's a good point. I wonder if Apple Silicon will give game | console emulators a leg up. | saagarjha wrote: | It does not, DeSmuME on iOS goes through the same JIT. | novok wrote: | I was about to say then you would think a PS4 emulator | would be out by now then, but lo and behold, it exists! | https://pcsx4.com/ | reaperhulk wrote: | PCSX4 is a fake, see: | https://www.pcgamer.com/ps4-emulator-pc/ | gtsnexp wrote: | Have people tried this? Any thoughts, comments? | striking wrote: | I would have loved to give this a try but it appears to require | RCM on my existing Switch... and it's not vulnerable. :( | novok wrote: | And that point you might as well just use your switch then. | zzo38computer wrote: | There are various reasons you may wish to use it on another | computer, and you may have the cartridge, but if you can't | dump/decrypt it, then that won't work, so they will need to | figure out how to work such a thing, so that if you do not | have a compatible Nintendo Switch system then you can still | dump the cartridge and use the necessary keys to decrypt as | needed. | novok wrote: | Pretty much every single switch game has already been | dumped and will continue to be dumped and every single | game +updates fits on a 5TB HDD. And I've never heard of | any particular RCM vulnerable switch not being able to | play specific switch games either. | | So what you've said doesn't make much sense to me. | criddell wrote: | How do you get around the need for a controller with an | accelerometer in it? | jhardy54 wrote: | Since you're using your own Switch for this method (right? :)) | then I'd imagine you could use your joycons? | saagarjha wrote: | Since it's relevant, I should probably note that dumping your own | game cartridges is perfectly legal. Using someone else's dumps or | sharing yours is not legal. Many emulator projects have had | issues with the latter and are extremely testy if you look like | you are doing it. | wodenokoto wrote: | Using? So I can dump my games but not play them? | saagarjha wrote: | Ah, I don't know how I slipped up there. Fixed, you can play | them all you want :) | gambiting wrote: | I should also note that law is not universal and when advising | people on the internet it should be noted as such. In Poland | for instance downloading games dumped by others is perfectly | legal, only sharing isn't. | Wowfunhappy wrote: | > In Poland for instance downloading games dumped by others | is perfectly legal, only sharing isn't. | | Wait, really? Are you sure? | | I ask primarily because, this sounds a little too close to | "Downloading roms you don't own is legal as long you delete | them within 24 hours." ;) | jamie_ca wrote: | Yes, some locales pin the crime specifically on | _distribution_ of copyrighted material. Downloading or | possessing aren't restricted in the same fashion. | dlhavema wrote: | So is this kind of the idea of going after the dealers | and not the users? | kalium-xyz wrote: | Just because the americans are lobbying to make piracy as a | concept a thing doesnt mean that european countries all | have anti-piracy laws. | saagarjha wrote: | Belated disclaimer: I am not a lawyer, and I am certainly not | _your_ lawyer :) If you are interested in this kind of thing | there is a lot of interesting casework in this area. | tobyhinloopen wrote: | I wonder if switch emulation would be more efficient on ARM | systems | saagarjha wrote: | Usually, no. Emulation generally goes through a JIT that | couldn't really care less; there are some processor features | that can be difficult to emulate sometimes but often even on a | similar ISA you cannot just "use your processor directly". | DCKing wrote: | One of the suspected main reasons why we don't have proper | original Xbox emulation yet on the PC is because of the fallacy | that "it should be easy to emulate an x86 console on x86 PCs". | This has lead to many failed attempts to attempt "shortcuts" of | running Xbox games on PCs, like converting executables | statically, or extremely high-level emulation approaches like | only emulating graphics calls. None turned out not to be so | easy in practice. The notion "it should be easy to emulate | architecture X on architecture X" does not tend to hold up very | well, at least not for game consoles that _also_ have | complicated graphics and sound. | | Compare this to Dolphin, which has been wildly successful in | emulating the Nintendo GameCube. Besides the big popularity of | Nintendo games, the GameCube was comparable in complexity and | sales figures to the OG Xbox. But since it had a relatively | non-standard CPU architecture and a non-standard GPU setup, it | guided emulation developers to not put too much effort in | shortcuts and tackle the emulation problem head on. | | It's worth noting some recent progress has been made in OG Xbox | emulation by the Xqemu and Cxbx-reloaded projects. The former | tries to use qemu for x86 emulation (or even virtualization?) | while "low level" emulating the rest of the Xbox hardware, | whereas the latter started life as an extreme high level | emulator that is going more and more low level over time. | [deleted] | pantaloony wrote: | I think almost all the interesting games on the X-Box either | already being available for Windows or else having a just-as- | good version available for another console is a lot of what | kills interest for emulating it. You can play Halo and such | just fine on a PC without an emulator. | MarioMan wrote: | It should be. Look at DraStic, for instance, a DS emulator | which runs ARM code on Android. It's a fairly performant and | accurate emulation option. | https://play.google.com/store/apps/details?id=com.dsemu.dras... | | Now if you're talking about trying to run one of these | emulators on an ARM build of Linux, you wouldn't see these | performance improvements since their designs are optimized | around x86 CPUs, not ARM. | | Edit: Several far more informed comments than mine have | mentioned that running on ARM is only one small piece of the | performance coming from DraStic. | DCKing wrote: | The DraStic developers have commented that they don't gain | much if anything because it runs on ARM [1]. It's just an | efficient emulator. If/when it is open sourced as promised, | it will run very fast on x86 systems too most likely. | | In any case, DraStic is a completely different style of | emulator compared to Yuzu. The Nintendo DS is nothing more | than a pair of microcontrollers with (from a modern | perspective) primitive 2D+3D acceleration hardware, whereas | the Nintendo Switch is a multiprocessor system with a modern | GPU and mulitasking operating system. The DS CPUs are | actually quite far removed from modern smartphone chips, | whereas the Switch chip should be mostly standard ARMv8. | Things that apply to one don't necessarily apply to the | other. | | [1]: https://drastic-ds.com/viewtopic.php?f=5&t=1939 | b0b_d0e wrote: | The fact that its performant is tangential to the fact that | its running on ARM android. IIRC Drastic still does a | traditional JIT to recompile the guest ARM code into ARMv7a | for phones (I might be misremembering, but I _recall_ they | had a whole lotta headache trying to update to support 64 bit | ARM in time for the Android deadline for that. Also I | remember them talking about tons of headaches dealing with | the new storage APIs for Android) | | Its really fast because of the tons of optimization that went | into the application. It does many cool things to cut out | overhead on the CPU side, but also it does a lot on the | graphics emulation side, including hand rolled ARM NEON code | for SIMD processing polygons. I'm not very familiar with DS | emulation, but one of the devs for Drastic contributed to | another project I worked on, so I had some chats here and | there about these sort of things. ___________________________________________________________________ (page generated 2020-07-24 23:00 UTC)