SDL_Surface *SdlScreenshotHelper::getScreenshot() { if (mainGraphics == nullptr) return nullptr; #if SDL_BYTEORDER == SDL_BIG_ENDIAN const int rmask = 0xff000000; const int gmask = 0x00ff0000; const int bmask = 0x0000ff00; #else // SDL_BYTEORDER == SDL_BIG_ENDIAN const int rmask = 0x000000ff; const int gmask = 0x0000ff00; const int bmask = 0x00ff0000; #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN const int amask = 0x00000000; SDL_Surface *const screenshot = MSDL_CreateRGBSurface(SDL_SWSURFACE, mainGraphics->mWidth, mainGraphics->mHeight, 24, rmask, gmask, bmask, amask); #ifndef USE_SDL2 if (screenshot != nullptr) SDL_BlitSurface(mainGraphics->mWindow, nullptr, screenshot, nullptr); #endif // USE_SDL2 return screenshot; }
void Minimap::setMap(const Map *const map) { BLOCK_START("Minimap::setMap") std::string caption; if (map) caption = map->getName(); if (caption.empty()) { // TRANSLATORS: mini map window name caption = _("Map"); } setCaption(caption); deleteMapImage(); if (map) { if (config.getBoolValue("showExtMinimaps")) { SDL_Surface *const surface = MSDL_CreateRGBSurface(SDL_SWSURFACE, map->getWidth(), map->getHeight(), 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000); if (!surface) { if (!isSticky()) setVisible(Visible_false); BLOCK_END("Minimap::setMap") return; } // I'm not sure if the locks are necessary since it's a SWSURFACE SDL_LockSurface(surface); int* data = static_cast<int*>(surface->pixels); if (!data) { if (!isSticky()) setVisible(Visible_false); BLOCK_END("Minimap::setMap") return; } const int size = surface->h * surface->w; const int mask = (BlockMask::WALL | BlockMask::AIR | BlockMask::WATER); for (int ptr = 0; ptr < size; ptr ++) *(data ++) = -!(map->mMetaTiles[ptr].blockmask & mask); SDL_UnlockSurface(surface); mMapImage = imageHelper->load(surface); mMapImage->setAlpha(settings.guiAlpha); mCustomMapImage = true; MSDL_FreeSurface(surface); } else {
SDL_Surface *OpenGLImageHelper::convertSurface(SDL_Surface *tmpImage, int width, int height) { if (!tmpImage) return nullptr; int realWidth = powerOfTwo(width); int realHeight = powerOfTwo(height); if (realWidth < width || realHeight < height) { logger->log("Warning: image too large, cropping to %dx%d texture!", tmpImage->w, tmpImage->h); } #ifdef USE_SDL2 SDL_SetSurfaceAlphaMod(tmpImage, SDL_ALPHA_OPAQUE); #else // Make sure the alpha channel is not used, but copied to destination SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); #endif // Determine 32-bit masks based on byte order uint32_t rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif if (tmpImage->format->BitsPerPixel != 32 || realWidth != width || realHeight != height || rmask != tmpImage->format->Rmask || gmask != tmpImage->format->Gmask || amask != tmpImage->format->Amask) { SDL_Surface *oldImage = tmpImage; #ifdef USE_SDL2 SDL_SetSurfaceBlendMode(oldImage, SDL_BLENDMODE_NONE); #endif tmpImage = MSDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, 32, rmask, gmask, bmask, amask); if (!tmpImage) { logger->log("Error, image convert failed: out of memory"); return nullptr; } SDL_BlitSurface(oldImage, nullptr, tmpImage, nullptr); } return tmpImage; }
SDL_Surface *OpenGLImageHelper::convertSurface(SDL_Surface *tmpImage, int width, int height) { if (!tmpImage) return nullptr; #ifdef USE_SDL2 SDL_SetSurfaceAlphaMod(tmpImage, SDL_ALPHA_OPAQUE); #else // USE_SDL2 // Make sure the alpha channel is not used, but copied to destination SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); #endif // USE_SDL2 // Determine 32-bit masks based on byte order uint32_t rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else // SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN if (tmpImage->format->BitsPerPixel != 32 || rmask != tmpImage->format->Rmask || gmask != tmpImage->format->Gmask || amask != tmpImage->format->Amask) { SDL_Surface *oldImage = tmpImage; #ifdef USE_SDL2 SDL_SetSurfaceBlendMode(oldImage, SDL_BLENDMODE_NONE); #endif // USE_SDL2 tmpImage = MSDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask); if (!tmpImage) { reportAlways("Error, image convert failed: out of memory"); return nullptr; } SDL_BlitSurface(oldImage, nullptr, tmpImage, nullptr); } return tmpImage; }
SDL_Surface *OpenGLScreenshotHelper::getScreenshot() { const int h = mainGraphics->mHeight; const int w = mainGraphics->mWidth - (mainGraphics->mWidth % 4); GLint pack = 1; SDL_Surface *const screenshot = MSDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000); if (screenshot == nullptr) return nullptr; if (SDL_MUSTLOCK(screenshot)) SDL_LockSurface(screenshot); const size_t lineSize = 3 * w; GLubyte *const buf = new GLubyte[lineSize]; // Grap the pixel buffer and write it to the SDL surface mglGetIntegerv(GL_PACK_ALIGNMENT, &pack); mglPixelStorei(GL_PACK_ALIGNMENT, 1); mglReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, screenshot->pixels); // Flip the screenshot, as OpenGL has 0,0 in bottom left const int h2 = h / 2; for (int i = 0; i < h2; i++) { GLubyte *const top = static_cast<GLubyte*>( screenshot->pixels) + lineSize * i; GLubyte *const bot = static_cast<GLubyte*>( screenshot->pixels) + lineSize * (h - 1 - i); memcpy(buf, top, lineSize); memcpy(top, bot, lineSize); memcpy(bot, buf, lineSize); } delete [] buf; if (config.getBoolValue("usefbo")) graphicsManager.deleteFBO(&mFbo); mglPixelStorei(GL_PACK_ALIGNMENT, pack); if (SDL_MUSTLOCK(screenshot)) SDL_UnlockSurface(screenshot); return screenshot; }
SDL_Surface *OpenGLImageHelper::create32BitSurface(int width, int height) const { #if SDL_BYTEORDER == SDL_BIG_ENDIAN const int rmask = 0xff000000; const int gmask = 0x00ff0000; const int bmask = 0x0000ff00; const int amask = 0x000000ff; #else const int rmask = 0x000000ff; const int gmask = 0x0000ff00; const int bmask = 0x00ff0000; const int amask = 0xff000000; #endif width = powerOfTwo(width); height = powerOfTwo(height); return MSDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask); }
SDL_Surface *MobileOpenGLScreenshotHelper::getScreenshot() { const int h = mainGraphics->mHeight; const int w = mainGraphics->mWidth - (mainGraphics->mWidth % 4); GLint pack = 1; SDL_Surface *const tmpImage = MSDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); if (tmpImage == nullptr) return nullptr; // Grap the pixel buffer and write it to the SDL surface mglGetIntegerv(GL_PACK_ALIGNMENT, &pack); mglPixelStorei(GL_PACK_ALIGNMENT, 1); mglReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->pixels); const size_t lineSize = 3 * w; GLubyte *const buf = new GLubyte[lineSize]; SDL_Surface *const screenshot = MSDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000); if (screenshot == nullptr) { MSDL_FreeSurface(tmpImage); delete [] buf; return nullptr; } #ifdef USE_SDL2 SDL_SetSurfaceAlphaMod(tmpImage, SDL_ALPHA_OPAQUE); SDL_SetSurfaceBlendMode(tmpImage, SDL_BLENDMODE_NONE); #else // USE_SDL2 // Make sure the alpha channel is not used, but copied to destination SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); #endif // USE_SDL2 if (SDL_MUSTLOCK(screenshot)) SDL_LockSurface(screenshot); SDL_BlitSurface(tmpImage, nullptr, screenshot, nullptr); MSDL_FreeSurface(tmpImage); // Flip the screenshot, as OpenGL has 0,0 in bottom left const int h2 = h / 2; for (int i = 0; i < h2; i++) { GLubyte *const top = static_cast<GLubyte*>( screenshot->pixels) + lineSize * i; GLubyte *const bot = static_cast<GLubyte*>( screenshot->pixels) + lineSize * (h - 1 - i); memcpy(buf, top, lineSize); memcpy(top, bot, lineSize); memcpy(bot, buf, lineSize); } delete [] buf; if (config.getBoolValue("usefbo")) graphicsManager.deleteFBO(&mFbo); mglPixelStorei(GL_PACK_ALIGNMENT, pack); if (SDL_MUSTLOCK(screenshot)) SDL_UnlockSurface(screenshot); return screenshot; }