STARK: Draw text at the native resolution

This commit is contained in:
Bastien Bouclet 2015-11-29 20:43:43 +01:00
parent 2e83312de7
commit 9ed9efb443
10 changed files with 86 additions and 41 deletions

View File

@ -90,7 +90,7 @@ Common::Point Cursor::getMousePosition(bool unscaled) const {
return _mousePos;
} else {
// Most of the engine expects 640x480 coordinates
return _gfx->scalePoint(_mousePos);
return _gfx->convertCoordinateCurrentToOriginal(_mousePos);
}
}

View File

@ -69,24 +69,32 @@ Common::Rect Driver::gameViewport() const {
return game;
}
Common::Point Driver::getScreenPosBounded(Common::Point point) {
Common::Point Driver::getScreenPosBounded(const Common::Point &point) const {
Common::Point boundedPos = point;
boundedPos.x = CLIP<int16>(boundedPos.x, _screenViewport.left, _screenViewport.right);
return boundedPos;
}
Common::Point Driver::scalePoint(Common::Point point) {
Common::Point Driver::convertCoordinateCurrentToOriginal(const Common::Point &point) const {
// Most of the engine expects 640x480 coordinates
Common::Point scaledPosition = point;
scaledPosition.x -= _screenViewport.left;
scaledPosition.y -= _screenViewport.top;
scaledPosition.x = CLIP<int16>(scaledPosition.x, 0, _screenViewport.width());
scaledPosition.y = CLIP<int16>(scaledPosition.y, 0, _screenViewport.height());
scaledPosition.x *= Gfx::Driver::kOriginalWidth / (float)_screenViewport.width();
scaledPosition.y *= Gfx::Driver::kOriginalHeight / (float)_screenViewport.height();
scaledPosition.x *= kOriginalWidth / (float)_screenViewport.width();
scaledPosition.y *= kOriginalHeight / (float)_screenViewport.height();
return scaledPosition;
}
uint Driver::scaleWidthOriginalToCurrent(uint width) const {
return _screenViewport.width() * width / kOriginalWidth;
}
uint Driver::scaleHeightOriginalToCurrent(uint height) const {
return _screenViewport.height() * height / kOriginalHeight;
}
} // End of namespace Gfx
} // End of namespace Stark

View File

@ -80,14 +80,21 @@ public:
virtual VisualProp *createPropRenderer() = 0;
/** Bound a screen coordinate coord within the actual game area */
Common::Point getScreenPosBounded(Common::Point point);
Common::Point getScreenPosBounded(const Common::Point &point) const;
/** Convert a coordinate from current to original resolution */
Common::Point convertCoordinateCurrentToOriginal(const Common::Point &point) const;
/** Scale a width value from original resolution to current resolution */
uint scaleWidthOriginalToCurrent(uint width) const;
/** Scale a height value from original resolution to current resolution */
uint scaleHeightOriginalToCurrent(uint height) const;
/** Scale a coordinate from original to current coordinates */
Common::Point scalePoint(Common::Point point);
/**
* Draw a 2D surface from the specified texture
*/
virtual void drawSurface(const Texture *texture, const Common::Point &dest) = 0;
virtual void drawSurface(const Texture *texture, const Common::Point &dest, bool noScalingOverride = false) = 0;
virtual Graphics::PixelFormat getScreenFormat();

View File

