OPENGL: Add OSD support.
This commit is contained in:
parent
5ce830b976
commit
cc9c991d77
2 changed files with 178 additions and 1 deletions
|
@ -29,8 +29,16 @@
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
#include "common/translation.h"
|
#include "common/translation.h"
|
||||||
#include "common/algorithm.h"
|
#include "common/algorithm.h"
|
||||||
|
#ifdef USE_OSD
|
||||||
|
#include "common/tokenizer.h"
|
||||||
|
#include "common/rect.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "graphics/conversion.h"
|
#include "graphics/conversion.h"
|
||||||
|
#ifdef USE_OSD
|
||||||
|
#include "graphics/fontman.h"
|
||||||
|
#include "graphics/font.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
|
@ -42,7 +50,11 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
|
||||||
_overlayVisible(false), _cursor(nullptr),
|
_overlayVisible(false), _cursor(nullptr),
|
||||||
_cursorX(0), _cursorY(0), _cursorHotspotX(0), _cursorHotspotY(0), _cursorHotspotXScaled(0),
|
_cursorX(0), _cursorY(0), _cursorHotspotX(0), _cursorHotspotY(0), _cursorHotspotXScaled(0),
|
||||||
_cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0), _cursorKeyColor(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));
|
memset(_gamePalette, 0, sizeof(_gamePalette));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +62,9 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
|
||||||
delete _gameScreen;
|
delete _gameScreen;
|
||||||
delete _overlay;
|
delete _overlay;
|
||||||
delete _cursor;
|
delete _cursor;
|
||||||
|
#ifdef USE_OSD
|
||||||
|
delete _osd;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) {
|
bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) {
|
||||||
|
@ -137,6 +152,12 @@ bool OpenGLGraphicsManager::setGraphicsMode(int mode) {
|
||||||
if (_cursor) {
|
if (_cursor) {
|
||||||
_cursor->enableLinearFiltering(mode == GFX_LINEAR);
|
_cursor->enableLinearFiltering(mode == GFX_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_OSD
|
||||||
|
if (_osd) {
|
||||||
|
_osd->enableLinearFiltering(mode == GFX_LINEAR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -374,6 +395,34 @@ void OpenGLGraphicsManager::updateScreen() {
|
||||||
|
|
||||||
glPopMatrix();
|
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() {
|
Graphics::Surface *OpenGLGraphicsManager::lockScreen() {
|
||||||
|
@ -617,6 +666,59 @@ void OpenGLGraphicsManager::setCursorPalette(const byte *colors, uint start, uin
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLGraphicsManager::displayMessageOnOSD(const char *msg) {
|
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) {
|
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->allocate(overlayWidth, overlayHeight);
|
||||||
_overlay->fill(0);
|
_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
|
// Re-setup the scaling for the screen and cursor
|
||||||
recalculateDisplayArea();
|
recalculateDisplayArea();
|
||||||
recalculateCursorScaling();
|
recalculateCursorScaling();
|
||||||
|
@ -729,6 +846,12 @@ void OpenGLGraphicsManager::notifyContextChange(const Graphics::PixelFormat &def
|
||||||
if (_cursor) {
|
if (_cursor) {
|
||||||
_cursor->recreateInternalTexture();
|
_cursor->recreateInternalTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_OSD
|
||||||
|
if (_osd) {
|
||||||
|
_osd->recreateInternalTexture();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
|
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
|
} // End of namespace OpenGL
|
||||||
|
|
|
@ -27,9 +27,19 @@
|
||||||
#include "backends/graphics/graphics.h"
|
#include "backends/graphics/graphics.h"
|
||||||
|
|
||||||
#include "common/frac.h"
|
#include "common/frac.h"
|
||||||
|
#include "common/mutex.h"
|
||||||
|
|
||||||
|
namespace Graphics {
|
||||||
|
class Font;
|
||||||
|
} // End of namespace Graphics
|
||||||
|
|
||||||
namespace OpenGL {
|
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;
|
class Texture;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -415,6 +425,44 @@ private:
|
||||||
* The special cursor palette in case enabled.
|
* The special cursor palette in case enabled.
|
||||||
*/
|
*/
|
||||||
byte _cursorPalette[3 * 256];
|
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
|
} // End of namespace OpenGL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue