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/chat.cc | 4 +- src/client/console.cc | 4 +- src/client/input.cc | 5 ++- src/client/video.cc | 97 ++++++++++++++++++++++++++++++++++++++++++++++ src/client/video.h | 3 ++ src/client/view.h | 2 +- src/core/application.cc | 3 +- src/core/cvar.cc | 5 ++- src/core/cvar.h | 5 ++- src/filesystem/diskfile.cc | 2 +- src/filesystem/inifile.cc | 1 + src/render/draw.cc | 2 +- src/render/render.cc | 16 +++++--- src/render/render.h | 2 +- 14 files changed, 132 insertions(+), 19 deletions(-) diff --git a/src/client/chat.cc b/src/client/chat.cc index 8d5e94c..7f5c22c 100644 --- a/src/client/chat.cc +++ b/src/client/chat.cc @@ -40,7 +40,7 @@ void func_con_chat(std::string const &args) void init() { // add engine functions - core::Func::add("con_chat", (core::FuncPtr) func_con_chat); + //core::Func::add("con_chat", (core::FuncPtr) func_con_chat); history.clear(); history.push_back(""); @@ -52,7 +52,7 @@ void init() void shutdown() { // remove engine functions - core::Func::remove("con_chat"); + //core::Func::remove("con_chat"); history.clear(); input_pos = 0; diff --git a/src/client/console.cc b/src/client/console.cc index 67a6ac9..2d667a8 100644 --- a/src/client/console.cc +++ b/src/client/console.cc @@ -84,7 +84,7 @@ void init() console_visible = false; // add engine functions - core::Func::add("con_toggle", (core::FuncPtr) func_con_toggle); + //core::Func::add("con_toggle", (core::FuncPtr) func_con_toggle); text.clear(); console_scroll = 0; @@ -104,7 +104,7 @@ void shutdown() save_history(); // remove engine functions - core::Func::remove("con_toggle"); + //core::Func::remove("con_toggle"); text.clear(); console_scroll = 0; diff --git a/src/client/input.cc b/src/client/input.cc index 4d0f54b..1a61424 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -11,6 +11,7 @@ #include "client/console.h" #include "client/camera.h" #include "client/keyboard.h" +#include "client/video.h" #include "SDL/SDL.h" @@ -117,7 +118,9 @@ void frame(float seconds) switch (event.type) { case SDL_KEYUP: - if (!chat::visible() && !console::visible() && + if (event.key.keysym.sym == SDLK_PRINT) { + video::screenshot(); + } else if (!chat::visible() && !console::visible() && core::application()->connected() && core::localcontrol()) // send key events to the game world 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 diff --git a/src/client/video.h b/src/client/video.h index 2b3fc41..d453536 100644 --- a/src/client/video.h +++ b/src/client/video.h @@ -24,6 +24,9 @@ namespace video /// reset and clear the viewport void reset(); + /// make a screenshot + void screenshot(); + /// width of the window in pixels extern int width; diff --git a/src/client/view.h b/src/client/view.h index 6220147..d9e44ab 100644 --- a/src/client/view.h +++ b/src/client/view.h @@ -21,7 +21,7 @@ namespace view /// draw the next frame void frame(float seconds); - /// reset the projection matrix + /// reset OpenGL state void reset(); } // namespace view diff --git a/src/core/application.cc b/src/core/application.cc index efa7bca..d1dbcc0 100644 --- a/src/core/application.cc +++ b/src/core/application.cc @@ -168,7 +168,8 @@ void Application::init() Cvar::net_host = Cvar::get("net_host", "0.0.0.0", Cvar::Archive); Cvar::net_port = Cvar::get("net_port", "8042", Cvar::Archive); Cvar::net_maxclients = Cvar::get("net_maxclients", "16", Cvar::Archive); - + Cvar::net_timeout = Cvar::get("net_timeout", "20", Cvar::Archive); + // register our engine functions Func::add("print", func_print); Func::add("help", func_help); diff --git a/src/core/cvar.cc b/src/core/cvar.cc index e95f61c..518ec5a 100644 --- a/src/core/cvar.cc +++ b/src/core/cvar.cc @@ -24,6 +24,7 @@ Cvar *Cvar::sv_framerate = 0; Cvar *Cvar::net_host = 0; Cvar *Cvar::net_port = 0; Cvar *Cvar::net_maxclients = 0; +Cvar *Cvar::net_timeout = 0; std::map Cvar::registry; @@ -69,7 +70,7 @@ Cvar* Cvar::get(const char *name, const char *value, unsigned int flags) registry[std::string(name)] = c; (*c) = value; } - c->cvar_flags = flags; + c->cvar_flags |= flags; return c; } @@ -84,7 +85,7 @@ Cvar* Cvar::get(const char *name, float value, unsigned int flags) registry[std::string(name)] = c; (*c) = value; } - c->cvar_flags = flags; + c->cvar_flags |= flags; return c; } diff --git a/src/core/cvar.h b/src/core/cvar.h index 21f2601..8ced7a4 100644 --- a/src/core/cvar.h +++ b/src/core/cvar.h @@ -103,10 +103,11 @@ public: static Cvar *sv_dedicated; // dedicated server static Cvar *sv_private; // client with private server static Cvar *sv_framerate; // server framerate + static Cvar *net_host; // network server ip (default binds to all interfaces) static Cvar *net_port; // network port - static Cvar *net_maxclients; // maximum number of connected clients - + static Cvar *net_maxclients;// maximum number of connected clients + static Cvar *net_timeout; // network timeout in seconds private: std::string cvar_name; std::string cvar_str; diff --git a/src/filesystem/diskfile.cc b/src/filesystem/diskfile.cc index 8f84baf..11070f2 100644 --- a/src/filesystem/diskfile.cc +++ b/src/filesystem/diskfile.cc @@ -67,7 +67,7 @@ bool DiskFile::open(const char *filename) if (diskfile_handle) return true; - con_error << "Could not open " << filename << std::endl; + //con_error << "Could not open " << filename << std::endl; return false; } diff --git a/src/filesystem/inifile.cc b/src/filesystem/inifile.cc index dcc0876..d9f2839 100644 --- a/src/filesystem/inifile.cc +++ b/src/filesystem/inifile.cc @@ -31,6 +31,7 @@ void IniFile::open(std::string const & name) { filesystem::File *f = filesystem::open(inifile_name.c_str()); if (!f) { + con_warn << "Could not open " << inifile_name << std::endl; return; } diff --git a/src/render/draw.cc b/src/render/draw.cc index e3d4174..2775f63 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -465,7 +465,7 @@ void draw(math::Vector3f const &eye, math::Vector3f const &target, float seconds glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - if (r_drawwireframe && r_drawwireframe->value()) { + if (r_wireframe && r_wireframe->value()) { glPolygonMode(GL_FRONT, GL_LINE); } else { glPolygonMode(GL_FRONT, GL_FILL); diff --git a/src/render/render.cc b/src/render/render.cc index b7f42a8..15a6d5c 100644 --- a/src/render/render.cc +++ b/src/render/render.cc @@ -4,9 +4,14 @@ the terms of the GNU General Public License version 2 */ -// project headers +#include +#include +#include +#include + #include "render/render.h" #include "core/core.h" +#include "filesystem/filesystem.h" #include "sys/sys.h" namespace render { @@ -15,7 +20,7 @@ GLuint textures[32]; core::Cvar *r_drawradius = 0; core::Cvar *r_drawstats = 0; -core::Cvar *r_drawwireframe = 0; +core::Cvar *r_wireframe = 0; void init() { @@ -28,17 +33,17 @@ void init() con_print << "Loading textures..." << std::endl; if (!TGA::texture(textures, "bitmaps/loader.tga", 0)) { - //con_error << "Essential file bitmaps/loader.tga missing" << std::endl; + con_error << "Essential file bitmaps/loader.tga missing" << std::endl; core::application()->shutdown(); } if (!TGA::texture(textures, "bitmaps/conchars.tga", 1)) { - //con_error << "Essential file bitmaps/conchars.tga missing" << std::endl; + con_error << "Essential file bitmaps/conchars.tga missing" << std::endl; core::application()->shutdown(); } r_drawradius = core::Cvar::get("r_drawradius", "0", core::Cvar::Archive); r_drawstats = core::Cvar::get("r_drawstats", "0", core::Cvar::Archive); - r_drawwireframe = core::Cvar::get("r_drawwireframe", "0", core::Cvar::Archive); + r_wireframe = core::Cvar::get("r_wireframe", "0", core::Cvar::Archive); } void shutdown() @@ -47,3 +52,4 @@ void shutdown() } } + diff --git a/src/render/render.h b/src/render/render.h index c622dfe..34ba974 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -24,8 +24,8 @@ namespace render { extern GLuint textures[32]; extern core::Cvar *r_drawradius; - extern core::Cvar *r_drawwireframe; extern core::Cvar *r_drawstats; + extern core::Cvar *r_wireframe; } #include "render/draw.h" -- cgit v1.2.3