mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-07-03 14:34:34 +00:00
Save screenshots in PNG instead of TGA format. Closes #34.
This commit is contained in:
parent
b4c001edb6
commit
4751b31653
3 changed files with 90 additions and 74 deletions
|
@ -2993,7 +2993,6 @@ void DSQ::doSaveSlotMenu(SaveSlotMode ssm, const Vector &position)
|
||||||
memmove(scrShotData, scrShotData + adjOffset, adjImageSize);
|
memmove(scrShotData, scrShotData + adjOffset, adjImageSize);
|
||||||
memset(scrShotData + adjImageSize, 0, imageDataSize - adjImageSize);
|
memset(scrShotData + adjImageSize, 0, imageDataSize - adjImageSize);
|
||||||
zgaSave(os.str().c_str(), scrShotWidth, scrShotHeight, 32, scrShotData);
|
zgaSave(os.str().c_str(), scrShotWidth, scrShotHeight, 32, scrShotData);
|
||||||
scrShotData = 0; // deleted by tgaSave()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaySfx sfx;
|
PlaySfx sfx;
|
||||||
|
|
152
BBGE/Core.cpp
152
BBGE/Core.cpp
|
@ -366,7 +366,6 @@ Core::Core(const std::string &filesystem, const std::string& extraDataDir, int n
|
||||||
renderObjectCount = 0;
|
renderObjectCount = 0;
|
||||||
avgFPS.resize(1);
|
avgFPS.resize(1);
|
||||||
minimized = false;
|
minimized = false;
|
||||||
numSavedScreenshots = 0;
|
|
||||||
shuttingDown = false;
|
shuttingDown = false;
|
||||||
nestedMains = 0;
|
nestedMains = 0;
|
||||||
afterEffectManager = 0;
|
afterEffectManager = 0;
|
||||||
|
@ -1238,12 +1237,14 @@ std::string Core::getEnqueuedJumpState()
|
||||||
}
|
}
|
||||||
|
|
||||||
int screenshotNum = 0;
|
int screenshotNum = 0;
|
||||||
std::string getScreenshotFilename()
|
std::string getScreenshotFilename(bool png)
|
||||||
{
|
{
|
||||||
|
std::string prefix = core->getUserDataFolder() + "/screenshots/screen";
|
||||||
|
std::string ext = png ? ".png" : ".tga";
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << core->getUserDataFolder() << "/screenshots/screen" << screenshotNum << ".tga";
|
os << prefix << screenshotNum << ext;
|
||||||
screenshotNum ++;
|
screenshotNum ++;
|
||||||
std::string str(os.str());
|
std::string str(os.str());
|
||||||
if (!core->exists(str)) // keep going until we hit an unused filename.
|
if (!core->exists(str)) // keep going until we hit an unused filename.
|
||||||
|
@ -1464,9 +1465,10 @@ void Core::run(float runTime)
|
||||||
if (doScreenshot)
|
if (doScreenshot)
|
||||||
{
|
{
|
||||||
doScreenshot = false;
|
doScreenshot = false;
|
||||||
|
const bool png = true;
|
||||||
saveScreenshot(getScreenshotFilename());
|
saveScreenshot(getScreenshotFilename(png), png);
|
||||||
prepScreen(0);
|
prepScreen(0);
|
||||||
|
resetTimer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
quitNestedMainFlag = false;
|
quitNestedMainFlag = false;
|
||||||
|
@ -2571,11 +2573,8 @@ bool Core::canChangeState()
|
||||||
// longer needed.
|
// longer needed.
|
||||||
unsigned char *Core::grabScreenshot(int x, int y, int w, int h)
|
unsigned char *Core::grabScreenshot(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned char *imageData;
|
|
||||||
|
|
||||||
unsigned int size = sizeof(unsigned char) * w * h * 4;
|
unsigned int size = sizeof(unsigned char) * w * h * 4;
|
||||||
imageData = new unsigned char[size];
|
unsigned char *imageData = new unsigned char[size];
|
||||||
|
|
||||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
@ -2613,15 +2612,19 @@ unsigned char *Core::grabCenteredScreenshot(int w, int h)
|
||||||
}
|
}
|
||||||
|
|
||||||
// takes a screen shot and saves it to a TGA or PNG image
|
// takes a screen shot and saves it to a TGA or PNG image
|
||||||
int Core::saveScreenshot(const std::string &filename)
|
bool Core::saveScreenshot(const std::string &filename, bool png)
|
||||||
{
|
{
|
||||||
int w = getWindowWidth(), h = getWindowHeight();
|
int w = getWindowWidth(), h = getWindowHeight();
|
||||||
unsigned char *imageData = grabCenteredScreenshot(w, h);
|
unsigned char *imageData = grabCenteredScreenshot(w, h);
|
||||||
return tgaSave(filename.c_str(),w,h,32,imageData);
|
bool ok = png
|
||||||
|
? pngSave(filename.c_str(), w, h, imageData)
|
||||||
|
: tgaSave(filename.c_str(),w,h,32,imageData);
|
||||||
|
delete [] imageData;
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// saves an array of pixels as a TGA image (frees the image data passed in)
|
// saves an array of pixels as a TGA image
|
||||||
int Core::tgaSave( const char *filename,
|
bool Core::tgaSave( const char *filename,
|
||||||
short int width,
|
short int width,
|
||||||
short int height,
|
short int height,
|
||||||
unsigned char pixelDepth,
|
unsigned char pixelDepth,
|
||||||
|
@ -2634,10 +2637,8 @@ int Core::tgaSave( const char *filename,
|
||||||
|
|
||||||
// open file and check for errors
|
// open file and check for errors
|
||||||
file = fopen(adjustFilenameCase(filename).c_str(), "wb");
|
file = fopen(adjustFilenameCase(filename).c_str(), "wb");
|
||||||
if (file == NULL) {
|
if (!file)
|
||||||
delete [] imageData;
|
return false;
|
||||||
return (int)false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute image type: 2 for RGB(A), 3 for greyscale
|
// compute image type: 2 for RGB(A), 3 for greyscale
|
||||||
mode = pixelDepth / 8;
|
mode = pixelDepth / 8;
|
||||||
|
@ -2661,8 +2662,7 @@ int Core::tgaSave( const char *filename,
|
||||||
|| fwrite(&cGarbage, sizeof(unsigned char), 1, file) != 1)
|
|| fwrite(&cGarbage, sizeof(unsigned char), 1, file) != 1)
|
||||||
{
|
{
|
||||||
fclose(file);
|
fclose(file);
|
||||||
delete [] imageData;
|
return false;
|
||||||
return (int)false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the image data from RGB(A) to BGR(A)
|
// convert the image data from RGB(A) to BGR(A)
|
||||||
|
@ -2674,44 +2674,12 @@ int Core::tgaSave( const char *filename,
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the image data
|
// save the image data
|
||||||
if (fwrite(imageData, sizeof(unsigned char),
|
size_t bytes = width * height * mode;
|
||||||
width * height * mode, file) != width * height * mode)
|
bool ok = fwrite(imageData, 1, bytes, file) == bytes;
|
||||||
{
|
|
||||||
fclose(file);
|
|
||||||
delete [] imageData;
|
|
||||||
return (int)false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
delete [] imageData;
|
|
||||||
|
|
||||||
return (int)true;
|
return ok;
|
||||||
}
|
|
||||||
|
|
||||||
// saves a series of files with names "filenameX"
|
|
||||||
int Core::tgaSaveSeries(char *filename,
|
|
||||||
short int width,
|
|
||||||
short int height,
|
|
||||||
unsigned char pixelDepth,
|
|
||||||
unsigned char *imageData) {
|
|
||||||
|
|
||||||
char *newFilename;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
// compute the new filename by adding the
|
|
||||||
// series number and the extension
|
|
||||||
newFilename = (char *)malloc(sizeof(char) * strlen(filename)+16);
|
|
||||||
|
|
||||||
sprintf(newFilename,"%s%d",filename,numSavedScreenshots);
|
|
||||||
|
|
||||||
// save the image
|
|
||||||
status = tgaSave(newFilename,width,height,pixelDepth,imageData);
|
|
||||||
|
|
||||||
//increase the counter
|
|
||||||
if (status == (int)true)
|
|
||||||
numSavedScreenshots++;
|
|
||||||
free(newFilename);
|
|
||||||
return(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::screenshot()
|
void Core::screenshot()
|
||||||
|
@ -2723,7 +2691,7 @@ void Core::screenshot()
|
||||||
#include "DeflateCompressor.h"
|
#include "DeflateCompressor.h"
|
||||||
|
|
||||||
// saves an array of pixels as a TGA image (frees the image data passed in)
|
// saves an array of pixels as a TGA image (frees the image data passed in)
|
||||||
int Core::zgaSave( const char *filename,
|
bool Core::zgaSave( const char *filename,
|
||||||
short int w,
|
short int w,
|
||||||
short int h,
|
short int h,
|
||||||
unsigned char depth,
|
unsigned char depth,
|
||||||
|
@ -2737,8 +2705,7 @@ int Core::zgaSave( const char *filename,
|
||||||
// open file and check for errors
|
// open file and check for errors
|
||||||
FILE *file = fopen(adjustFilenameCase(filename).c_str(), "wb");
|
FILE *file = fopen(adjustFilenameCase(filename).c_str(), "wb");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
delete [] imageData;
|
return false;
|
||||||
return (int)false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute image type: 2 for RGB(A), 3 for greyscale
|
// compute image type: 2 for RGB(A), 3 for greyscale
|
||||||
|
@ -2775,18 +2742,11 @@ int Core::zgaSave( const char *filename,
|
||||||
z.append(imageData, width * height * mode);
|
z.append(imageData, width * height * mode);
|
||||||
z.Compress(3);
|
z.Compress(3);
|
||||||
|
|
||||||
// save the image data
|
bool ok = fwrite(z.contents(), 1, z.size(), file) == z.size();
|
||||||
if (fwrite(z.contents(), 1, z.size(), file) != z.size())
|
|
||||||
{
|
|
||||||
fclose(file);
|
|
||||||
delete [] imageData;
|
|
||||||
return (int)false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
delete [] imageData;
|
|
||||||
|
|
||||||
return (int)true;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2899,3 +2859,63 @@ Joystick *Core::getJoystickForSourceID(int sourceID)
|
||||||
return getJoystick(actionStatus[sourceID+1]->getJoystickID());
|
return getJoystick(actionStatus[sourceID+1]->getJoystickID());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
bool Core::pngSave(const char *filename, unsigned width, unsigned height, unsigned char *data)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
std::vector<png_byte*> rowData(height);
|
||||||
|
// passed in buffer is upside down; flip it
|
||||||
|
for(unsigned i = 0; i < height; i++)
|
||||||
|
rowData[height - i - 1] = i * width * 4 + data;
|
||||||
|
|
||||||
|
FILE *fp = fopen(filename, "wb");
|
||||||
|
if (!fp)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
png_structp png;
|
||||||
|
png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (!png)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
png_infop info_ptr;
|
||||||
|
info_ptr = png_create_info_struct(png);
|
||||||
|
if (!info_ptr)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (setjmp(png_jmpbuf(png)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
png_init_io(png, fp);
|
||||||
|
|
||||||
|
if (setjmp(png_jmpbuf(png)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
png_set_IHDR(png, info_ptr, width, height,
|
||||||
|
8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
|
||||||
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||||
|
|
||||||
|
png_write_info(png, info_ptr);
|
||||||
|
|
||||||
|
if (setjmp(png_jmpbuf(png)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
png_write_image(png, (png_byte**)&rowData[0]);
|
||||||
|
|
||||||
|
if (setjmp(png_jmpbuf(png)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
png_write_end(png, NULL);
|
||||||
|
|
||||||
|
end:
|
||||||
|
if(fp)
|
||||||
|
fclose(fp);
|
||||||
|
return ok;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
debugLog("Failed to save PNG");
|
||||||
|
ok = false;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
11
BBGE/Core.h
11
BBGE/Core.h
|
@ -361,7 +361,7 @@ public:
|
||||||
|
|
||||||
unsigned char *grabScreenshot(int x, int y, int w, int h);
|
unsigned char *grabScreenshot(int x, int y, int w, int h);
|
||||||
unsigned char *grabCenteredScreenshot(int w, int h);
|
unsigned char *grabCenteredScreenshot(int w, int h);
|
||||||
int saveScreenshot(const std::string &filename);
|
bool saveScreenshot(const std::string &filename, bool png);
|
||||||
|
|
||||||
bool minimized;
|
bool minimized;
|
||||||
std::string getEnqueuedJumpState();
|
std::string getEnqueuedJumpState();
|
||||||
|
@ -456,9 +456,9 @@ public:
|
||||||
|
|
||||||
CoreSettings settings;
|
CoreSettings settings;
|
||||||
|
|
||||||
int tgaSave(const char *filename, short int width, short int height, unsigned char pixelDepth, unsigned char *imageData);
|
bool tgaSave(const char *filename, short int width, short int height, unsigned char pixelDepth, unsigned char *imageData);
|
||||||
int zgaSave(const char *filename, short int width, short int height, unsigned char pixelDepth, unsigned char *imageData);
|
bool zgaSave(const char *filename, short int width, short int height, unsigned char pixelDepth, unsigned char *imageData);
|
||||||
int pngSave(const char *filename, unsigned width, unsigned height, unsigned char *data);
|
bool pngSave(const char *filename, unsigned width, unsigned height, unsigned char *data);
|
||||||
volatile int dbg_numThreadDecoders;
|
volatile int dbg_numThreadDecoders;
|
||||||
|
|
||||||
virtual void onBackgroundUpdate();
|
virtual void onBackgroundUpdate();
|
||||||
|
@ -535,11 +535,8 @@ protected:
|
||||||
int _vsync, _bpp;
|
int _vsync, _bpp;
|
||||||
bool _fullscreen;
|
bool _fullscreen;
|
||||||
|
|
||||||
int numSavedScreenshots;
|
|
||||||
|
|
||||||
CountedPtr<Texture> texError;
|
CountedPtr<Texture> texError;
|
||||||
|
|
||||||
int tgaSaveSeries(char *filename, short int width, short int height, unsigned char pixelDepth, unsigned char *imageData);
|
|
||||||
virtual void onUpdate(float dt);
|
virtual void onUpdate(float dt);
|
||||||
virtual void onRender(){}
|
virtual void onRender(){}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue