From a29aa1ee2935857f616351a23578311f514516d4 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 25 Mar 2008 18:51:27 +0000 Subject: screenshots --- src/client/video.cc | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'src/client/video.cc') 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 +#include + #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 @@ -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 -- cgit v1.2.3