Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [A5] Just Sharing a simple screen shot function

This thread is locked; no one can reply to it. rss feed Print
[A5] Just Sharing a simple screen shot function
Neil Roy
Member #2,229
April 2002
avatar

I just whipped up this screenshot function for my Allegro 5 project I thought I would share if anyone wants it. It doesn't have all the bells and whistles, it basically saves a screenshot in the same folder as your executable. It can be easily modified to save elsewhere, just provide the path as part of the gamename you send to it I suppose.

It saves with the date + the time, so if you supply a game name like my "DeluxePacman" it would save it as "DeluxePacman_20130905_144600.png" for example. It uses 24hour time and the full year. The order is "YYYYMMDD_HHMMSS" so it will be listed in the folder in order that it was taken. This also easily allows you to take multiple screenshots with no limits, one per second.

If you prefer another format, just change PNG to JPG or BMP or whatever Allegro supports. I tested it and it works for me just fine.

I don't know if there is a way to automatically detect physfs and perhaps have the function automatically call `al_set_standard_file_interface()` and `al_set_physfs_file_interface()` or not, I just whipped this up quickly, but it would be nice if that functionality could be added. I suppose it should probably be left up to the person though.

Edit: I just updated this code and used Elias' suggestion to store the current file interface state, then switch to standard file interface, save the bitmap and restore the old state to what it was. Great solution. Works perfectly. :)

a5_screenshot.c

#SelectExpand
1#include "a5_screenshot.h" 2 3bool a5_screenshot(const char *gamename) 4{ 5 time_t rawtime; 6 struct tm *timeinfo; 7 char filename[80], timestr[80]; 8 bool saved; 9 ALLEGRO_STATE state; 10 11 al_store_state(&state, ALLEGRO_STATE_NEW_FILE_INTERFACE); 12 13 al_set_standard_file_interface(); 14 15 time(&rawtime); 16 timeinfo = localtime(&rawtime); 17 18 strftime(timestr, 80, "%Y%m%d_%H%M%S", timeinfo); 19 snprintf(filename, 80, "%s_%s.png", gamename, timestr); 20 21 saved = al_save_bitmap(filename, al_get_target_bitmap()); 22 23 al_restore_state(&state); 24 25 if(!saved) return false; 26 27 return true; 28}

a5_screenshot.h

#ifndef _a5_screenshot_h_
#define _a5_screenshot_h_

#include "allegro5/allegro.h"
#include <stdio.h>

bool a5_screenshot(const char *gamename);

#endif //_a5_screenshot_h_

---
“I love you too.” - last words of Wanda Roy

Elias
Member #358
May 2000

You can use al_get_new_file_interface to get the current file interface (and reset back to that if it's not the standard one). Or you can use al_store_state and al_restore_state with ALLEGRO_STATE_NEW_FILE_INTERFACE to store/restore the current file interface.

--
"Either help out or stop whining" - Evert

Neil Roy
Member #2,229
April 2002
avatar

Great idea Elias, thanks. I updated my original posts code to reflect your suggestion. Works great.

Edit: I tried this out with a5_screenshot("Screenshots/DeluxePacman2"); and it saved it into the "Screenshots" folder as expected. Of course, the folder has to already exist, but it does work which is nice.

---
“I love you too.” - last words of Wanda Roy

Evert
Member #794
November 2000
avatar

How reliable is it that al_get_target_bitmap() gives you the front buffer (ie, what's currently on the screen) rather than the back buffer (ie, where stuff that is drawn actually goes)?

I assumed (based on manual) that there was no reliable cross-platform way to do that...

J-Gamer
Member #12,491
January 2011
avatar

Evert said:

I assumed (based on manual) that there was no reliable cross-platform way to do that...

Even if there isn't, couldn't you bypass this by calling the screenshot function after drawing your current frame(and before flipping the screen)? At 60fps, there normally isn't too much difference between two frames, and the user won't notice the screenshot is one frame off.

EDIT: this might be relevant: http://stackoverflow.com/questions/2661936/asynchronous-readback-from-opengl-front-buffer-using-multiple-pbos

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Thomas Fjellstrom
Member #476
June 2000
avatar

J-Gamer said:

Even if there isn't, couldn't you bypass this by calling the screenshot function after drawing your current frame(and before flipping the screen)? At 60fps, there normally isn't too much difference between two frames, and the user won't notice the screenshot is one frame off.

One problem is that there's no guarantee that the backbuffer even contains what you drew, or that theres only two pages, there could be many more.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

J-Gamer
Member #12,491
January 2011
avatar

One problem is that there's no guarantee that the backbuffer even contains what you drew, or that theres only two pages, there could be many more.

I meant taking a screenshot of the next frame instead of trying to get the current front buffer.

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Thomas Fjellstrom
Member #476
June 2000
avatar

Ah, I missed that part. Sorry. Yeah, I expect that would work.

Or you could draw to a screen sized bitmap, and save that off.

It seems like some games do that, as it takes them some time to actually create and save a screenshot.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

J-Gamer
Member #12,491
January 2011
avatar

Or you could draw to a screen sized bitmap, and save that off.It seems like some games do that, as it takes them some time to actually create and save a screenshot.

You could easily redraw the current frame to that bitmap, instead of using the next frame as a screenshot. That's a less hackish way of doing it, I suppose.

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Go to: