Metroid: Samus Returns - possible to upscale?

I’m new to Citra and I am excited to see how well the new Metroid game runs. From showcases I can see that many games like the Zelda and Mario Kart games can be upscaled to beautiful 1080p glory, resulting in clear and crisp graphics. I am trying to up the resolution with Samus Returns but the game becomes more and more pixelated the higher the resolution goes. Am I missing some step? Is there any way to improve the visuals of this game?

Many thanks!

the answer is complicated. in order to upscale this game, citra needs a gpu texture copy implementation, but after working for 20 hours on it, it might just be impossible. I’m not giving up yet, as I’m a big time metroid fan boi and really want it to work great in citra, but I can’t promise anything until its ready.

I see. I hope you make it! Another user seems to be attempting to crack this, b0b_d0e on the Reddit forum (, he shared a screen grab of his progress… maybe you two could share discoveries :slight_smile:

I hope you guys make it! Thanks for the contribution to the community! Hopefully we’ll soon be able to play this game in HD glory :smiley:

That’s not another user, that’s @jroweboy haha

oh, lol. Wow. I should have guessed maybe :smiley:

yeah haha jroweboy is my “developer” user name account and b0b d0e is my “gaming” user name account. at one point i wanted to keep them separate, but i kinda gave up :stuck_out_tongue: too much effort.

i’ve been working with some of the other devs on it though (the two people who are most knowledgeable about this area of the code), and it doesn’t seem likely that i’ll be able to finish this sadly. but i’m not going to give up just yet. got a few more things to test. i’ve done a few write ups one why its not likely to be possible, but i don’t feel like doing another write up right now

oh no, please don’t give up :sob:

okay fine. status update: I’m 90% sure i can get it sped up. I think that part is free at this point. I’m only about 5% confident i can get the upscaling though. Simply put, the game applies full screen graphical effects by copying the current frame buffer (whats about to be drawn to the screen) in a new texture, and then doodles on the texture. This part hits a fallback in the citra gpu emulation code, which makes it drop back to native resolution and also kills performance because the gpu has to upload the texture to the cpu, and then download it from the cpu later. This is reaaally slow. Gpu <-> Cpu transfer is high bandwidth high latency meaning you can transfer a lot of things, but its also slow to do that.

What my change is all about, is i’m going to copy the texture entirely on the gpu. The problem is, the game doesn’t say anything about a width/height to copy, it just treats it like a giant array, and says “copy these chunks, and skip every N bytes” Well I used some math to try to figure out what is the rectangle they are trying to copy, but heres the problem. I don’t know what dimensions to store the image with in the cache. So what ends up happening is I cache the texture, tell the gpu code that the address is to be looked up in the gpu cache and move on. Now when the game tries to use it, citra will look in the gpu cache for the texture. Heres where it breaks down… the game will try to load a texture at L address with M width N height, and citra says “Hmm I have a texture at L address! But its not M width or N height” and so it won’t load it from cache, which means its slow again. Remember earlier, I said when i cached it that I can’t know what the final width and height is supposed to be, but I can make up two numbers and put that as the width and height. Then I can try to trick the emulator to load the texture based on its size instead of width and height, but this hasn’t worked at all. Textures just don’t work that way lol

So when I took that picture, I knew that the game was using a 256x512 texture size, and so I hardcoded those values into citra. But this is only useful for metroid, and it turns out tons of other games use this as well, and hardcoding those numbers will break all of them. Try as we might, no one has any clue how to solve this problem. I have a few more ideas for how to solve this, but i don’t have much hope for them right now.

Lots to do, little time to do it :stuck_out_tongue: I’ll make sure to make posts if i do find some way of course. I’m very much a metroid fan, and really want to play this game in the resolution i feel it deserved :smiley:


10/10, needs to stream again

Thanks for the update! Man, what a conundrum! In the last paragraph, where you mention hardcoding some values that might help Metroid but break other games, would it not be possible to maybe add a debug menu where users can activate this option only when playing Metroid?

i really suggest not doing it, breaking many games for the sake of one is just not right.

Maybe some solutions have to be hardcoded :frowning:

Maybe the design in video core, rasterizer or whatever is flawed? Or has it been done correctly so far?

no. citra does not have a “hack” configuration tab and never will.

for a sneak preview of what its looking like (sorry about the low quality. didn’t feel like overwriting my streaming settings for this gif lol) i do my testing with frame limiter off so I can see what the full impact of the changes are. 150% speed average is pretty nice compared to the 80% i get without these changes :smiley:

i’m well aware, but thanks.

who knows. i think i have a solution for hardcoding width and height (haven’t tested it throughly yet) but now i have to do math to figure out the output dimensions. math is easy for me, but figuring out what math i need to do is the hard part ^^;

Maybe add in some filters.That does look like a gba game with filters.(metroid fanbois please don’t kill me)

Wow, jroweboy, that last GIF you shared does look pretty great!! It’s not stretched like the one you shared a few days ago and the picture is so much sharper than what we are getting now…

So what are you saying, that you cannot release this update? Because it will break other games?

I know terribly little about Citra, but Cemu for instance, has a menu to enable game specific settings that will enhance that game specifically and you turn them on and off as needed (they are called Graphic Packs there). You consider them hacks, but as long as they can be turned on or off ?

i don’t care at all what cemu does. its an emulator for profit and citra is not. they make more money by pleasing the userbase so it makes business sense for them, but citra doesn’t have any monetary incentive like that, meaning citra can focus on being accurate to the hardware. citra is made by many of the same people that have worked on dolphin and other emulators, and they have all learned from the mistakes of those emulators, and “configurable hacks” is one such mistake. for example, dolphin has a hacks tab and i remember them saying it was a mistake and they wish they had never added one.

no, i’m saying if i don’t figure out how to make it work for every game, then i won’t release it. there are 3 scenarios in order of best case to worst case.

  1. I magically get everything to work for every game. Very unlikely at this point, but its what i’m shooting for.
  2. I use the cpu fallback for first time generation of the texture, meaning it’ll be low rez still, but it’ll be fast at least. This is entirely possible to get merged into mainline citra, and is the most realistic scenario right now.
  3. It turns out its impossible and i just scrap it all. Sorry, but I won’t be releasing any binaries or code in this case. Someone else can write it from scratch if they wanna make an unofficial build outta this. I don’t wanna have to live with the backlash of “OMG CITRA IS SO BAD. I found XXXX build online that plays metroid fast AND upscaled” especially when its my own code. I’ve been around the citra project for 2 1/2 years and I know thats exactly what will happen if I release the code. Since its my code, I’m free to not share it should I choose.

fite me irl Kappa


I’ve been following progress (well, rumblings and replies really :P) across here and the Citra subreddit. Your progress looks amazing, and although I do hope to see these features make it into Citra, I can understand NOT implementing them as well. You wrote them after all!

I’ll be keeping an eye out though. I’ve been dying to play M:SR, but am unable to use my 3DS without further damaging my thumbs. Getting old is fun! I played for a little while but had to give up for my hand’s sake.

So far on my PC (i7-3770k, Nvidia 1070) I get 12~25FPS and it’s just far too variable to enjoy. Higher resolutions would be nice, but honestly as long as an update is available eventually that improves framerate I’ll be happy (whether your change or someone else’s in the future).

You’re doing Bryyo god’s work, son.


so for an update. i’ve been hard at work on it for two weeks and someone else posted their finished code for the same thing i was working on, to the citra development chat and said “i don’t feel like getting this merged. if anyone else wants to clean it up and merge it be my guest” that was pretty unexpected to say the least.

so… bye bye my terrible terrible code and hello finished product!

it will still be a bit as i need to understand the code and “adopt” it, meaning i need to know it well enough to answer questions about it. from reading the code its clear that the author knows what they are doing and I clearly don’t ^^;


Woo hoo! Hooray for the amazing Citra Dev community! That’s amazing to hear!

So this will address both the speed and the upscaling?

How is the progress going on this? Currently debating Samus Returns or AM2R. Playing them all over again chronologically. Finishing up Corruption, soon.