mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-12 03:36:42 +00:00
OPENGL: Add OSD support.
This commit is contained in:
parent
5ce830b976
commit
cc9c991d77
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user