mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-30 14:14:43 +00:00
OPENGL/SDL: Add screenshot support.
This commit is contained in:
parent
37f7123552
commit
05c347fc8a
@ -29,6 +29,7 @@
|
||||
#include "common/textconsole.h"
|
||||
#include "common/translation.h"
|
||||
#include "common/algorithm.h"
|
||||
#include "common/file.h"
|
||||
#ifdef USE_OSD
|
||||
#include "common/tokenizer.h"
|
||||
#include "common/rect.h"
|
||||
@ -849,6 +850,11 @@ void OpenGLGraphicsManager::notifyContextChange(const Graphics::PixelFormat &def
|
||||
|
||||
GLCALL(glEnable(GL_TEXTURE_2D));
|
||||
|
||||
// We use a "pack" alignment (when reading from textures) to 4 here,
|
||||
// since the only place where we really use it is the BMP screenshot
|
||||
// code and that requires the same alignment too.
|
||||
GLCALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
|
||||
|
||||
// Query information needed by textures.
|
||||
Texture::queryTextureInformation();
|
||||
|
||||
@ -1082,4 +1088,61 @@ const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const {
|
||||
const uint width = _outputScreenWidth;
|
||||
const uint height = _outputScreenHeight;
|
||||
|
||||
// A line of a BMP image must have a size divisible by 4.
|
||||
// We calculate the padding bytes needed here.
|
||||
// Since we use a 3 byte per pixel mode, we can use width % 4 here, since
|
||||
// it is equal to 4 - (width * 3) % 4. (4 - (width * Bpp) % 4, is the
|
||||
// usual way of computing the padding bytes required).
|
||||
const uint linePaddingSize = width % 4;
|
||||
const uint lineSize = width * 3 + linePaddingSize;
|
||||
|
||||
// Allocate memory for screenshot
|
||||
uint8 *pixels = new uint8[lineSize * height];
|
||||
|
||||
// Get pixel data from OpenGL buffer
|
||||
GLCALL(glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
// BMP stores as BGR. Since we can't assume that GL_BGR is supported we
|
||||
// will swap the components from the RGB we read to BGR on our own.
|
||||
for (uint y = height; y-- > 0;) {
|
||||
uint8 *line = pixels + y * lineSize;
|
||||
|
||||
for (uint x = width; x > 0; --x, line += 3) {
|
||||
SWAP(line[0], line[2]);
|
||||
}
|
||||
}
|
||||
|
||||
// Open file
|
||||
Common::DumpFile out;
|
||||
out.open(filename);
|
||||
|
||||
// Write BMP header
|
||||
out.writeByte('B');
|
||||
out.writeByte('M');
|
||||
out.writeUint32LE(height * lineSize + 54);
|
||||
out.writeUint32LE(0);
|
||||
out.writeUint32LE(54);
|
||||
out.writeUint32LE(40);
|
||||
out.writeUint32LE(width);
|
||||
out.writeUint32LE(height);
|
||||
out.writeUint16LE(1);
|
||||
out.writeUint16LE(24);
|
||||
out.writeUint32LE(0);
|
||||
out.writeUint32LE(0);
|
||||
out.writeUint32LE(0);
|
||||
out.writeUint32LE(0);
|
||||
out.writeUint32LE(0);
|
||||
out.writeUint32LE(0);
|
||||
|
||||
// Write pixel data to BMP
|
||||
out.write(pixels, lineSize * height);
|
||||
|
||||
// Free allocated memory
|
||||
delete[] pixels;
|
||||
}
|
||||
|
||||
} // End of namespace OpenGL
|
||||
|
@ -247,6 +247,14 @@ protected:
|
||||
*/
|
||||
virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) = 0;
|
||||
|
||||
/**
|
||||
* Save a screenshot of the full display as BMP to the given file. This
|
||||
* uses Common::DumpFile for writing the screenshot.
|
||||
*
|
||||
* @param filename The output filename.
|
||||
*/
|
||||
void saveScreenshot(const Common::String &filename) const;
|
||||
|
||||
private:
|
||||
//
|
||||
// OpenGL utilities
|
||||
|
@ -355,6 +355,26 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.kbd.keycode == Common::KEYCODE_s) {
|
||||
// Alt-s creates a screenshot
|
||||
Common::String filename;
|
||||
|
||||
for (int n = 0;; n++) {
|
||||
SDL_RWops *file;
|
||||
|
||||
filename = Common::String::format("scummvm%05d.bmp", n);
|
||||
file = SDL_RWFromFile(filename.c_str(), "r");
|
||||
if (!file)
|
||||
break;
|
||||
SDL_RWclose(file);
|
||||
}
|
||||
|
||||
saveScreenshot(filename.c_str());
|
||||
debug("Saved screenshot '%s'", filename.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if (event.kbd.hasFlags(Common::KBD_CTRL | Common::KBD_ALT)) {
|
||||
if ( event.kbd.keycode == Common::KEYCODE_PLUS || event.kbd.keycode == Common::KEYCODE_MINUS
|
||||
|| event.kbd.keycode == Common::KEYCODE_KP_PLUS || event.kbd.keycode == Common::KEYCODE_KP_MINUS) {
|
||||
@ -502,7 +522,8 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
|
||||
bool OpenGLSdlGraphicsManager::isHotkey(const Common::Event &event) {
|
||||
if (event.kbd.hasFlags(Common::KBD_ALT)) {
|
||||
return event.kbd.keycode == Common::KEYCODE_RETURN
|
||||
|| event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER;
|
||||
|| event.kbd.keycode == (Common::KeyCode)SDLK_KP_ENTER
|
||||
|| event.kbd.keycode == Common::KEYCODE_s;
|
||||
} else if (event.kbd.hasFlags(Common::KBD_CTRL | Common::KBD_ALT)) {
|
||||
return event.kbd.keycode == Common::KEYCODE_PLUS || event.kbd.keycode == Common::KEYCODE_MINUS
|
||||
|| event.kbd.keycode == Common::KEYCODE_KP_PLUS || event.kbd.keycode == Common::KEYCODE_KP_MINUS
|
||||
|
Loading…
Reference in New Issue
Block a user