aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2013-08-19 00:44:55 +0200
committerJohannes Schickel2013-10-19 22:17:39 +0200
commitcc9c991d7711ec08b7f06ca712cd7dfabe69f752 (patch)
tree27734e68f564844cc1937b3ffa8b3afd534457a7
parent5ce830b97643fc76bdcafdbbe09e226519a9d2e6 (diff)
downloadscummvm-rg350-cc9c991d7711ec08b7f06ca712cd7dfabe69f752.tar.gz
scummvm-rg350-cc9c991d7711ec08b7f06ca712cd7dfabe69f752.tar.bz2
scummvm-rg350-cc9c991d7711ec08b7f06ca712cd7dfabe69f752.zip
OPENGL: Add OSD support.
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp131
-rw-r--r--backends/graphics/opengl/opengl-graphics.h48
2 files changed, 178 insertions, 1 deletions
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 87d6d3c2e5..3223075fbd 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -29,8 +29,16 @@
#include "common/textconsole.h"
#include "common/translation.h"
#include "common/algorithm.h"
+#ifdef USE_OSD
+#include "common/tokenizer.h"
+#include "common/rect.h"
+#endif
#include "graphics/conversion.h"
+#ifdef USE_OSD
+#include "graphics/fontman.h"
+#include "graphics/font.h"
+#endif
namespace OpenGL {
@@ -42,7 +50,11 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
_overlayVisible(false), _cursor(nullptr),
_cursorX(0), _cursorY(0), _cursorHotspotX(0), _cursorHotspotY(0), _cursorHotspotXScaled(0),
_cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0), _cursorKeyColor(0),
- _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false) {
+ _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false)
+#ifdef USE_OSD
+ , _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
+#endif
+ {
memset(_gamePalette, 0, sizeof(_gamePalette));
}
@@ -50,6 +62,9 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
delete _gameScreen;
delete _overlay;
delete _cursor;
+#ifdef USE_OSD
+ delete _osd;
+#endif
}
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) {
@@ -137,6 +152,12 @@ bool OpenGLGraphicsManager::setGraphicsMode(int mode) {
if (_cursor) {
_cursor->enableLinearFiltering(mode == GFX_LINEAR);
}
+
+#ifdef USE_OSD
+ if (_osd) {
+ _osd->enableLinearFiltering(mode == GFX_LINEAR);
+ }
+#endif
return true;
default:
@@ -374,6 +395,34 @@ void OpenGLGraphicsManager::updateScreen() {
glPopMatrix();
}
+
+#ifdef USE_OSD
+ // Fourth step: Draw the OSD.
+ if (_osdAlpha > 0) {
+ Common::StackLock lock(_osdMutex);
+
+ // Update alpha value.
+ const int diff = g_system->getMillis(false) - _osdFadeStartTime;
+ if (diff > 0) {
+ if (diff >= kOSDFadeOutDuration) {
+ // Back to full transparency.
+ _osdAlpha = 0;
+ } else {
+ // Do a fade out.
+ _osdAlpha = kOSDInitialAlpha - diff * kOSDInitialAlpha / kOSDFadeOutDuration;
+ }
+ }
+
+ // Set the OSD transparency.
+ GLCALL(glColor4f(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f));
+
+ // Draw the OSD texture.
+ _osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
+
+ // Reset color.
+ GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
+ }
+#endif
}
Graphics::Surface *OpenGLGraphicsManager::lockScreen() {
@@ -617,6 +666,59 @@ void OpenGLGraphicsManager::setCursorPalette(const byte *colors, uint start, uin
}
void OpenGLGraphicsManager::displayMessageOnOSD(const char *msg) {
+#ifdef USE_OSD
+ // HACK: Actually no client code should use graphics functions from
+ // another thread. But the MT-32 emulator still does, thus we need to
+ // make sure this doesn't happen while a updateScreen call is done.
+ Common::StackLock lock(_osdMutex);
+
+ // Slip up the lines.
+ Common::Array<Common::String> osdLines;
+ Common::StringTokenizer tokenizer(msg, "\n");
+ while (!tokenizer.empty()) {
+ osdLines.push_back(tokenizer.nextToken());
+ }
+
+ // Do the actual drawing like the SDL backend.
+ const Graphics::Font *font = getFontOSD();
+ Graphics::Surface *dst = _osd->getSurface();
+ _osd->fill(0);
+ _osd->flagDirty();
+
+ // Determine a rect which would contain the message string (clipped to the
+ // screen dimensions).
+ const int vOffset = 6;
+ const int lineSpacing = 1;
+ const int lineHeight = font->getFontHeight() + 2 * lineSpacing;
+ int width = 0;
+ int height = lineHeight * osdLines.size() + 2 * vOffset;
+ for (uint i = 0; i < osdLines.size(); i++) {
+ width = MAX(width, font->getStringWidth(osdLines[i]) + 14);
+ }
+
+ // Clip the rect
+ width = MIN<int>(width, dst->w);
+ height = MIN<int>(height, dst->h);
+
+ int dstX = (dst->w - width) / 2;
+ int dstY = (dst->h - height) / 2;
+
+ // Draw a dark gray rect.
+ const uint32 color = dst->format.RGBToColor(40, 40, 40);
+ dst->fillRect(Common::Rect(dstX, dstY, dstX + width, dstY + height), color);
+
+ // Render the message, centered, and in white
+ const uint32 white = dst->format.RGBToColor(255, 255, 255);
+ for (uint i = 0; i < osdLines.size(); ++i) {
+ font->drawString(dst, osdLines[i],
+ dstX, dstY + i * lineHeight + vOffset + lineSpacing, width,
+ white, Graphics::kTextAlignCenter);
+ }
+
+ // Init the OSD display parameters.
+ _osdAlpha = kOSDInitialAlpha;
+ _osdFadeStartTime = g_system->getMillis() + kOSDFadeOutDelay;
+#endif
}
void OpenGLGraphicsManager::setPalette(const byte *colors, uint start, uint num) {
@@ -672,6 +774,21 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
_overlay->allocate(overlayWidth, overlayHeight);
_overlay->fill(0);
+#ifdef USE_OSD
+ if (!_osd || _osd->getFormat() != _defaultFormatAlpha) {
+ delete _osd;
+ _osd = nullptr;
+
+ GLenum glIntFormat, glFormat, glType;
+ const bool supported = getGLPixelFormat(_defaultFormatAlpha, glIntFormat, glFormat, glType);
+ assert(supported);
+ _osd = new Texture(glIntFormat, glFormat, glType, _defaultFormatAlpha);
+ _osd->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR);
+ }
+ _osd->allocate(_outputScreenWidth, _outputScreenHeight);
+ _osd->fill(0);
+#endif
+
// Re-setup the scaling for the screen and cursor
recalculateDisplayArea();
recalculateCursorScaling();
@@ -729,6 +846,12 @@ void OpenGLGraphicsManager::notifyContextChange(const Graphics::PixelFormat &def
if (_cursor) {
_cursor->recreateInternalTexture();
}
+
+#ifdef USE_OSD
+ if (_osd) {
+ _osd->recreateInternalTexture();
+ }
+#endif
}
void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
@@ -923,4 +1046,10 @@ void OpenGLGraphicsManager::recalculateCursorScaling() {
}
}
+#ifdef USE_OSD
+const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
+ return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
+}
+#endif
+
} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 5aa521cb7a..d4bd0137ed 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -27,9 +27,19 @@
#include "backends/graphics/graphics.h"
#include "common/frac.h"
+#include "common/mutex.h"
+
+namespace Graphics {
+class Font;
+} // End of namespace Graphics
namespace OpenGL {
+// HACK: We use glColor in the OSD code. This might not be working on GL ES but
+// we still enable it because Tizen already shipped with it. Also, the
+// SurfaceSDL backend enables it and disabling it can cause issues in sdl.cpp.
+#define USE_OSD 1
+
class Texture;
enum {
@@ -415,6 +425,44 @@ private:
* The special cursor palette in case enabled.
*/
byte _cursorPalette[3 * 256];
+
+#ifdef USE_OSD
+ //
+ // OSD
+ //
+protected:
+ /**
+ * Returns the font used for on screen display
+ */
+ virtual const Graphics::Font *getFontOSD();
+
+private:
+ /**
+ * The OSD's contents.
+ */
+ Texture *_osd;
+
+ /**
+ * Current opacity level of the OSD.
+ */
+ uint8 _osdAlpha;
+
+ /**
+ * When fading the OSD has started.
+ */
+ uint32 _osdFadeStartTime;
+
+ /**
+ * Mutex to allow displayMessageOnOSD to be used from the audio thread.
+ */
+ Common::Mutex _osdMutex;
+
+ enum {
+ kOSDFadeOutDelay = 2 * 1000,
+ kOSDFadeOutDuration = 500,
+ kOSDInitialAlpha = 80
+ };
+#endif
};
} // End of namespace OpenGL