gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > How To Save Screenshots On The DS

#142241 - Ishi - Sat Oct 06, 2007 8:36 pm

I spent last night looking things up for this and getting it working, so I thought I'd share what I learned.

This basically allows you to dump a screenshot straight to a file on your DS card, and then convert it into a proper image file on your PC. Really handy for showing glitches that you need help fixing or something like that.

It requires a free VRAM bank unfortunately. I don't think there's a way to do this without using a bank, but if there is I'd love to be shown how.

I'm using this on 3D on the top screen, settings may need to be changed if you're doing anything different. Again, clarification on that would be fantastic :)

1.

Get your game up and running. Keep one of the main VRAM banks free (I use D).

Amongst the usual headers, you'll need:

Code:
#include <stdio.h>
#include <fat.h>


Don't forget to initialise the file system for saving the image later. Usually done right after powerON() etc.

Code:
   fatInitDefault(); //file system


2.

When you want to take the screenshot (probably when the user presses a button or something), change the video mode and enable display capture:

Code:
   //set up frame buffer video mode
   videoSetMode(MODE_FB3); //frame buffer 3

   DISP_CAPTURE = DCAP_ENABLE | //enables display capturing
               DCAP_BANK(3) | //which vram bank to use - 0=A, 1=B, 2=C, 3=D
               DCAP_SIZE(3) | //3 = full size 256 x 192
               DCAP_SRC(1); //capture source - not sure what this does


3.

At this point I let it render a couple of frames before I grab the image. When I tried grabbing it straight away there was glitches on the image, probably caused by the switch in video mode.

4.

Time to get the image.

Code:
   //dump the screenshot to file
   FILE *file = fopen("/screenshot", "wb");
   if(file)
   {
      fwrite((void*)0x6860000, //memory location of the screen buffer - this might only apply to VRAM bank D, I'm not sure tbh
         2, //each pixel is two bytes
         256 * 192, //total number of pixels (49152)
         file);
      fclose(file);
   }


That saves the current screen data to the root directory of your card.

Finally, return the video mode to what it used to be, and the game should carry on running as normal. Note that MODE_0_3D is just an example here, you can set whatever video mode you need to.

Code:
   //return to default video mode
   videoSetMode(MODE_0_3D);

   DISP_CAPTURE = 0; //disable display capture


5.

Copy/move the screenshot file off the DS onto your PC. Drag & Drop it onto my converter program - http://www.ishisoft.remakes.org/misc/ds_screenshot_converter.zip - and if all goes well, your screenshot should be saved out as a 256x192 .png image. (like so: http://www.ishisoft.remakes.org/misc/screenshot1.png ).


Hope this is useful for someone. It's not exactly comprehensive or detailed, but it gets the job done.

Note that you can save the screenshot file as whatever you want. Mine outputs incrementally numbered files so that you can take more than one screenshot at a time. I left that kind of thing out of this tutorial for the sake of simpicity.

#142282 - gm112 - Sun Oct 07, 2007 7:12 pm

Woah! Nice find :D. At least this is a start, you know?

#142285 - Lazy1 - Sun Oct 07, 2007 7:39 pm

Can you capture the sub screen as well?
That would be really good to capture them both and write it as a single 256x384 image.

#142287 - Mighty Max - Sun Oct 07, 2007 7:49 pm

Lazy1 wrote:
Can you capture the sub screen as well?
That would be really good to capture them both and write it as a single 256x384 image.


The second gfx core does not seem to have the needed capture registers.
http://nocash.emubase.de/gbatek.htm#dsvideodisplaysystemblockdiagram
_________________
GBAMP Multiboot

#142289 - Dood77 - Sun Oct 07, 2007 7:58 pm

Mighty Max wrote:
Lazy1 wrote:
Can you capture the sub screen as well?
That would be really good to capture them both and write it as a single 256x384 image.


The second gfx core does not seem to have the needed capture registers.
http://nocash.emubase.de/gbatek.htm#dsvideodisplaysystemblockdiagram

So flip screens, capture, then append one image to the other...
_________________
If I use a term wrong or something then feel free to correct, I?m not much of a programmer.

Original DS Phat obtained on day of release + flashme v7
Supercard: miniSD, Kingston 1GB, Kingston 2GB
Ralink chipset PCI NIC

#142290 - Mighty Max - Sun Oct 07, 2007 8:07 pm

If you flip the screens, you are not flipping the engine.
You would completely need to flip the core you are rendering on. This will most likely have a huge impact on your code.
_________________
GBAMP Multiboot

#142303 - wintermute - Sun Oct 07, 2007 11:36 pm

There's been a screenshot demo in CVS examples since April. It outputs .bmps
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#142355 - Ishi - Mon Oct 08, 2007 6:59 pm

wintermute wrote:
There's been a screenshot demo in CVS examples since April. It outputs .bmps


What / where is CVS examples? I couldn't find anything on the forum here so I figured it would be worth posting.

#142362 - tepples - Mon Oct 08, 2007 7:49 pm

CVS is a revision control system. All devkitPro projects, such as devkitARM and libnds, have their latest source code in the devkitPro CVS repository on SourceForge.net. I interpreted "CVS examples" as shorthand for the latest version of the libnds examples that has been made available in the devkitPro CVS repository.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#142393 - Ishi - Mon Oct 08, 2007 10:30 pm

Ah cool, ta for the info :)
I had a look for CVS on wiki but I think I got distracted by Cyclic Vomiting Syndrome. ;)

#142441 - HyperHacker - Tue Oct 09, 2007 5:27 am

Mighty Max wrote:
If you flip the screens, you are not flipping the engine.
You would completely need to flip the core you are rendering on. This will most likely have a huge impact on your code.
Worse, you can't render 3D on the second core.
_________________
I'm a PSP hacker now, but I still <3 DS.

#148291 - Neo_Ace - Fri Jan 04, 2008 12:22 pm

Can you put the code complete? Than is not separated.

Sorry for my English

#148404 - simonjhall - Sat Jan 05, 2008 1:38 pm

Hi Ishi, when I run your program to convert the image to a png I get an error about a missing corona.dll.
I'm hunting around for a replacement but it may be worth updating your zip file to include this file...
_________________
Big thanks to everyone who donated for Quake2

#148451 - yellowstar - Sat Jan 05, 2008 10:35 pm

Ishi wrote:

It requires a free VRAM bank unfortunately. I don't think there's a way to do this without using a bank, but if there is I'd love to be shown how.

FIFO can probably do that. But, I don't know how to do it... Check gbatek.

Ishi wrote:

3.

At this point I let it render a couple of frames before I grab the image. When I tried grabbing it straight away there was glitches on the image, probably caused by the switch in video mode.

That's most likely because the display capture isn't done. Use this to check for that.(Your code does the following, but it doesn't continue as soon as the capture is done)

Code:

while(DISP_CAPTURE==1)swiWaitForVBlank();
//Wait for the display capture to finish. You set this to 1 to start the capture. The hardware sets this //to 0 when it's done. So, this code waits for that to happen.


My captures were captured flawlessly every time with this.(But I used my own code. But that shouldn't make any difference)
Of course, since it's waiting on the capture, you have to wait a bit for it
to finish.(One way to know if it's done is to have something moving, but most things have that)(Or display a done message)