Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-03-25 18:51:27 +0000
committerStijn Buys <ingar@osirion.org>2008-03-25 18:51:27 +0000
commita29aa1ee2935857f616351a23578311f514516d4 (patch)
tree5d9f241b0bb1facc6dc31a4ae4e26a4182641c3b /src/client/video.cc
parentf2c7b3846468461d3d88a797b4cc006ee4d3b624 (diff)
screenshots
Diffstat (limited to 'src/client/video.cc')
-rw-r--r--src/client/video.cc97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/client/video.cc b/src/client/video.cc
index 86fca89..a7a74d5 100644
--- a/src/client/video.cc
+++ b/src/client/video.cc
@@ -4,10 +4,14 @@
the terms and conditions of the GNU General Public License version 2
*/
+#include <fstream>
+#include <sstream>
+
#include "client/video.h"
#include "client/view.h"
#include "render/render.h"
#include "core/core.h"
+#include "filesystem/filesystem.h"
#include "sys/sys.h"
#include <SDL/SDL.h>
@@ -141,6 +145,99 @@ void shutdown()
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
+void screenshot()
+{
+ int number = 0;
+ bool available = false;
+ std::string shortname;
+ std::string filename;
+
+ // make sure the screenshots folder exists
+ filename.assign(filesystem::writedir);
+ filename.append("screenshots/");
+ sys::mkdir(filename);
+
+ // find the first available screenshotxxx.tga
+ do {
+ std::stringstream nstr;
+ nstr << number;
+ shortname.assign(nstr.str());
+
+ while(shortname.size() < 3)
+ shortname.insert(0, 1, '0');
+
+ shortname.insert(0, "screenshots/osirion");
+ shortname.append(".tga");
+
+ filename.assign(filesystem::writedir);
+ filename.append(shortname);
+
+ FILE *handle = fopen(filename.c_str(), "r");
+ if (handle) {
+ fclose(handle);
+ number++;
+ } else {
+ available = true;
+ }
+ } while (!available);
+
+ std::ofstream ofs(filename.c_str());
+
+ if (!ofs.is_open()) {
+ con_warn << "Could not write " << shortname << std::endl;
+ return;
+ }
+
+ // TGA header
+ // TODO: RL-encoding, image ID
+
+ // note: see http://www.fileformat.info/format/tga/egff.htm
+ unsigned char header[18];
+ memset(header, 0, sizeof(header));
+
+ // byte 0 - image ID field lenght = 0 (no image ID field present)
+ // byte 1 - color map type = 0 (no palette present)
+ // byte 2 - image type = 2 (truecolor without RLE)
+ header[2] = 2;
+ // byte 3-11 - palette data (not used)
+ // byte 12+13 - image width
+ header[12] = (video::width & 0xff);
+ header[13] = ((video::width >> 8) & 0xff);
+ // byte 14+15 - image height
+ header[14] = (video::height & 0xff);
+ header[15] = ((video::height >> 8) & 0xff);
+ // byte 16 - image color depth = 24 (RGB)
+ header[16] = 24;
+ // byte 17 - image descriptor byte
+ header[17] = 0;
+
+ // allocate buffer to hold the RGB data
+ unsigned char *rgb_data = (unsigned char *) malloc(video::width * video::height * 3);
+
+ // read OpenGL pixels into the buffer
+ //glReadBuffer(GL_FRONT);
+ glReadPixels(0, 0, (GLsizei) video::width, (GLsizei) video::height, GL_RGB, GL_UNSIGNED_BYTE, (void *) rgb_data);
+
+ // either OpenGL actually returns BGR, or TGA wants BGR
+ for (size_t i = 0; i < (size_t) (video::width * video::height); i++) {
+ unsigned char tmp = rgb_data[i*3];
+ rgb_data[i*3] = rgb_data[i*3+2];
+ rgb_data[i*3+2] = tmp;
+ }
+
+ ofs.write((char *)header, sizeof(header));
+ ofs.write((char *)rgb_data, video::width * video::height * 3 );
+
+ // free the buffer
+ free(rgb_data);
+
+ // close file
+ ofs.close();
+
+ con_print << "Wrote " << shortname << std::endl;
+}
+
+
} // namespace video
} // namespace client