GRAPHICS: Add a function for scaling a standard Graphics::Surface
This also makes use of it in the SCI and Wintermute engines
This commit is contained in:
parent
ff1474591f
commit
352653b8a2
8 changed files with 40 additions and 37 deletions
|
@ -30,7 +30,6 @@
|
|||
#include "common/system.h" // for g_system
|
||||
#include "engines/engine.h" // for Engine, g_engine
|
||||
#include "graphics/palette.h" // for PaletteManager
|
||||
#include "graphics/transparent_surface.h" // for TransparentSurface
|
||||
#include "sci/console.h" // for Console
|
||||
#include "sci/engine/features.h" // for GameFeatures
|
||||
#include "sci/engine/state.h" // for EngineState
|
||||
|
@ -242,20 +241,16 @@ void VideoPlayer::renderFrame(const Graphics::Surface &nextFrame) const {
|
|||
|
||||
if (_decoder->getWidth() != _drawRect.width() || _decoder->getHeight() != _drawRect.height()) {
|
||||
Graphics::Surface *const unscaledFrame(convertedFrame);
|
||||
// TODO: The only reason TransparentSurface is used here because it is
|
||||
// where common scaler code is right now, which should just be part of
|
||||
// Graphics::Surface (or some free functions).
|
||||
const Graphics::TransparentSurface tsUnscaledFrame(*unscaledFrame);
|
||||
#ifdef USE_RGB_COLOR
|
||||
if (_hqVideoMode) {
|
||||
convertedFrame = tsUnscaledFrame.scaleT<Graphics::FILTER_BILINEAR>(_drawRect.width(), _drawRect.height());
|
||||
convertedFrame = unscaledFrame->scale(_drawRect.width(), _drawRect.height(), true);
|
||||
} else {
|
||||
#elif 1
|
||||
{
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
convertedFrame = tsUnscaledFrame.scaleT<Graphics::FILTER_NEAREST>(_drawRect.width(), _drawRect.height());
|
||||
convertedFrame = unscaledFrame->scale(_drawRect.width(), _drawRect.height(), false);
|
||||
}
|
||||
assert(convertedFrame);
|
||||
if (freeConvertedFrame) {
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "engines/wintermute/base/gfx/base_image.h"
|
||||
#include "engines/wintermute/base/save_thumb_helper.h"
|
||||
#include "engines/wintermute/base/sound/base_sound.h"
|
||||
#include "graphics/transparent_surface.h"
|
||||
#include "engines/wintermute/wintermute.h"
|
||||
#include "graphics/scaler.h"
|
||||
#include "image/bmp.h"
|
||||
|
@ -173,11 +172,9 @@ void BasePersistenceManager::getSaveStateDesc(int slot, SaveStateDescriptor &des
|
|||
Image::BitmapDecoder bmpDecoder;
|
||||
if (bmpDecoder.loadStream(thumbStream)) {
|
||||
const Graphics::Surface *bmpSurface = bmpDecoder.getSurface();
|
||||
Graphics::TransparentSurface *scaleableSurface = new Graphics::TransparentSurface(*bmpSurface, false);
|
||||
Graphics::Surface *scaled = scaleableSurface->scale(kThumbnailWidth, kThumbnailHeight2);
|
||||
Graphics::Surface *scaled = bmpSurface->scale(kThumbnailWidth, kThumbnailHeight2);
|
||||
Graphics::Surface *thumb = scaled->convertTo(g_system->getOverlayFormat());
|
||||
desc.setThumbnail(thumb);
|
||||
delete scaleableSurface;
|
||||
scaled->free();
|
||||
delete scaled;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "engines/wintermute/base/gfx/base_image.h"
|
||||
#include "engines/wintermute/base/base_file_manager.h"
|
||||
#include "graphics/transparent_surface.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "image/png.h"
|
||||
#include "image/jpeg.h"
|
||||
|
@ -112,14 +111,13 @@ bool BaseImage::saveBMPFile(const Common::String &filename) const {
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
bool BaseImage::resize(int newWidth, int newHeight) {
|
||||
// WME Lite used FILTER_BILINEAR with FreeImage_Rescale here.
|
||||
Graphics::TransparentSurface temp(*_surface, true);
|
||||
Graphics::Surface *temp = _surface->scale((uint16)newWidth, (uint16)newHeight);
|
||||
if (_deletableSurface) {
|
||||
_deletableSurface->free();
|
||||
delete _deletableSurface;
|
||||
_deletableSurface = nullptr;
|
||||
}
|
||||
_surface = _deletableSurface = temp.scale((uint16)newWidth, (uint16)newHeight);
|
||||
temp.free();
|
||||
_surface = _deletableSurface = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -216,13 +214,13 @@ bool BaseImage::writeBMPToStream(Common::WriteStream *stream) const {
|
|||
bool BaseImage::copyFrom(BaseImage *origImage, int newWidth, int newHeight) {
|
||||
// WME Lite used FILTER_BILINEAR with FreeImage_Rescale here.
|
||||
|
||||
Graphics::TransparentSurface temp(*origImage->_surface, false);
|
||||
Graphics::Surface *temp = origImage->_surface->scale((uint16)newWidth, (uint16)newHeight);
|
||||
if (_deletableSurface) {
|
||||
_deletableSurface->free();
|
||||
delete _deletableSurface;
|
||||
_deletableSurface = nullptr;
|
||||
}
|
||||
_surface = _deletableSurface = temp.scale((uint16)newWidth, (uint16)newHeight);
|
||||
_surface = _deletableSurface = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,13 +72,7 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s
|
|||
} else if ((dstRect->width() != srcRect->width() ||
|
||||
dstRect->height() != srcRect->height()) &&
|
||||
_transform._numTimesX * _transform._numTimesY == 1) {
|
||||
Graphics::TransparentSurface src(*_surface, false);
|
||||
Graphics::Surface *temp;
|
||||
if (owner->_gameRef->getBilinearFiltering()) {
|
||||
temp = src.scaleT<Graphics::FILTER_BILINEAR>(dstRect->width(), dstRect->height());
|
||||
} else {
|
||||
temp = src.scaleT<Graphics::FILTER_NEAREST>(dstRect->width(), dstRect->height());
|
||||
}
|
||||
Graphics::Surface *temp = _surface->scale(dstRect->width(), dstRect->height(), owner->_gameRef->getBilinearFiltering());
|
||||
_surface->free();
|
||||
delete _surface;
|
||||
_surface = temp;
|
||||
|
|
|
@ -368,6 +368,21 @@ void Surface::flipVertical(const Common::Rect &r) {
|
|||
delete[] temp;
|
||||
}
|
||||
|
||||
Graphics::Surface *Surface::scale(uint16 newWidth, uint16 newHeight, bool filtering) const {
|
||||
|
||||
Graphics::Surface *target = new Graphics::Surface();
|
||||
|
||||
target->create(newWidth, newHeight, format);
|
||||
|
||||
if (filtering) {
|
||||
scaleBlitBilinear((byte *)target->getPixels(), (const byte *)getPixels(), target->pitch, pitch, target->w, target->h, w, h, format);
|
||||
} else {
|
||||
scaleBlit((byte *)target->getPixels(), (const byte *)getPixels(), target->pitch, pitch, target->w, target->h, w, h, format);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void Surface::convertToInPlace(const PixelFormat &dstFormat, const byte *palette) {
|
||||
// Do not convert to the same format and ignore empty surfaces.
|
||||
if (format == dstFormat || pixels == 0) {
|
||||
|
|
|
@ -334,6 +334,19 @@ public:
|
|||
* @param r Rect to flip
|
||||
*/
|
||||
void flipVertical(const Common::Rect &r);
|
||||
|
||||
/**
|
||||
* Scale the data to the given size.
|
||||
*
|
||||
* The calling code must call free on the returned surface and then delete
|
||||
* it.
|
||||
*
|
||||
* @param newWidth the resulting width.
|
||||
* @param newHeight the resulting height.
|
||||
* @param filtering Whether or not to use bilinear filtering.
|
||||
*/
|
||||
Graphics::Surface *scale(uint16 newWidth, uint16 newHeight, bool filtering = false) const;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -909,14 +909,13 @@ TransparentSurface *TransparentSurface::rotoscaleT(const TransformStruct &transf
|
|||
return target;
|
||||
}
|
||||
|
||||
template <TFilteringMode filteringMode>
|
||||
TransparentSurface *TransparentSurface::scaleT(uint16 newWidth, uint16 newHeight) const {
|
||||
TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight, bool filtering) const {
|
||||
|
||||
TransparentSurface *target = new TransparentSurface();
|
||||
|
||||
target->create(newWidth, newHeight, format);
|
||||
|
||||
if (filteringMode == FILTER_BILINEAR) {
|
||||
if (filtering) {
|
||||
scaleBlitBilinear((byte *)target->getPixels(), (const byte *)getPixels(), target->pitch, pitch, target->w, target->h, w, h, format);
|
||||
} else {
|
||||
scaleBlit((byte *)target->getPixels(), (const byte *)getPixels(), target->pitch, pitch, target->w, target->h, w, h, format);
|
||||
|
@ -1005,15 +1004,9 @@ TransparentSurface *TransparentSurface::convertTo(const PixelFormat &dstFormat,
|
|||
|
||||
template TransparentSurface *TransparentSurface::rotoscaleT<FILTER_NEAREST>(const TransformStruct &transform) const;
|
||||
template TransparentSurface *TransparentSurface::rotoscaleT<FILTER_BILINEAR>(const TransformStruct &transform) const;
|
||||
template TransparentSurface *TransparentSurface::scaleT<FILTER_NEAREST>(uint16 newWidth, uint16 newHeight) const;
|
||||
template TransparentSurface *TransparentSurface::scaleT<FILTER_BILINEAR>(uint16 newWidth, uint16 newHeight) const;
|
||||
|
||||
TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const {
|
||||
return rotoscaleT<FILTER_BILINEAR>(transform);
|
||||
}
|
||||
|
||||
TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight) const {
|
||||
return scaleT<FILTER_NEAREST>(newWidth, newHeight);
|
||||
}
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
|
|
@ -145,12 +145,10 @@ struct TransparentSurface : public Graphics::Surface {
|
|||
*
|
||||
* @param newWidth the resulting width.
|
||||
* @param newHeight the resulting height.
|
||||
* @param filtering Whether or not to use bilinear filtering.
|
||||
* @see TransformStruct
|
||||
*/
|
||||
template <TFilteringMode filteringMode>
|
||||
TransparentSurface *scaleT(uint16 newWidth, uint16 newHeight) const;
|
||||
|
||||
TransparentSurface *scale(uint16 newWidth, uint16 newHeight) const;
|
||||
TransparentSurface *scale(uint16 newWidth, uint16 newHeight, bool filtering = false) const;
|
||||
|
||||
/**
|
||||
* @brief Rotoscale function; this returns a transformed version of this surface after rotation and
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue