diff options
Diffstat (limited to 'backends/graphics')
-rw-r--r-- | backends/graphics/opengl/gltexture.cpp | 2 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 151 | ||||
-rw-r--r-- | backends/graphics/openglsdl/openglsdl-graphics.cpp | 17 | ||||
-rw-r--r-- | backends/graphics/sdl/sdl-graphics.cpp | 14 |
4 files changed, 120 insertions, 64 deletions
diff --git a/backends/graphics/opengl/gltexture.cpp b/backends/graphics/opengl/gltexture.cpp index cd9e23cb71..7b7d40f174 100644 --- a/backends/graphics/opengl/gltexture.cpp +++ b/backends/graphics/opengl/gltexture.cpp @@ -149,7 +149,7 @@ void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLu glBindTexture(GL_TEXTURE_2D, _textureName); CHECK_GL_ERROR(); // Check if the buffer has its data contiguously - if (static_cast<int>(w) * _bytesPerPixel == pitch && w == _textureWidth) { + if (static_cast<int>(w) * _bytesPerPixel == pitch) { glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, _glFormat, _glType, buf); CHECK_GL_ERROR(); } else { diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index beac2f6d3e..9a2efe3eec 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -136,6 +136,8 @@ int OpenGLGraphicsManager::getDefaultGraphicsMode() const { bool OpenGLGraphicsManager::setGraphicsMode(int mode) { assert(_transactionMode == kTransactionActive); + setScale(2); + if (_oldVideoMode.setup && _oldVideoMode.mode == mode) return true; @@ -166,11 +168,9 @@ void OpenGLGraphicsManager::resetGraphicsScale() { } #ifdef USE_RGB_COLOR - Graphics::PixelFormat OpenGLGraphicsManager::getScreenFormat() const { return _screenFormat; } - #endif void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::PixelFormat *format) { @@ -308,7 +308,7 @@ int16 OpenGLGraphicsManager::getWidth() { void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num) { assert(colors); - + #ifdef USE_RGB_COLOR assert(_screenFormat.bytesPerPixel == 1); #endif @@ -324,7 +324,7 @@ void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num) void OpenGLGraphicsManager::grabPalette(byte *colors, uint start, uint num) { assert(colors); - + #ifdef USE_RGB_COLOR assert(_screenFormat.bytesPerPixel == 1); #endif @@ -341,9 +341,9 @@ void OpenGLGraphicsManager::copyRectToScreen(const byte *buf, int pitch, int x, // Copy buffer data to game screen internal buffer const byte *src = buf; - byte *dst = (byte *)_screenData.pixels + y * _screenData.pitch; + byte *dst = (byte *)_screenData.pixels + y * _screenData.pitch + x * _screenData.bytesPerPixel; for (int i = 0; i < h; i++) { - memcpy(dst + x * _screenData.bytesPerPixel, src, w * _screenData.bytesPerPixel); + memcpy(dst, src, w * _screenData.bytesPerPixel); src += pitch; dst += _screenData.pitch; } @@ -367,6 +367,7 @@ void OpenGLGraphicsManager::fillScreen(uint32 col) { if (_gameTexture == NULL) return; +#ifdef USE_RGB_COLOR if (_screenFormat.bytesPerPixel == 1) { memset(_screenData.pixels, col, _screenData.h * _screenData.pitch); } else if (_screenFormat.bytesPerPixel == 2) { @@ -392,7 +393,9 @@ void OpenGLGraphicsManager::fillScreen(uint32 col) { pixels[i] = col; } } - +#else + memset(_screenData.pixels, col, _screenData.h * _screenData.pitch); +#endif _screenNeedsRedraw = true; } @@ -558,7 +561,8 @@ void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int #endif // Allocate space for cursor data - if (_cursorData.w != w || _cursorData.h != h) + if (_cursorData.w != w || _cursorData.h != h || + _cursorData.bytesPerPixel != _cursorFormat.bytesPerPixel) _cursorData.create(w, h, _cursorFormat.bytesPerPixel); // Save cursor data @@ -754,11 +758,17 @@ void OpenGLGraphicsManager::refreshOverlay() { void OpenGLGraphicsManager::refreshCursor() { _cursorNeedsRedraw = false; - if (_cursorFormat.bytesPerPixel == 1) { - // Create a temporary RGBA8888 surface - byte *surface = new byte[_cursorState.w * _cursorState.h * 4]; - memset(surface, 0, _cursorState.w * _cursorState.h * 4); + // Allocate a texture big enough for cursor + _cursorTexture->allocBuffer(_cursorState.w, _cursorState.h); + // Create a temporary RGBA8888 surface + byte *surface = new byte[_cursorState.w * _cursorState.h * 4]; + memset(surface, 0, _cursorState.w * _cursorState.h * 4); + + byte *dst = surface; + + // Convert the paletted cursor to RGBA8888 + if (_cursorFormat.bytesPerPixel == 1) { // Select palette byte *palette; if (_cursorPaletteDisabled) @@ -768,7 +778,6 @@ void OpenGLGraphicsManager::refreshCursor() { // Convert the paletted cursor to RGBA8888 const byte *src = (byte *)_cursorData.pixels; - byte *dst = surface; for (int i = 0; i < _cursorState.w * _cursorState.h; i++) { // Check for keycolor if (src[i] != _cursorKeyColor) { @@ -779,16 +788,42 @@ void OpenGLGraphicsManager::refreshCursor() { } dst += 4; } + } else { + const bool gotNoAlpha = (_cursorFormat.aLoss == 8); + + // Convert the RGB cursor to RGBA8888 + if (_cursorFormat.bytesPerPixel == 2) { + const uint16 *src = (uint16 *)_cursorData.pixels; + for (int i = 0; i < _cursorState.w * _cursorState.h; i++) { + // Check for keycolor + if (src[i] != _cursorKeyColor) { + _cursorFormat.colorToARGB(src[i], dst[3], dst[0], dst[1], dst[2]); + + if (gotNoAlpha) + dst[3] = 255; + } + dst += 4; + } + } else if (_cursorFormat.bytesPerPixel == 4) { + const uint32 *src = (uint32 *)_cursorData.pixels; + for (int i = 0; i < _cursorState.w * _cursorState.h; i++) { + // Check for keycolor + if (src[i] != _cursorKeyColor) { + _cursorFormat.colorToARGB(src[i], dst[3], dst[0], dst[1], dst[2]); + + if (gotNoAlpha) + dst[3] = 255; + } + dst += 4; + } + } + } - // Allocate a texture big enough for cursor - _cursorTexture->allocBuffer(_cursorState.w, _cursorState.h); - - // Update the texture with new cursor - _cursorTexture->updateBuffer(surface, _cursorState.w * 4, 0, 0, _cursorState.w, _cursorState.h); + // Update the texture with new cursor + _cursorTexture->updateBuffer(surface, _cursorState.w * 4, 0, 0, _cursorState.w, _cursorState.h); - // Free the temp surface - delete[] surface; - } + // Free the temp surface + delete[] surface; } void OpenGLGraphicsManager::refreshCursorScale() { @@ -811,7 +846,8 @@ void OpenGLGraphicsManager::refreshCursorScale() { } else { // Otherwise, scale the cursor for the overlay int targetScaleFactor = MIN(_cursorTargetScale, _videoMode.scaleFactor); - int actualFactor = screenScaleFactor - (targetScaleFactor - 1) * 10000; + // We limit the maximum scale to 3 here to avoid too big cursors, for large overlay resolutions + int actualFactor = MIN<uint>(3, screenScaleFactor - (targetScaleFactor - 1)) * 10000; _cursorState.rW = (int16)(_cursorState.w * actualFactor / 10000); _cursorState.rH = (int16)(_cursorState.h * actualFactor / 10000); _cursorState.rHotX = (int16)(_cursorState.hotX * actualFactor / 10000); @@ -873,6 +909,11 @@ void OpenGLGraphicsManager::getGLPixelFormat(Graphics::PixelFormat pixelFormat, intFormat = GL_RGBA; glFormat = GL_RGBA; gltype = GL_UNSIGNED_SHORT_5_5_5_1; + } else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) { // RGB555 + bpp = 2; + intFormat = GL_RGB; + glFormat = GL_BGRA; + gltype = GL_UNSIGNED_SHORT_1_5_5_5_REV; } else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0)) { // RGBA4444 bpp = 2; intFormat = GL_RGBA; @@ -963,7 +1004,7 @@ void OpenGLGraphicsManager::internUpdateScreen() { refreshOverlay(); // Draw the overlay - _overlayTexture->drawTexture(_displayX, _displayY, _displayWidth, _displayHeight); + _overlayTexture->drawTexture(0, 0, _videoMode.overlayWidth, _videoMode.overlayHeight); } if (_cursorVisible) { @@ -1059,10 +1100,14 @@ void OpenGLGraphicsManager::initGL() { void OpenGLGraphicsManager::loadTextures() { #ifdef USE_RGB_COLOR - if (_transactionDetails.formatChanged && _gameTexture) + if (_transactionDetails.formatChanged && _gameTexture) { delete _gameTexture; + _gameTexture = 0; + } #endif + uint gameScreenBPP = 0; + if (!_gameTexture) { byte bpp; GLenum intformat; @@ -1073,6 +1118,7 @@ void OpenGLGraphicsManager::loadTextures() { #else getGLPixelFormat(Graphics::PixelFormat::createFormatCLUT8(), bpp, intformat, format, type); #endif + gameScreenBPP = bpp; _gameTexture = new GLTexture(bpp, intformat, format, type); } else _gameTexture->refresh(); @@ -1093,7 +1139,7 @@ void OpenGLGraphicsManager::loadTextures() { _cursorTexture = new GLTexture(4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE); else _cursorTexture->refresh(); - + GLint filter = _videoMode.antialiasing ? GL_LINEAR : GL_NEAREST; _gameTexture->setFilter(filter); _overlayTexture->setFilter(filter); @@ -1104,21 +1150,38 @@ void OpenGLGraphicsManager::loadTextures() { _overlayTexture->allocBuffer(_videoMode.overlayWidth, _videoMode.overlayHeight); _cursorTexture->allocBuffer(_cursorState.w, _cursorState.h); - if (_transactionDetails.formatChanged || + if ( +#ifdef USE_RGB_COLOR + _transactionDetails.formatChanged || +#endif _oldVideoMode.screenWidth != _videoMode.screenWidth || _oldVideoMode.screenHeight != _videoMode.screenHeight) _screenData.create(_videoMode.screenWidth, _videoMode.screenHeight, - _screenFormat.bytesPerPixel); +#ifdef USE_RGB_COLOR + _screenFormat.bytesPerPixel +#else + 1 +#endif + ); + if (_oldVideoMode.overlayWidth != _videoMode.overlayWidth || _oldVideoMode.overlayHeight != _videoMode.overlayHeight) _overlayData.create(_videoMode.overlayWidth, _videoMode.overlayHeight, _overlayFormat.bytesPerPixel); - + _screenNeedsRedraw = true; _overlayNeedsRedraw = true; _cursorNeedsRedraw = true; + // We need to setup a proper unpack alignment value here, else we will + // get problems with the texture updates, in case the surface data is + // not properly aligned. + // For now we use the gcd of the game screen format and 2, since 2 is + // the BPP value for the overlay and the OSD. + if (gameScreenBPP) + glPixelStorei(GL_UNPACK_ALIGNMENT, Common::gcd<uint>(gameScreenBPP, 2)); + #ifdef USE_OSD if (!_osdTexture) _osdTexture = new GLTexture(2, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); @@ -1166,32 +1229,20 @@ uint OpenGLGraphicsManager::getAspectRatio() { } void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) { - if (_videoMode.mode == OpenGL::GFX_NORMAL) { - if (_videoMode.hardwareWidth != _videoMode.overlayWidth) - x = x * _videoMode.overlayWidth / _videoMode.hardwareWidth; - if (_videoMode.hardwareHeight != _videoMode.overlayHeight) - y = y * _videoMode.overlayHeight / _videoMode.hardwareHeight; - - if (!_overlayVisible) { - x /= _videoMode.scaleFactor; - y /= _videoMode.scaleFactor; - } + if (_overlayVisible) + return; - } else { + if (_videoMode.mode == OpenGL::GFX_NORMAL) { + x /= _videoMode.scaleFactor; + y /= _videoMode.scaleFactor; + } else if (!_overlayVisible) { x -= _displayX; y -= _displayY; - if (_overlayVisible) { - if (_displayWidth != _videoMode.overlayWidth) - x = x * _videoMode.overlayWidth / _displayWidth; - if (_displayHeight != _videoMode.overlayHeight) - y = y * _videoMode.overlayHeight / _displayHeight; - } else { - if (_displayWidth != _videoMode.screenWidth) - x = x * _videoMode.screenWidth / _displayWidth; - if (_displayHeight != _videoMode.screenHeight) - y = y * _videoMode.screenHeight / _displayHeight; - } + if (_displayWidth != _videoMode.screenWidth) + x = x * _videoMode.screenWidth / _displayWidth; + if (_displayHeight != _videoMode.screenHeight) + y = y * _videoMode.screenHeight / _displayHeight; } } diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index c7ce0aa7de..cbc152a4a3 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -121,6 +121,7 @@ void OpenGLSdlGraphicsManager::detectSupportedFormats() { #endif Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), // RGB565 Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0), // RGB5551 + Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0), // RGB555 Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0), // RGBA4444 #ifndef USE_GLES Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12) // ARGB4444 @@ -344,13 +345,10 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() { if (_aspectRatioCorrection) _videoMode.mode = OpenGL::GFX_4_3; - _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor; - _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor; - // If the screen was resized, do not change its size if (!_screenResized) { - _videoMode.hardwareWidth = _videoMode.overlayWidth; - _videoMode.hardwareHeight = _videoMode.overlayHeight; + _videoMode.overlayWidth = _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor; + _videoMode.overlayHeight = _videoMode.hardwareHeight = _videoMode.screenHeight * _videoMode.scaleFactor; int screenAspectRatio = _videoMode.screenWidth * 10000 / _videoMode.screenHeight; int desiredAspectRatio = getAspectRatio(); @@ -365,6 +363,9 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() { // the width is modified it can break the overlay. if (_videoMode.hardwareHeight > _videoMode.overlayHeight) _videoMode.overlayHeight = _videoMode.hardwareHeight; + } else { + _videoMode.overlayWidth = _videoMode.hardwareWidth; + _videoMode.overlayHeight = _videoMode.hardwareHeight; } _screenResized = false; @@ -376,11 +377,15 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() { SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if (_videoMode.fullscreen) + if (_videoMode.fullscreen) { if (!setupFullscreenMode()) // Failed setuping a fullscreen mode return false; + _videoMode.overlayWidth = _videoMode.hardwareWidth; + _videoMode.overlayHeight = _videoMode.hardwareHeight; + } + uint32 flags = SDL_OPENGL; if (_videoMode.fullscreen) diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp index 15d896c57a..d8b686e61f 100644 --- a/backends/graphics/sdl/sdl-graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -1166,25 +1166,25 @@ void SdlGraphicsManager::copyRectToScreen(const byte *src, int pitch, int x, int error("SDL_LockSurface failed: %s", SDL_GetError()); #ifdef USE_RGB_COLOR - byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth * _screenFormat.bytesPerPixel + x * _screenFormat.bytesPerPixel; - if (_videoMode.screenWidth == w && pitch == w * _screenFormat.bytesPerPixel) { - memcpy(dst, src, h*w*_screenFormat.bytesPerPixel); + byte *dst = (byte *)_screen->pixels + y * _screen->pitch + x * _screenFormat.bytesPerPixel; + if (_videoMode.screenWidth == w && pitch == _screen->pitch) { + memcpy(dst, src, h*pitch); } else { do { memcpy(dst, src, w * _screenFormat.bytesPerPixel); src += pitch; - dst += _videoMode.screenWidth * _screenFormat.bytesPerPixel; + dst += _screen->pitch; } while (--h); } #else - byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x; - if (_videoMode.screenWidth == pitch && pitch == w) { + byte *dst = (byte *)_screen->pixels + y * _screen->pitch + x; + if (_screen->pitch == pitch && pitch == w) { memcpy(dst, src, h*w); } else { do { memcpy(dst, src, w); src += pitch; - dst += _videoMode.screenWidth; + dst += _screen->pitch; } while (--h); } #endif |