--- clientCommands.cxx.old 2008-02-03 18:10:02.000000000 +0000 +++ clientCommands.cxx.new 2008-02-03 18:38:20.000000000 +0000 @@ -20,6 +20,8 @@ # include #endif +#include + /* common implementation headers */ #include "BZDBCache.h" #include "TextUtils.h" @@ -39,6 +41,10 @@ #include "HUDRenderer.h" #include "HUDui.h" +pthread_mutex_t mutex; +void *screenshot(void *); + + /** jump */ static std::string cmdJump(const std::string&, @@ -635,12 +641,31 @@ static std::string cmdScreenshot(const std::string&, const CommandManager::ArgList& args, bool*) { + pthread_t thread; + static int first = 1; + + if (first) { + pthread_mutex_init(&mutex, NULL); + first = 0; + } + int w = mainWindow->getWidth(), h = mainWindow->getHeight(); + unsigned char *pixels = (unsigned char *) malloc(h * w * 3); + glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels); + pthread_create(&thread, NULL, screenshot, (void *) pixels); + + return (""); +} + + +void *screenshot(void *sptr) +{ + unsigned char *pixels = (unsigned char *) sptr; + + pthread_mutex_lock(&mutex); + int snap = atoi(BZDB.get(std::string("lastScreenshot")).c_str()); snap++; - if (args.size() != 0) - return "usage: screenshot"; - std::string filename = getScreenShotDirName(); const std::string prefix = "bzfi"; const std::string ext = ".png"; @@ -682,6 +707,8 @@ BZDB.setInt(std::string("lastScreenshot"),snap); + pthread_mutex_unlock(&mutex); + std::ostream* f = FILEMGR.createDataOutStream (filename.c_str(), true, true); if (f != NULL) { @@ -689,16 +716,6 @@ const unsigned long blength = h * w * 3 + h; //size of b[] and br[] unsigned char* b = new unsigned char[blength]; //screen of pixels + column for filter type required by PNG - filtered data - // pause to prevent dt from accumulating until done screenshotting - LocalPlayer *myTank = LocalPlayer::getMyTank(); - bool temp_paused = false; - if (myTank && !myTank->isPaused()) - { - // myTank->setDeadStop(); - // serverLink->sendPlayerUpdate(myTank); - temp_paused = true; - } - //Prepare gamma table const bool gammaAdjust = BZDB.isSet("gamma"); unsigned char gammaTable[256]; @@ -759,7 +776,7 @@ for (i = h - 1; i >= 0; i--) { const unsigned long line = (h - (i + 1)) * (w * 3 + 1); //beginning of this line b[line] = 0; //filter type byte at the beginning of each scanline (0 = no filter, 1 = sub filter) - glReadPixels(0, i, w, 1, GL_RGB, GL_UNSIGNED_BYTE, b + line + 1); //capture line + memcpy(b + line + 1, pixels + i * w * 3, w * 3); // apply gamma correction if necessary if (gammaAdjust) { unsigned char *ptr = b + line + 1; @@ -770,11 +787,6 @@ } } - // let the user know we're paused while saving the file - if (temp_paused) { - drawFrame(0.0f); - } - unsigned long zlength = blength + 15; //length of bz[], will be changed by zlib to the length of the compressed string contained therein unsigned char* bz = new unsigned char[zlength]; //just like b, but compressed; might get bigger, so give it room // compress b into bz @@ -807,10 +819,12 @@ crc = htonl(crc32(crc, b, (unsigned)strlen(reinterpret_cast(b)))); f->write((char*) &crc, 4); //(crc) write crc - // tEXt chunk containing gl renderer information - std::string renderer = reinterpret_cast(glGetString(GL_VENDOR)); renderer += ": "; - renderer += reinterpret_cast(glGetString(GL_RENDERER)); renderer += " (OpenGL "; - renderer += reinterpret_cast(glGetString(GL_VERSION)); renderer += ")"; + // tEXt chunk containing gl renderer information + //std::string renderer = reinterpret_cast(glGetString(GL_VENDOR)); renderer += ": "; + //renderer += reinterpret_cast(glGetString(GL_RENDERER)); renderer += " (OpenGL "; + //renderer += reinterpret_cast(glGetString(GL_VERSION)); renderer += ")"; + std::string renderer = ""; + temp = htonl(12 + (int)renderer.size()); //(length) tEXt is len("GL Renderer") + 1 + renderer.size() f->write((char*) &temp, 4); temp = htonl(PNGTAG("tEXt")); //(tag) tEXt @@ -838,22 +852,9 @@ delete [] bz; delete [] b; delete f; - char notify[128]; - snprintf(notify, 128, "%s: %dx%d", filename.c_str(), w, h); - controlPanel->addMessage(notify); - - // unpause to prevent dt from accumulating until done screenshotting - if (myTank && temp_paused) - { - // do a micro update to prevent DT overuns - // myTank->update(0.001f); - // myTank->setDeadStop(); - // serverLink->sendPlayerUpdate(myTank); - } - // update the display regardless of pausing - drawFrame(0.0f); + } - return std::string(); + return (void *) NULL; }