@ -137,7 +137,7 @@ VisualProp *OpenGLSDriver::createPropRenderer() {
return new OpenGLSPropRenderer(this);
}
void OpenGLSDriver::drawSurface(const Texture *texture, const Common::Point &dest) {
void OpenGLSDriver::drawSurface(const Texture *texture, const Common::Point &dest, bool noScalingOverride) {
// Source texture rectangle
const float tLeft = 0.0;
const float tWidth = 1.0;
@ -156,7 +156,11 @@ void OpenGLSDriver::drawSurface(const Texture *texture, const Common::Point &des
_boxShader->setUniform("textured", true);
_boxShader->setUniform("color", Math::Vector4d(1.0f, 1.0f, 1.0f, 1.0f));
_boxShader->setUniform("verOffsetXY", scaled(sLeft, sTop));
_boxShader->setUniform("verSizeWH", scaled(sWidth, sHeight));
if (noScalingOverride) {
_boxShader->setUniform("verSizeWH", Math::Vector2d(sWidth / (float) _viewport.width(), sHeight / (float) _viewport.height()));
} else {
_boxShader->setUniform("verSizeWH", scaled(sWidth, sHeight));
}
_boxShader->setUniform("texOffsetXY", Math::Vector2d(tLeft, tTop));
_boxShader->setUniform("texSizeWH", Math::Vector2d(tWidth, tHeight));

View File

@ -58,7 +58,7 @@ public:
VisualProp *createPropRenderer() override;
Graphics::Shader *createActorShaderInstance();
void drawSurface(const Texture *texture, const Common::Point &dest) override;
void drawSurface(const Texture *texture, const Common::Point &dest, bool noScalingOverride = false) override;
void set3DMode();

View File

@ -22,6 +22,9 @@
#include "engines/stark/services/fontprovider.h"
#include "engines/stark/services/services.h"
#include "engines/stark/gfx/driver.h"
#include "common/archive.h"
#include "graphics/font.h"
@ -31,7 +34,6 @@
namespace Stark {
FontProvider::FontProvider() {
initFonts();
}
FontProvider::~FontProvider() {
@ -62,7 +64,8 @@ void FontProvider::initFonts() {
FontProvider::FontHolder::FontHolder(FontProvider *fontProvider, Common::String name, uint32 height, uint32 charset) {
_name = name;
_height = height;
_originalHeight = height;
_scaledHeight = StarkGfx->scaleHeightOriginalToCurrent(_originalHeight);
_charset = charset;
// Fetch the font file name
@ -72,7 +75,7 @@ FontProvider::FontHolder::FontHolder(FontProvider *fontProvider, Common::String
Common::SeekableReadStream *s = SearchMan.createReadStreamForMember(ttfFileName);
if (s) {
_font = Common::SharedPtr<Graphics::Font>(
Graphics::loadTTFFont(*s, _height, Graphics::kTTFSizeModeCell, 0, Graphics::kTTFRenderModeMonochrome)
Graphics::loadTTFFont(*s, _scaledHeight, Graphics::kTTFSizeModeCell, 0, Graphics::kTTFRenderModeMonochrome)
);
delete s;
} else {
@ -91,7 +94,7 @@ FontProvider::FontHolder *FontProvider::getFontHolder(FontProvider::FontType typ
}
}
const Graphics::Font *FontProvider::getFont(FontProvider::FontType type, int32 customFontIndex) {
const Graphics::Font *FontProvider::getScaledFont(FontProvider::FontType type, int32 customFontIndex) {
FontHolder *holder = getFontHolder(type, customFontIndex);
if (holder->_font) {
return holder->_font.get();
@ -101,9 +104,17 @@ const Graphics::Font *FontProvider::getFont(FontProvider::FontType type, int32 c
}
}
int FontProvider::getFontHeight(FontProvider::FontType type, int32 customFontIndex) {
uint FontProvider::getScaledFontHeight(FontProvider::FontType type, int32 customFontIndex) {
FontHolder *holder = getFontHolder(type, customFontIndex);
return holder->_height;
return holder->_scaledHeight;
}
uint FontProvider::getOriginalFontHeight(FontProvider::FontType type, int32 customFontIndex) {
FontHolder *holder = getFontHolder(type, customFontIndex);
return holder->_originalHeight;
}
uint FontProvider::scaleWidthOriginalToCurrent(uint width) {
return StarkGfx->scaleWidthOriginalToCurrent(width);
}
} // End of namespace Stark

View File

@ -49,25 +49,35 @@ public:
/**
* Request a font matching the specified parameters
*/
const Graphics::Font *getFont(FontType type, int32 customFontIndex);
const Graphics::Font *getScaledFont(FontType type, int32 customFontIndex);
/**
* Get the height of the font matching the specified parameters
*/
int getFontHeight(FontType type, int32 customFontIndex);
uint getScaledFontHeight(FontType type, int32 customFontIndex);
uint getOriginalFontHeight(FontType type, int32 customFontIndex);
/** Load all the fonts to memory */
void initFonts();
/** Scale a width value from original resolution to current resolution */
uint scaleWidthOriginalToCurrent(uint width);
private:
struct FontHolder {
Common::String _name;
uint32 _height;
uint32 _originalHeight;
uint32 _scaledHeight;
uint32 _charset;
Common::SharedPtr<Graphics::Font> _font;
FontHolder() : _height(0), _charset(0) {}
FontHolder() : _originalHeight(0), _scaledHeight(0), _charset(0) {}
FontHolder(FontProvider *fontProvider, Common::String name, uint32 height, uint32 charset = 0);
};
void initFonts();
FontHolder *getFontHolder(FontType type, int32 customFontIndex);
FontHolder _smallFont;

View File

@ -136,6 +136,7 @@ Common::Error StarkEngine::run() {
// Load global resources
_resourceProvider->initGlobal();
_staticProvider->init();
_fontProvider->initFonts();
_cursor->init();
// Initialize the UI
_userInterface->init();

View File

@ -40,7 +40,7 @@ VisualText::VisualText(Gfx::Driver *gfx) :
_texture(nullptr),
_color(0),
_backgroundColor(0),
_targetWidth(600),
_originalRect(600, 0),
_fontCustomIndex(-1),
_fontType(FontProvider::kBigFont) {
}
@ -54,7 +54,7 @@ Common::Rect VisualText::getRect() {
createTexture();
}
return Common::Rect(_texture->width(), _texture->height());
return _originalRect;
}
void VisualText::setText(const Common::String &text) {
@ -74,7 +74,7 @@ void VisualText::setBackgroundColor(uint32 color) {
void VisualText::setTargetWidth(uint32 width) {
freeTexture();
_targetWidth = width;
_originalRect.right = width;
}
void VisualText::setFont(FontProvider::FontType type, int32 customFontIndex) {
@ -85,26 +85,30 @@ void VisualText::setFont(FontProvider::FontType type, int32 customFontIndex) {
}
void VisualText::createTexture() {
const Graphics::Font *font = StarkFontProvider->getFont(_fontType, _fontCustomIndex);
int height = StarkFontProvider->getFontHeight(_fontType, _fontCustomIndex);
// Get the font and required metrics
const Graphics::Font *font = StarkFontProvider->getScaledFont(_fontType, _fontCustomIndex);
uint scaledLineHeight = StarkFontProvider->getScaledFontHeight(_fontType, _fontCustomIndex);
uint originalLineHeight = StarkFontProvider->getOriginalFontHeight(_fontType, _fontCustomIndex);
uint maxScaledLineWidth = StarkFontProvider->scaleWidthOriginalToCurrent(_originalRect.width());
// Word wrap the text and compute the scaled and original resolution bounding boxes
Common::Rect scaledRect;
Common::Array<Common::String> lines;
font->wordWrapText(_text, _targetWidth, lines);
int width = 0;
for (uint i = 0; i < lines.size(); i++) {
width = MAX(width, font->getStringWidth(lines[i]));
}
Common::Rect boundingRect = Common::Rect(width, height * lines.size());
scaledRect.right = scaledRect.left + font->wordWrapText(_text, maxScaledLineWidth, lines);
scaledRect.bottom = scaledRect.top + scaledLineHeight * lines.size();
_originalRect.bottom = _originalRect.top + originalLineHeight * lines.size();
// Create a surface to render to
Graphics::Surface surface;
surface.create(boundingRect.width(), boundingRect.height(), _gfx->getScreenFormat());
surface.fillRect(boundingRect, _backgroundColor);
surface.create(scaledRect.width(), scaledRect.height(), _gfx->getScreenFormat());
surface.fillRect(scaledRect, _backgroundColor);
// Render the lines to the surface
for (uint i = 0; i < lines.size(); i++) {
font->drawString(&surface, lines[i], 0, height * i, _targetWidth, _color);
font->drawString(&surface, lines[i], 0, scaledLineHeight * i, scaledRect.width(), _color);
}
// Create a texture from the surface
_texture = _gfx->createTexture(&surface);
surface.free();
}
@ -119,7 +123,7 @@ void VisualText::render(const Common::Point &position) {
createTexture();
}
_gfx->drawSurface(_texture, position);
_gfx->drawSurface(_texture, position, true);
}
} // End of namespace Stark

View File

@ -65,8 +65,8 @@ private:
Common::String _text;
uint32 _color;
uint32 _backgroundColor;
uint32 _targetWidth;
Gfx::Texture *_texture;
Common::Rect _originalRect;
FontProvider::FontType _fontType;
int32 _fontCustomIndex;