Gameboy Development Forum

Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)

You are not logged in.

#1 2015-09-08 19:56:38

Scazon
Member
From: Boston, MA
Registered: 2015-06-14
Posts: 24
Website

Taking a screenshot

Is it possible to directly access the on-screen pixel data, to, for example, take a 'screenshot' of the game? I'm using GBDK.

Offline

 

#2 2015-09-08 23:21:24

l0k1
Member
Registered: 2014-10-23
Posts: 44

Re: Taking a screenshot

AFAIK, no, you can't directly access the pixel data.
You could copy the BG map, and any sprite data. So instead of pixel-by-pixel, you could do tile-by-tile.

In ASM (untested, would need to be run in VBlank as you're accessing the BG Map and OAM RAM):

Code:

Copy_Background_Data:   

   ld HL,$9800      ;location of background map data, assuming it's at $9800 and not $9C00 (i'm being lazy by not checking)
   ld BC,$C000      ;we're copying it to the beginning of the internal ram.
   ld DE,32*32      ;DE will be our counter. copying the WHOLE background map. You could do it for just the screen though. assuming your using 8x8 tiles.
.loop
   ld A,[HL+]       ;load the first background map tile into the accumulator, and increment HL
   ld [BC],A        ;load the accumulator into BC (our spot in RAM)
   inc BC           ;increment BC
   dec DE           ;decrement DE, our counter
   ld A,E           ;now check if DE is zero
   or D
   jr nz,.loop      ;jump back up if we aren't done copying.

Copy_Sprite_Data:

   ld HL,$FE00      ;location of the OAM RAM
   ;we aren't going to load up BC with a new value, we will just leave it at $C000 + (32 * 32)
   ld DE,40*4       ;that's 40 sprites, at 4 bytes a piece.
.loop               ;this is the lazy way to do it, you'll probably want to check x/y/attributes when writing the data to make sure the sprite should be rendered.
   ld A,[HL+]       ;pretty much a copy of the Copy_Background_Data function.
   ld [BC],A
   inc BC
   dec DE
   ld A,E
   or D
   jr nz,.loop

None of that is compressed, and is probably a lazy way to do it, but it'll copy the background data tile by tile.
I didn't do the window, because meh. Pretty much the same.
Also, since your using GBDK, this may be of like zero use to you haha.

Ideally, there'd be copies of the BG Map and sprite data somewhere else in RAM that you could copy instead, that way you can do it outside of VBlank, but... that's situational.

EDIT: Fixing code comment indentation.

Last edited by l0k1 (2015-09-08 23:24:56)

Offline

 

#3 2015-09-09 03:00:34

Xephyr
Member
From: France
Registered: 2015-02-26
Posts: 59

Re: Taking a screenshot

If you're using GBDK, you can use get_bkg_tiles / get_bkg_data (works for win and sprites too) to save your layers.
I guess it use the same things as l0k1.

Here's the doc if you want : http://gbdk.sourceforge.net/doc/html/c0504.html

Last edited by Xephyr (2015-09-09 03:01:27)

Offline

 

#4 2015-09-09 09:47:25

Scazon
Member
From: Boston, MA
Registered: 2015-06-14
Posts: 24
Website

Re: Taking a screenshot

Would that method work if I've used scroll_bkg()? Basically what I want to do is to copy a given 16x16 square on the screen and display it on the side. I'm not worried about sprites in the way, but the bkg might be offset due to scroll_bkg().

I was thinking I could save the pixel data at the 16x16 location and make 4 new tiles to display on the side (as sprites so they would stay in place while the bkg is moving), but the issue is somehow copying those pixels into a new tile array to load into sprite data.

Offline

 

#5 2015-09-09 10:49:24

l0k1
Member
Registered: 2014-10-23
Posts: 44

Re: Taking a screenshot

I was thinking about my code in the shower, and realized it'd only copy the tile numbers, not the actual tiles. So woops. =] It only does half the work, you'd still need to get the tiles out of VRAM.
As to your question, yes it's possible.
You could either save all possible offsets for the tile (which would eat up a lot of memory), or look at what tiles are in the "copy area" (off the cuff thinking tells me there could be up to 9 8x8 tiles at a time in a 16x16 area), and shift the bits themselves around to get only the data in the 16x16 area, and then use those bits to dynamically write new tiles (which is a tad tricky). Not even going in to sprites or the window yet haha. Not sure how to do it in GBDK, but it is possible.

Last edited by l0k1 (2015-09-09 10:50:57)

Offline

 

#6 2015-09-09 11:08:18

Xephyr
Member
From: France
Registered: 2015-02-26
Posts: 59

Re: Taking a screenshot

The get_data() function apparently allows you to copy any data from the VRAM, so if you know the address of your tile, I think you should be able to use it.
If not, well I guess assembly will be better. You can write some methods in assembly and link them with your .c file though, so it shouldn't be a problem.

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson