aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2017-07-02 22:37:41 -0500
committerColin Snover2017-07-06 19:12:36 -0500
commit7ce2e4cf080d9a328be6d1b2f8594cbb52159c28 (patch)
tree5859026c71918e8096645c3f22856bc212121da2
parent1fbee2f51ef8f1027a638d1a9895fc859568fa4a (diff)
downloadscummvm-rg350-7ce2e4cf080d9a328be6d1b2f8594cbb52159c28.tar.gz
scummvm-rg350-7ce2e4cf080d9a328be6d1b2f8594cbb52159c28.tar.bz2
scummvm-rg350-7ce2e4cf080d9a328be6d1b2f8594cbb52159c28.zip
GRAPHICS: Allow nearest neighbor scaling of 1Bpp and 2Bpp TransparentSurfaces
This is one small step toward allowing more shared usage of existing scaling code.
-rw-r--r--graphics/transparent_surface.cpp52
-rw-r--r--graphics/transparent_surface.h3
2 files changed, 36 insertions, 19 deletions
diff --git a/graphics/transparent_surface.cpp b/graphics/transparent_surface.cpp
index 48e6da6c79..83869cef30 100644
--- a/graphics/transparent_surface.cpp
+++ b/graphics/transparent_surface.cpp
@@ -793,21 +793,17 @@ TransparentSurface *TransparentSurface::rotoscaleT(const TransformStruct &transf
template <TFilteringMode filteringMode>
TransparentSurface *TransparentSurface::scaleT(uint16 newWidth, uint16 newHeight) const {
- Common::Rect srcRect(0, 0, (int16)w, (int16)h);
- Common::Rect dstRect(0, 0, (int16)newWidth, (int16)newHeight);
-
TransparentSurface *target = new TransparentSurface();
- assert(format.bytesPerPixel == 4);
-
- int srcW = srcRect.width();
- int srcH = srcRect.height();
- int dstW = dstRect.width();
- int dstH = dstRect.height();
+ int srcW = w;
+ int srcH = h;
+ int dstW = newWidth;
+ int dstH = newHeight;
- target->create((uint16)dstW, (uint16)dstH, this->format);
+ target->create((uint16)dstW, (uint16)dstH, format);
if (filteringMode == FILTER_BILINEAR) {
+ assert(format.bytesPerPixel == 4);
bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor
@@ -954,25 +950,29 @@ TransparentSurface *TransparentSurface::scaleT(uint16 newWidth, uint16 newHeight
delete[] say;
} else {
-
int *scaleCacheX = new int[dstW];
for (int x = 0; x < dstW; x++) {
scaleCacheX[x] = (x * srcW) / dstW;
}
- for (int y = 0; y < dstH; y++) {
- uint32 *destP = (uint32 *)target->getBasePtr(0, y);
- const uint32 *srcP = (const uint32 *)getBasePtr(0, (y * srcH) / dstH);
- for (int x = 0; x < dstW; x++) {
- *destP++ = srcP[scaleCacheX[x]];
- }
+ switch (format.bytesPerPixel) {
+ case 1:
+ scaleNN<uint8>(scaleCacheX, target);
+ break;
+ case 2:
+ scaleNN<uint16>(scaleCacheX, target);
+ break;
+ case 4:
+ scaleNN<uint32>(scaleCacheX, target);
+ break;
+ default:
+ error("Can only scale 8bpp, 16bpp, and 32bpp");
}
- delete[] scaleCacheX;
+ delete[] scaleCacheX;
}
return target;
-
}
TransparentSurface *TransparentSurface::convertTo(const PixelFormat &dstFormat, const byte *palette) const {
@@ -1053,12 +1053,26 @@ TransparentSurface *TransparentSurface::convertTo(const PixelFormat &dstFormat,
return surface;
}
+template <typename Size>
+void TransparentSurface::scaleNN(int *scaleCacheX, TransparentSurface *target) const {
+ for (int y = 0; y < target->h; y++) {
+ Size *destP = (Size *)target->getBasePtr(0, y);
+ const Size *srcP = (const Size *)getBasePtr(0, (y * h) / target->h);
+ for (int x = 0; x < target->w; x++) {
+ *destP++ = srcP[scaleCacheX[x]];
+ }
+ }
+}
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;
+template void TransparentSurface::scaleNN<uint8>(int *scaleCacheX, TransparentSurface *target) const;
+template void TransparentSurface::scaleNN<uint16>(int *scaleCacheX, TransparentSurface *target) const;
+template void TransparentSurface::scaleNN<uint32>(int *scaleCacheX, TransparentSurface *target) const;
+
TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const {
return rotoscaleT<FILTER_BILINEAR>(transform);
}
diff --git a/graphics/transparent_surface.h b/graphics/transparent_surface.h
index 6fcdac1735..22fe04551e 100644
--- a/graphics/transparent_surface.h
+++ b/graphics/transparent_surface.h
@@ -150,6 +150,7 @@ struct TransparentSurface : public Graphics::Surface {
TransparentSurface *scaleT(uint16 newWidth, uint16 newHeight) const;
TransparentSurface *scale(uint16 newWidth, uint16 newHeight) const;
+
/**
* @brief Rotoscale function; this returns a transformed version of this surface after rotation and
* scaling. Please do not use this if angle == 0, use plain old scaling function.
@@ -176,6 +177,8 @@ struct TransparentSurface : public Graphics::Surface {
private:
AlphaType _alphaMode;
+ template <typename Size>
+ void scaleNN(int *scaleCacheX, TransparentSurface *target) const;
};
/**