aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'backends/graphics')
-rw-r--r--backends/graphics/opengl/gltexture.cpp2
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp151
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp17
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp14
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