 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
ADePSP
Joined: 13 Jul 2006 Posts: 58
|
Posted: Mon Aug 07, 2006 1:48 am Post subject: [RESOLVED] Take a Screenshot or is there an easier way...? |
|
|
I'm messing about with popup dialogs in my new app and want them to appear on top of whatever is currently on the screen and when you are done with them flip the screen back to what it was before...
I'm probably being dumb and there is an easy way to blit the dialog onto the current screen and then revert but not sure how...
I was thinking I might need to grab the current screen, blit that and then blit the dialog graphics over it and then flipScreen... Then, when done simply blit the original screen again and flipScreen to put the user back where they were...
Anyone know how to grab the current screen into an Image variable...? Something like the reverse of this,
| Code: | void blitImageToScreen(int sx, int sy, int width, int height, Image* source, int dx, int dy)
{
if (!initialized) return;
Color* vram = getVramDrawBuffer();
sceKernelDcacheWritebackInvalidateAll();
guStart();
sceGuCopyImage(GU_PSM_8888, sx, sy, width, height, source->textureWidth, source->data, dx, dy, PSP_LINE_SIZE, vram);
sceGuFinish();
sceGuSync(0,0);
} |
...i.e. blitScreenToImage instead...
Please tell me if there is an easier way but i'd like a function to capture parts of the screen anyway... It might come in handy...
Cheers
ADe
Last edited by ADePSP on Mon Aug 07, 2006 3:22 am; edited 1 time in total |
|
| Back to top |
|
 |
Kojima
Joined: 26 Jun 2006 Posts: 275
|
Posted: Mon Aug 07, 2006 2:01 am Post subject: |
|
|
| Not sure what you're doing, but I'd just carry on blitting the original screen before blitting the dialog. |
|
| Back to top |
|
 |
ADePSP
Joined: 13 Jul 2006 Posts: 58
|
Posted: Mon Aug 07, 2006 2:07 am Post subject: |
|
|
| Kojima wrote: | | Not sure what you're doing, but I'd just carry on blitting the original screen before blitting the dialog. |
I'm trying to encapsulate it so I end up with transportable code for my popup dialogs that don't need to know anything about what is on the current screen they are appearing on top of... The function will capture whatever junk is currently on the screen, display it's own thing on top of it and at the end return the screen to it's original state...
Does that make more sense or am I just confusing myself and everybody else...? :D
Thanks anyway and good work on the 3D Graphics engine I saw on PSPUpdates by the way...
ADe |
|
| Back to top |
|
 |
ADePSP
Joined: 13 Jul 2006 Posts: 58
|
Posted: Mon Aug 07, 2006 3:07 am Post subject: |
|
|
Ok, just wrote this function and it originally just saved a black image 480x272... I then relalized this was because the getPixelScreen function was getting the pixel from the buffer which had been swapped by the flipScreen function that was called before the saveScreen function was called later on in my code...
I added a flipScreen before I take the screenshot and one after to swap them back and it works but for a split second you see the previous screen whilst it swaps the one I want back into the buffer that can be read...
Is there a way to "copy" rather than swap the buffers so that on screen buffer and the "behind the scenes" buffer (that I can read) are the same so this flicker doesn't happen...?
| Code: | void saveScreen(char* filename) {
int posX;
int posY;
Color pixel;
Image* screenShot;
screenShot = createImage(480,272);
flipScreen();
for (posY=0; posY<272; posY++) {
for(posX=0; posX<480; posX++) {
pixel = getPixelScreen(posX,posY);
putPixelImage(pixel,posX,posY,screenShot);
}
}
flipScreen();
saveImage(filename,screenShot->data,480,272,PSP_LINE_SIZE,0);
freeImage(screenShot);
} |
EDIT: Great, worked it out... I just needed to get the Display Buffer rather than the Draw buffer and now it works perfectly...
Here is a simple screenshot function if anyone wants it... Obviously requires the graphics.c include files...
| Code: | void saveScreen(char* filename) {
int posX;
int posY;
Color pixel;
Color* vram = getVramDisplayBuffer();
Image* screenShot;
screenShot = createImage(480,272);
for (posY=0; posY<272; posY++) {
for(posX=0; posX<480; posX++) {
pixel = vram[PSP_LINE_SIZE * posY + posX];
putPixelImage(pixel,posX,posY,screenShot);
}
}
saveImage(filename,screenShot->data,480,272,PSP_LINE_SIZE,0);
freeImage(screenShot);
} |
EDIT2: Probably better to split this function into 2 and allow people to grab sections of the screen aswell as save the whole thing...
| Code: | Image* grabScreen(int x1, int y1, int x2, int y2) {
int posX;
int posY;
Color pixel;
Color* vram = getVramDisplayBuffer();
Image* screenShot;
screenShot = createImage(x2-x1,y2-y1);
for (posY=y1; posY<y2; posY++) {
for(posX=x1; posX<x2; posX++) {
pixel = vram[PSP_LINE_SIZE * posY + posX];
putPixelImage(pixel,posX,posY,screenShot);
}
}
return screenShot;
}
void saveScreen(char* filename) {
Image* screenShot;
screenShot = grabScreen(0,0,480,272);
saveImage(filename,screenShot->data,480,272,PSP_LINE_SIZE,0);
freeImage(screenShot);
} |
|
|
| Back to top |
|
 |
paxux
Joined: 25 Jul 2006 Posts: 4
|
Posted: Wed Aug 09, 2006 8:58 pm Post subject: |
|
|
While that code will work you should be able to do it quicker with pointers and copying the block of memory all in one go and not reading each pixel individually
Pseudo code:
| Code: | LineLength = Width * Pixel Size;
for (x=0; x < Height; x ++)
for (i=0; i < LineLength; i++)
Copy[(x * LineLength)+i] = Source[(x * LineLength) + i];
|
Now depending on how you handle you’re Rendering queue you want to do overlays at the end of the process. Do you start each rendering loop with a blank screen or do you use the output from the previous loop?
If you want to have animated backgrounds while overlaying you’ll need something like this:
Standard Queue:
- New Frame
- Draw Object to Buffer [loop]
- Flip Buffer to PSP screen
Updated for Overlays:
Example (assumes new blank buffer each loop)
- Blank Buffer
- Draw Object to Buffer [loop]
- {new} if (overlay) DisplayOverlay();
- Flip Buffer to PSP screen
overlay a boolean that’s set while you want to display an overlay
Example (use last frame as input to the next)
- Draw Object to Screen [loop]
- {new} if (overlay) CopyScreen(); DisplayOverlay();
- Flip Buffer to PSP screen
- {new} if (overlay) RestoreScreen();
Don’t know if that made any sense? Hope you see what I’m getting at. |
|
| Back to top |
|
 |
paxux
Joined: 25 Jul 2006 Posts: 4
|
Posted: Wed Aug 09, 2006 9:06 pm Post subject: |
|
|
| Also what I just describing is a form (a very simple form) of Finite state machine. They're very handy if you know how to use them when solving problems with enable and disable logic blocks in code. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|