Screenshots don't overwrite existing
by Josh Moore · 04/11/2006 (2:02 pm) · 4 comments
The current screenshot system uses saved pref variables for naming so that the code doesn't create new screenshots to overwrite existing files(and to give your screenshots some kind of order). The problem with this is that sometimes the prefs do not get saved, and sometimes they get deleted. This resource will make a call to screenshot(...); fail if there's a file with the same name already in existance, and will attempt 3 more screenshots automaticly.
So first of all, open engine/game/game.cc and find:
and replace the entire function with:
As you can tell, I've changed the return type of screenshot(...); to a boolean and added a Platform::isFile check to the function(as well as adding the proper returns where needed).
Save and compile.
OK, so now your screenshots will not overwrite existing ones. Great, so how can we make it so it'll at least try to take the screenie if it fails at first?
Easy, open up common/client/screenshot.cs and replace:
with:
Now it will try to take the shot 3 extra times if it fails at first, awesome.
So first of all, open engine/game/game.cc and find:
ConsoleFunction(screenShot, void.......
and replace the entire function with:
ConsoleFunction(screenShot, bool, 3, 3, "(string file, string format)"
"Take a screenshot.\n\n"
"@param format One of JPEG or PNG.")
{
// Added so screenshots cannot overwrite previous ones - JM
if(Platform::isFile(argv[1]))
return false;
FileStream fStream;
if(!fStream.open(argv[1], FileStream::Write))
{
Con::printf("Failed to open file '%s'.", argv[1]);
return false;
}
glReadBuffer(GL_FRONT);
Point2I extent = Canvas->getExtent();
U8 * pixels = new U8[extent.x * extent.y * 3];
glReadPixels(0, 0, extent.x, extent.y, GL_RGB, GL_UNSIGNED_BYTE, pixels);
GBitmap * bitmap = new GBitmap;
bitmap->allocateBitmap(U32(extent.x), U32(extent.y));
// flip the rows
for(U32 y = 0; y < extent.y; y++)
dMemcpy(bitmap->getAddress(0, extent.y - y - 1), pixels + y * extent.x * 3, U32(extent.x * 3));
if ( dStrcmp( argv[2], "JPEG" ) == 0 )
bitmap->writeJPEG(fStream);
else if( dStrcmp( argv[2], "PNG" ) == 0)
bitmap->writePNG(fStream);
else
bitmap->writePNG(fStream);
fStream.close();
delete [] pixels;
delete bitmap;
return true;
}As you can tell, I've changed the return type of screenshot(...); to a boolean and added a Platform::isFile check to the function(as well as adding the proper returns where needed).
Save and compile.
OK, so now your screenshots will not overwrite existing ones. Great, so how can we make it so it'll at least try to take the screenie if it fails at first?
Easy, open up common/client/screenshot.cs and replace:
if($pref::Video::screenShotFormat $= "JPEG")
screenShot($name @ ".jpg", "JPEG");
else
if($pref::Video::screenShotFormat $= "PNG")
screenShot($name @ ".png", "PNG");
else
screenShot($name @ ".png", "PNG");with:
if($pref::Video::screenShotFormat $= "JPEG") {
if(!screenShot($name @ ".jpg", "JPEG")) {
error("Screenshot failed! Attempting 3 more times.");
// Screenshot failed, try 3 more times
for(%i = 0; %i < 3; %i++) {
$name = "screenshot_" @ formatSessionNumber($pref::Video::screenShotSession) @ "-" @ formatImageNumber($screenshotNumber++);
if(screenShot($name @ ".jpg", "JPEG")) break;
error("Screenshot("@ %i+1 @") failed!");
}
}
}
else {
if(!screenShot($name @ ".png", "PNG")) {
error("Screenshot failed! Attempting 3 more times.");
// Screenshot failed, try 3 more times
for(%i = 0; %i < 3; %i++) {
$name = "screenshot_" @ formatSessionNumber($pref::Video::screenShotSession) @ "-" @ formatImageNumber($screenshotNumber++);
if(screenShot($name @ ".png", "PNG")) break;
error("Screenshot("@ %i+1 @") failed!");
}
}
}Now it will try to take the shot 3 extra times if it fails at first, awesome.
About the author
Recent Blogs
• What's up & T2d• Lightning Anyone?
• Quick .plan - TSE works...
• Shader deletion for TSE GFX
• Numeric Energy HUD

Torque Owner Josh Moore