From: Wouter V. <m97...@us...> - 2005-07-21 10:27:23
|
Update of /cvsroot/openmsx/openMSX/src/video In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11196/src/video Modified Files: Deinterlacer.cc Deinterlacer.hh HQ2xLiteScaler.cc HQ2xLiteScaler.hh HQ2xScaler.cc HQ2xScaler.hh LowScaler.cc LowScaler.hh PostProcessor.cc SaI2xScaler.cc SaI2xScaler.hh Scale2xScaler.cc Scale2xScaler.hh Scaler.cc Scaler.hh SimpleScaler.cc SimpleScaler.hh Log Message: made Scaler interface independent from scale factor Index: Deinterlacer.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/Deinterlacer.cc,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- Deinterlacer.cc 9 May 2005 17:38:33 -0000 1.4 +++ Deinterlacer.cc 21 Jul 2005 10:27:06 -0000 1.5 @@ -1,26 +1,35 @@ // $Id$ #include "Deinterlacer.hh" +#include "RawFrame.hh" #include "Scaler.hh" namespace openmsx { template <class Pixel> void Deinterlacer<Pixel>::deinterlaceLine256( - SDL_Surface* src0, SDL_Surface* src1, int srcY, - SDL_Surface* dst, int dstY ) + RawFrame& src0, RawFrame& src1, SDL_Surface* dst, unsigned y) { - Scaler<Pixel>::scaleLine(src0, srcY, dst, dstY); - Scaler<Pixel>::scaleLine(src1, srcY, dst, dstY + 1); + Pixel* srcLine0 = src0.getPixelPtr(0, y, (Pixel*)0); + Pixel* dstLine0 = Scaler<Pixel>::linePtr(dst, 2 * y + 0); + Scaler<Pixel>::scaleLine(srcLine0, dstLine0, 320); + + Pixel* srcLine1 = src1.getPixelPtr(0, y, (Pixel*)0); + Pixel* dstLine1 = Scaler<Pixel>::linePtr(dst, 2 * y + 1); + Scaler<Pixel>::scaleLine(srcLine1, dstLine1, 320); } template <class Pixel> void Deinterlacer<Pixel>::deinterlaceLine512( - SDL_Surface* src0, SDL_Surface* src1, int srcY, - SDL_Surface* dst, int dstY ) + RawFrame& src0, RawFrame& src1, SDL_Surface* dst, unsigned y) { - Scaler<Pixel>::copyLine(src0, srcY, dst, dstY); - Scaler<Pixel>::copyLine(src1, srcY, dst, dstY + 1); + Pixel* srcLine0 = src0.getPixelPtr(0, y, (Pixel*)0); + Pixel* dstLine0 = Scaler<Pixel>::linePtr(dst, 2 * y + 0); + Scaler<Pixel>::copyLine(srcLine0, dstLine0, 640); + + Pixel* srcLine1 = src1.getPixelPtr(0, y, (Pixel*)0); + Pixel* dstLine1 = Scaler<Pixel>::linePtr(dst, 2 * y + 1); + Scaler<Pixel>::copyLine(srcLine1, dstLine1, 640); } Index: Deinterlacer.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/Deinterlacer.hh,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- Deinterlacer.hh 10 Mar 2005 20:15:48 -0000 1.5 +++ Deinterlacer.hh 21 Jul 2005 10:27:06 -0000 1.6 @@ -7,6 +7,8 @@ namespace openmsx { +class RawFrame; + /** Deinterlace image filter: takes lines from the even and odd page to * produce a single deinterlaced output frame. * Its interface is similar to a scaler, however there are two input @@ -21,28 +23,24 @@ * It should be 320 pixels wide. * @param src1 Source 1: odd page of the image to be scaled. * It should be 320 pixels wide. - * @param srcY Y-coordinate of the source line. * @param dst Destination: image to store the scaled output in. * It should be 640 pixels wide and twice as high as the source image. - * @param dstY Y-coordinate of the destination line. + * @param y Y-coordinate */ void deinterlaceLine256( - SDL_Surface* src0, SDL_Surface* src1, int srcY, - SDL_Surface* dst, int dstY); + RawFrame& src0, RawFrame& src1, SDL_Surface* dst, unsigned y); /** Deinterlaces the given line. * @param src0 Source 0: even page of the image to be deinterlaced. - * It should be 320 pixels wide. + * It should be 640 pixels wide. * @param src1 Source 1: odd page of the image to be deinterlaced. - * It should be 320 pixels wide. - * @param srcY Y-coordinate of the source line. + * It should be 640 pixels wide. * @param dst Destination: image to store the scaled output in. * It should be 640 pixels wide and twice as high as the source image. - * @param dstY Y-coordinate of the destination line. + * @param y Y-coordinate */ void deinterlaceLine512( - SDL_Surface* src0, SDL_Surface* src1, int srcY, - SDL_Surface* dst, int dstY); + RawFrame& src0, RawFrame& src1, SDL_Surface* dst, unsigned y); }; } // namespace openmsx Index: HQ2xLiteScaler.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/HQ2xLiteScaler.cc,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- HQ2xLiteScaler.cc 29 Jun 2005 21:06:46 -0000 1.5 +++ HQ2xLiteScaler.cc 21 Jul 2005 10:27:06 -0000 1.6 @@ -13,8 +13,12 @@ */ #include "HQ2xLiteScaler.hh" +#include "RawFrame.hh" +#include <algorithm> #include <cassert> +using std::min; + namespace openmsx { template <class Pixel> @@ -84,30 +88,25 @@ } template <class Pixel> -static void scaleLine256( - SDL_Surface* src, int srcY, SDL_Surface* dst, int dstY, - const int prev, const int next) +static void scaleLine256(const Pixel* in0, const Pixel* in1, const Pixel* in2, + Pixel* out0, Pixel* out1) { const unsigned WIDTH = 320; - const int srcPitch = src->pitch / sizeof(Pixel); - const int dstPitch = dst->pitch / sizeof(Pixel); - - Pixel* in = (Pixel*)src->pixels + srcY * srcPitch; - Pixel* out = (Pixel*)dst->pixels + dstY * dstPitch; - unsigned c1, c2, c3, c4, c5, c6, c7, c8, c9; - c1 = c2 = readPixel(in + prev); - c4 = c5 = readPixel(in); - c7 = c8 = readPixel(in + next); - c3 = c6 = c9 = 0; // avoid warning - in += 1; + c2 = c3 = readPixel(in0); + c5 = c6 = readPixel(in1); + c8 = c9 = readPixel(in2); for (unsigned x = 0; x < WIDTH; ++x) { + c1 = c2; c4 = c5; c7 = c8; + c2 = c3; c5 = c6; c8 = c9; + ++in0; ++in1; ++in2; + if (x != WIDTH - 1) { - c3 = readPixel(in + prev); - c6 = readPixel(in); - c9 = readPixel(in + next); + c3 = readPixel(in0); + c6 = readPixel(in1); + c9 = readPixel(in2); } unsigned pattern = 0; @@ -479,31 +478,21 @@ break; } } - pset(out, pixel1); - pset(out + 1, pixel2); - pset(out + dstPitch, pixel3); - pset(out + dstPitch + 1, pixel4); + pset(out1 + 0, pixel3); + pset(out1 + 1, pixel4); + pset(out0 + 0, pixel1); + pset(out0 + 1, pixel2); c1 = c2; c2 = c3; c4 = c5; c5 = c6; c7 = c8; c8 = c9; - - in += 1; - out += 2; + out0 += 2; out1 += 2; } } template <class Pixel> -static void scaleLine512( - SDL_Surface* src, int srcY, SDL_Surface* dst, int dstY, - const int prevLine, const int nextLine ) +static void scaleLine512(const Pixel* in0, const Pixel* in1, const Pixel* in2, + Pixel* out0, Pixel* out1) { - const int width = 640; // TODO: Specify this in a clean way. - const int srcPitch = src->pitch / sizeof(Pixel); - const int dstPitch = dst->pitch / sizeof(Pixel); - - Pixel* pIn = (Pixel*)src->pixels + srcY * srcPitch; - Pixel* pOut = (Pixel*)dst->pixels + dstY * dstPitch; - - unsigned c1, c2, c3, c4, c5, c6, c7, c8, c9; + const unsigned WIDTH = 640; // TODO: Specify this in a clean way. // +----+----+----+ // | | | | @@ -515,21 +504,20 @@ // | | | | // | c7 | c8 | c9 | // +----+----+----+ + unsigned c1, c2, c3, c4, c5, c6, c7, c8, c9; + c2 = c3 = readPixel(in0); + c5 = c6 = readPixel(in1); + c8 = c9 = readPixel(in2); - c2 = c3 = readPixel(pIn + prevLine); - c5 = c6 = readPixel(pIn); - c8 = c9 = readPixel(pIn + nextLine); - - for (int i = 0; i < width; i++) { + for (unsigned i = 0; i < WIDTH; i++) { c1 = c2; c4 = c5; c7 = c8; c2 = c3; c5 = c6; c8 = c9; + ++in0; ++in1; ++in2; - pIn += 1; - - if (i < width - 1) { - c3 = readPixel(pIn + prevLine); - c6 = readPixel(pIn); - c9 = readPixel(pIn + nextLine); + if (i < WIDTH - 1) { + c3 = readPixel(in0); + c6 = readPixel(in1); + c9 = readPixel(in2); } unsigned pattern = 0; @@ -653,54 +641,53 @@ break; } } - pset(pOut, pixel1); - pset(pOut + dstPitch, pixel3); - - ++pOut; + pset(out1++, pixel3); + pset(out0++, pixel1); } } template <class Pixel> -void HQ2xLiteScaler<Pixel>::scale256( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) +void HQ2xLiteScaler<Pixel>::scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - const int srcPitch = src->pitch / sizeof(Pixel); - assert(srcY < endSrcY); - scaleLine256<Pixel>(src, srcY, dst, dstY, - 0, srcY < endSrcY - 1 ? srcPitch : 0 - ); - srcY += 1; - dstY += 2; - while (srcY < endSrcY - 1) { - scaleLine256<Pixel>(src, srcY, dst, dstY, -srcPitch, srcPitch); - srcY += 1; + unsigned dstY = 2 * startY + (lower ? 1 : 0); + unsigned prevY = startY; + while (startY < endY) { + Pixel* dummy = 0; + const Pixel* srcPrev = src.getPixelPtr(0, prevY, dummy); + const Pixel* srcCurr = src.getPixelPtr(0, startY, dummy); + const Pixel* srcNext = src.getPixelPtr(0, min(startY + 1, endY - 1), dummy); + Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, dstY + 0); + Pixel* dstLower = (dstY != (480 - 1)) + ? Scaler<Pixel>::linePtr(dst, dstY + 1) + : dstUpper; + scaleLine256(srcPrev, srcCurr, srcNext, dstUpper, dstLower); + prevY = startY; + ++startY; dstY += 2; } - if (srcY < endSrcY) { - scaleLine256<Pixel>(src, srcY, dst, dstY, -srcPitch, 0); - } } template <class Pixel> -void HQ2xLiteScaler<Pixel>::scale512( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) +void HQ2xLiteScaler<Pixel>::scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - const int srcPitch = src->pitch / sizeof(Pixel); - assert(srcY < endSrcY); - scaleLine512<Pixel>(src, srcY, dst, dstY, - 0, srcY < endSrcY - 1 ? srcPitch : 0); - srcY += 1; - dstY += 2; - while (srcY < endSrcY - 1) { - scaleLine512<Pixel>(src, srcY, dst, dstY, -srcPitch, srcPitch); - srcY += 1; + unsigned dstY = 2 * startY + (lower ? 1 : 0); + unsigned prevY = startY; + while (startY < endY) { + Pixel* dummy = 0; + const Pixel* srcPrev = src.getPixelPtr(0, prevY, dummy); + const Pixel* srcCurr = src.getPixelPtr(0, startY, dummy); + const Pixel* srcNext = src.getPixelPtr(0, min(startY + 1, endY - 1), dummy); + Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, dstY + 0); + Pixel* dstLower = (dstY != (480 - 1)) + ? Scaler<Pixel>::linePtr(dst, dstY + 1) + : dstUpper; + scaleLine512(srcPrev, srcCurr, srcNext, dstUpper, dstLower); + prevY = startY; + ++startY; dstY += 2; } - if (srcY < endSrcY) { - scaleLine512<Pixel>(src, srcY, dst, dstY, -srcPitch, 0); - } } Index: HQ2xLiteScaler.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/HQ2xLiteScaler.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- HQ2xLiteScaler.hh 10 Mar 2005 18:19:52 -0000 1.1 +++ HQ2xLiteScaler.hh 21 Jul 2005 10:27:06 -0000 1.2 @@ -11,10 +11,10 @@ class HQ2xLiteScaler: public Scaler<Pixel> { public: - virtual void scale256(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); - virtual void scale512(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); + virtual void scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + virtual void scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); }; } // namespace openmsx Index: HQ2xScaler.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/HQ2xScaler.cc,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- HQ2xScaler.cc 12 Jun 2005 14:12:48 -0000 1.10 +++ HQ2xScaler.cc 21 Jul 2005 10:27:06 -0000 1.11 @@ -11,8 +11,12 @@ */ #include "HQ2xScaler.hh" +#include "RawFrame.hh" +#include <algorithm> #include <cassert> +using std::min; + namespace openmsx { template <class Pixel> @@ -125,30 +129,24 @@ } template <class Pixel> -static void scaleLine256( - SDL_Surface* src, int srcY, SDL_Surface* dst, int dstY, - const int prev, const int next) +static void scaleLine256(const Pixel* in0, const Pixel* in1, const Pixel* in2, + Pixel* out0, Pixel* out1) { const unsigned WIDTH = 320; - - const int srcPitch = src->pitch / sizeof(Pixel); - const int dstPitch = dst->pitch / sizeof(Pixel); - - Pixel* in = (Pixel*)src->pixels + srcY * srcPitch; - Pixel* out = (Pixel*)dst->pixels + dstY * dstPitch; - unsigned c1, c2, c3, c4, c5, c6, c7, c8, c9; - c1 = c2 = readPixel(in + prev); - c4 = c5 = readPixel(in); - c7 = c8 = readPixel(in + next); - c3 = c6 = c9 = 0; // avoid warning - in += 1; + c2 = c3 = readPixel(in0); + c5 = c6 = readPixel(in1); + c8 = c9 = readPixel(in2); for (unsigned x = 0; x < WIDTH; ++x) { + c1 = c2; c4 = c5; c7 = c8; + c2 = c3; c5 = c6; c8 = c9; + ++in0; ++in1; ++in2; + if (x != WIDTH - 1) { - c3 = readPixel(in + prev); - c6 = readPixel(in); - c9 = readPixel(in + next); + c3 = readPixel(in0); + c6 = readPixel(in1); + c9 = readPixel(in2); } unsigned pattern = 0; @@ -1399,32 +1397,22 @@ pixel1 = pixel2 = pixel3 = pixel4 = 0; // avoid warning } - pset(out, pixel1); - pset(out + 1, pixel2); - pset(out + dstPitch, pixel3); - pset(out + dstPitch + 1, pixel4); + pset(out1 + 0, pixel3); + pset(out1 + 1, pixel4); + pset(out0 + 0, pixel1); + pset(out0 + 1, pixel2); c1 = c2; c2 = c3; c4 = c5; c5 = c6; c7 = c8; c8 = c9; - - in += 1; - out += 2; + out0 += 2; out1 += 2; } } template <class Pixel> -static void scaleLine512( - SDL_Surface* src, int srcY, SDL_Surface* dst, int dstY, - const int prevLine, const int nextLine ) +static void scaleLine512(const Pixel* in0, const Pixel* in1, const Pixel* in2, + Pixel* out0, Pixel* out1) { - const int width = 640; // TODO: Specify this in a clean way. - const int srcPitch = src->pitch / sizeof(Pixel); - const int dstPitch = dst->pitch / sizeof(Pixel); - - Pixel* pIn = (Pixel*)src->pixels + srcY * srcPitch; - Pixel* pOut = (Pixel*)dst->pixels + dstY * dstPitch; - - unsigned c1, c2, c3, c4, c5, c6, c7, c8, c9; + const unsigned WIDTH = 640; // TODO: Specify this in a clean way. // +----+----+----+ // | | | | @@ -1436,21 +1424,20 @@ // | | | | // | c7 | c8 | c9 | // +----+----+----+ + unsigned c1, c2, c3, c4, c5, c6, c7, c8, c9; + c2 = c3 = readPixel(in0); + c5 = c6 = readPixel(in1); + c8 = c9 = readPixel(in2); - c2 = c3 = readPixel(pIn + prevLine); - c5 = c6 = readPixel(pIn); - c8 = c9 = readPixel(pIn + nextLine); - - for (int i = 0; i < width; i++) { + for (unsigned i = 0; i < WIDTH; i++) { c1 = c2; c4 = c5; c7 = c8; c2 = c3; c5 = c6; c8 = c9; + ++in0; ++in1; ++in2; - pIn += 1; - - if (i < width - 1) { - c3 = readPixel(pIn + prevLine); - c6 = readPixel(pIn); - c9 = readPixel(pIn + nextLine); + if (i < WIDTH - 1) { + c3 = readPixel(in0); + c6 = readPixel(in1); + c9 = readPixel(in2); } byte pattern = 0; @@ -2376,54 +2363,53 @@ assert(false); pixel1 = pixel3 = 0; // avoid warning } - pset(pOut, pixel1); - pset(pOut + dstPitch, pixel3); - - ++pOut; + pset(out1++, pixel3); + pset(out0++, pixel1); } } template <class Pixel> -void HQ2xScaler<Pixel>::scale256( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) +void HQ2xScaler<Pixel>::scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - const int srcPitch = src->pitch / sizeof(Pixel); - assert(srcY < endSrcY); - scaleLine256<Pixel>(src, srcY, dst, dstY, - 0, srcY < endSrcY - 1 ? srcPitch : 0 - ); - srcY += 1; - dstY += 2; - while (srcY < endSrcY - 1) { - scaleLine256<Pixel>(src, srcY, dst, dstY, -srcPitch, srcPitch); - srcY += 1; + unsigned dstY = 2 * startY + (lower ? 1 : 0); + unsigned prevY = startY; + while (startY < endY) { + Pixel* dummy = 0; + const Pixel* srcPrev = src.getPixelPtr(0, prevY, dummy); + const Pixel* srcCurr = src.getPixelPtr(0, startY, dummy); + const Pixel* srcNext = src.getPixelPtr(0, min(startY + 1, endY - 1), dummy); + Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, dstY + 0); + Pixel* dstLower = (dstY != (480 - 1)) + ? Scaler<Pixel>::linePtr(dst, dstY + 1) + : dstUpper; + scaleLine256(srcPrev, srcCurr, srcNext, dstUpper, dstLower); + prevY = startY; + ++startY; dstY += 2; } - if (srcY < endSrcY) { - scaleLine256<Pixel>(src, srcY, dst, dstY, -srcPitch, 0); - } } template <class Pixel> -void HQ2xScaler<Pixel>::scale512( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) +void HQ2xScaler<Pixel>::scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - const int srcPitch = src->pitch / sizeof(Pixel); - assert(srcY < endSrcY); - scaleLine512<Pixel>(src, srcY, dst, dstY, - 0, srcY < endSrcY - 1 ? srcPitch : 0); - srcY += 1; - dstY += 2; - while (srcY < endSrcY - 1) { - scaleLine512<Pixel>(src, srcY, dst, dstY, -srcPitch, srcPitch); - srcY += 1; + unsigned dstY = 2 * startY + (lower ? 1 : 0); + unsigned prevY = startY; + while (startY < endY) { + Pixel* dummy = 0; + const Pixel* srcPrev = src.getPixelPtr(0, prevY, dummy); + const Pixel* srcCurr = src.getPixelPtr(0, startY, dummy); + const Pixel* srcNext = src.getPixelPtr(0, min(startY + 1, endY - 1), dummy); + Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, dstY + 0); + Pixel* dstLower = (dstY != (480 - 1)) + ? Scaler<Pixel>::linePtr(dst, dstY + 1) + : dstUpper; + scaleLine512(srcPrev, srcCurr, srcNext, dstUpper, dstLower); + prevY = startY; + ++startY; dstY += 2; } - if (srcY < endSrcY) { - scaleLine512<Pixel>(src, srcY, dst, dstY, -srcPitch, 0); - } } Index: HQ2xScaler.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/HQ2xScaler.hh,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- HQ2xScaler.hh 10 Mar 2005 20:15:49 -0000 1.9 +++ HQ2xScaler.hh 21 Jul 2005 10:27:06 -0000 1.10 @@ -13,10 +13,10 @@ class HQ2xScaler: public Scaler<Pixel> { public: - virtual void scale256(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); - virtual void scale512(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); + virtual void scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + virtual void scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); }; } // namespace openmsx Index: LowScaler.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/LowScaler.cc,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- LowScaler.cc 20 Jul 2005 17:20:16 -0000 1.1 +++ LowScaler.cc 21 Jul 2005 10:27:06 -0000 1.2 @@ -1,6 +1,7 @@ // $Id$ #include "LowScaler.hh" +#include "RawFrame.hh" #include "HostCPU.hh" #include "openmsx.hh" #include <cassert> @@ -19,27 +20,6 @@ } template <typename Pixel> -void LowScaler<Pixel>::scaleBlank(Pixel color, SDL_Surface* dst, - int dstY, int endDstY) -{ - while (dstY < endDstY) { - Pixel* dstLine = Scaler<Pixel>::linePtr(dst, dstY++); - Scaler<Pixel>::fillLine(dstLine, color, 320); - } -} - -template <typename Pixel> -void LowScaler<Pixel>::scale256(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY) -{ - while (srcY < endSrcY) { - Pixel* srcLine = Scaler<Pixel>::linePtr(src, srcY++); - Pixel* dstLine = Scaler<Pixel>::linePtr(dst, dstY++); - Scaler<Pixel>::copyLine(srcLine, dstLine, 320, false); - } -} - -template <typename Pixel> void LowScaler<Pixel>::halve(const Pixel* pIn, Pixel* pOut) { // TODO MMX/SSE optimizations @@ -267,12 +247,33 @@ } template <typename Pixel> -void LowScaler<Pixel>::scale512(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY) +void LowScaler<Pixel>::scaleBlank(Pixel color, SDL_Surface* dst, + unsigned startY, unsigned endY, bool /*lower*/) { - while (srcY < endSrcY) { - Pixel* srcLine = Scaler<Pixel>::linePtr(src, srcY++); - Pixel* dstLine = Scaler<Pixel>::linePtr(dst, dstY++); + for (unsigned y = startY; y < endY; ++y) { + Pixel* dstLine = Scaler<Pixel>::linePtr(dst, y); + Scaler<Pixel>::fillLine(dstLine, color, 320); + } +} + +template <typename Pixel> +void LowScaler<Pixel>::scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool /*lower*/) +{ + for (unsigned y = startY; y < endY; ++y) { + const Pixel* srcLine = src.getPixelPtr(0, y, (Pixel*)0); + Pixel* dstLine = Scaler<Pixel>::linePtr(dst, y); + Scaler<Pixel>::copyLine(srcLine, dstLine, 320, false); + } +} + +template <typename Pixel> +void LowScaler<Pixel>::scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool /*lower*/) +{ + for (unsigned y = startY; y < endY; ++y) { + const Pixel* srcLine = src.getPixelPtr(0, y, (Pixel*)0); + Pixel* dstLine = Scaler<Pixel>::linePtr(dst, y); halve(srcLine, dstLine); } } Index: LowScaler.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/LowScaler.hh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- LowScaler.hh 20 Jul 2005 17:20:16 -0000 1.1 +++ LowScaler.hh 21 Jul 2005 10:27:06 -0000 1.2 @@ -15,12 +15,12 @@ LowScaler(SDL_PixelFormat* format); virtual ~LowScaler(); - virtual void scaleBlank(Pixel color, - SDL_Surface* dst, int dstY, int endDstY); - virtual void scale256(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); - virtual void scale512(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); + virtual void scaleBlank(Pixel color, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + virtual void scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + virtual void scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); private: void halve(const Pixel* pIn, Pixel* pOut); Index: PostProcessor.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/PostProcessor.cc,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- PostProcessor.cc 20 Jul 2005 20:28:20 -0000 1.2 +++ PostProcessor.cc 21 Jul 2005 10:27:06 -0000 1.3 @@ -49,7 +49,7 @@ // Scale image. // TODO: Check deinterlace first: now that we keep LineContent info per // frame, we should take the content of two frames into account. - const unsigned deltaY = field == RawFrame::FIELD_ODD ? 1 : 0; + bool lower = field == RawFrame::FIELD_ODD; unsigned startY = 0; while (startY < 240) { const RawFrame::LineContent content = currFrame->getLineContent(startY); @@ -70,14 +70,11 @@ // TODO: This isn't 100% accurate: // on the previous frame, this area may have contained // graphics instead of blank pixels. - // TODO: Why add deltaY when deinterlacing? - currScaler->scaleBlank( - colour, screen, - startY * 2 + deltaY, endY * 2 + deltaY ); + currScaler->scaleBlank(colour, screen, + startY, endY, false); } else { - currScaler->scaleBlank( - colour, screen, - startY * 2 + deltaY, endY * 2 + deltaY ); + currScaler->scaleBlank(colour, screen, + startY, endY, lower); } break; } @@ -88,16 +85,13 @@ assert(field != RawFrame::FIELD_NONINTERLACED); bool odd = field == RawFrame::FIELD_ODD; deinterlacer.deinterlaceLine256( - (odd ? prevFrame : currFrame)->getSurface(), // even - (odd ? currFrame : prevFrame)->getSurface(), // odd - y, screen, y * 2 - ); + *(odd ? prevFrame : currFrame), // even + *(odd ? currFrame : prevFrame), // odd + screen, y); } } else { - currScaler->scale256( - currFrame->getSurface(), - startY, endY, screen, startY * 2 + deltaY - ); + currScaler->scale256(*currFrame, screen, + startY, endY, lower); } break; case RawFrame::LINE_512: @@ -107,16 +101,13 @@ assert(field != RawFrame::FIELD_NONINTERLACED); bool odd = field == RawFrame::FIELD_ODD; deinterlacer.deinterlaceLine512( - (odd ? prevFrame : currFrame)->getSurface(), // even - (odd ? currFrame : prevFrame)->getSurface(), // odd - y, screen, y * 2 - ); + *(odd ? prevFrame : currFrame), // even + *(odd ? currFrame : prevFrame), // odd + screen, y); } } else { - currScaler->scale512( - currFrame->getSurface(), - startY, endY, screen, startY * 2 + deltaY - ); + currScaler->scale512(*currFrame, screen, + startY, endY, lower); } break; default: Index: SaI2xScaler.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/SaI2xScaler.cc,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- SaI2xScaler.cc 12 Jun 2005 14:12:48 -0000 1.9 +++ SaI2xScaler.cc 21 Jul 2005 10:27:06 -0000 1.10 @@ -7,6 +7,7 @@ // Modified for use in openMSX by Maarten ter Huurne. #include "SaI2xScaler.hh" +#include "RawFrame.hh" #include "openmsx.hh" #include <cassert> @@ -21,8 +22,8 @@ { } -const int WIDTH256 = 320; // TODO: Specify this in a clean way. -const int HEIGHT = 480; +const unsigned WIDTH256 = 320; // TODO: Specify this in a clean way. +const unsigned HEIGHT = 480; template <class Pixel> void SaI2xScaler<Pixel>::scaleLine256( @@ -31,16 +32,16 @@ Pixel* dstUpper, Pixel* dstLower ) { // TODO: Scale border pixels as well. - for (int x = 0; x < WIDTH256; x++) { + for (unsigned x = 0; x < WIDTH256; x++) { // Map of the pixels: // I|E F|J // G|A B|K // H|C D|L // M|N O|P - int xl = max(x - 1, 0); - int xr = min(x + 1, WIDTH256 - 1); - int xrr = min(x + 2, WIDTH256 - 1); + unsigned xl = x ? x - 1 : 0; + unsigned xr = min(x + 1, WIDTH256 - 1); + unsigned xrr = min(x + 2, WIDTH256 - 1); // TODO: Possible performance improvements: // - Play with order of fetching (effect on data cache). @@ -242,39 +243,40 @@ } template <class Pixel> -void SaI2xScaler<Pixel>::scale256( - SDL_Surface* src, int srcY, int endSrcY, SDL_Surface* dst, int dstY ) +void SaI2xScaler<Pixel>::scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { assert(dst->w == WIDTH256 * 2); - for (int y = srcY; y < endSrcY; y++) { - const Pixel* srcLine0 = Scaler<Pixel>::linePtr(src, max(y - 1, srcY)); - const Pixel* srcLine1 = Scaler<Pixel>::linePtr(src, y); - const Pixel* srcLine2 = Scaler<Pixel>::linePtr(src, min(y + 1, endSrcY - 1)); - const Pixel* srcLine3 = Scaler<Pixel>::linePtr(src, min(y + 2, endSrcY - 1)); + unsigned dstY = 2 * startY + (lower ? 1 : 0); + for (unsigned y = startY; y < endY; ++y) { + const Pixel* srcLine0 = src.getPixelPtr(0, max(y - 1, startY), (Pixel*)0); + const Pixel* srcLine1 = src.getPixelPtr(0, y, (Pixel*)0); + const Pixel* srcLine2 = src.getPixelPtr(0, min(y + 1, endY - 1), (Pixel*)0); + const Pixel* srcLine3 = src.getPixelPtr(0, min(y + 2, endY - 1), (Pixel*)0); Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, dstY++); Pixel* dstLower = Scaler<Pixel>::linePtr(dst, min(dstY++, HEIGHT - 1)); - scaleLine256( - srcLine0, srcLine1, srcLine2, srcLine3, dstUpper, dstLower ); + scaleLine256(srcLine0, srcLine1, srcLine2, srcLine3, + dstUpper, dstLower); } } template <class Pixel> -void SaI2xScaler<Pixel>::scale512( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) +void SaI2xScaler<Pixel>::scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { assert(dst->w == WIDTH512); - for (int y = srcY; y < endSrcY; y++) { - const Pixel* srcLine0 = Scaler<Pixel>::linePtr(src, max(y - 1, srcY)); - const Pixel* srcLine1 = Scaler<Pixel>::linePtr(src, y); - const Pixel* srcLine2 = Scaler<Pixel>::linePtr(src, min(y + 1, endSrcY - 1)); - const Pixel* srcLine3 = Scaler<Pixel>::linePtr(src, min(y + 2, endSrcY - 1)); + unsigned dstY = 2 * startY + (lower ? 1 : 0); + for (unsigned y = startY; y < endY; y++) { + const Pixel* srcLine0 = src.getPixelPtr(0, max(y - 1, startY), (Pixel*)0); + const Pixel* srcLine1 = src.getPixelPtr(0, y, (Pixel*)0); + const Pixel* srcLine2 = src.getPixelPtr(0, min(y + 1, endY - 1), (Pixel*)0); + const Pixel* srcLine3 = src.getPixelPtr(0, min(y + 2, endY - 1), (Pixel*)0); Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, dstY++); Pixel* dstLower = Scaler<Pixel>::linePtr(dst, min(dstY++, HEIGHT - 1)); - scaleLine512( - srcLine0, srcLine1, srcLine2, srcLine3, dstUpper, dstLower ); + scaleLine512(srcLine0, srcLine1, srcLine2, srcLine3, + dstUpper, dstLower); } } Index: SaI2xScaler.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/SaI2xScaler.hh,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- SaI2xScaler.hh 10 Mar 2005 20:15:49 -0000 1.5 +++ SaI2xScaler.hh 21 Jul 2005 10:27:06 -0000 1.6 @@ -16,21 +16,20 @@ { public: SaI2xScaler(SDL_PixelFormat* format); - void scale256( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ); - void scale512( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ); + virtual void scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + virtual void scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + private: void scaleLine256( const Pixel* srcLine0, const Pixel* srcLine1, const Pixel* srcLine2, const Pixel* srcLine3, - Pixel* dstUpper, Pixel* dstLower ); + Pixel* dstUpper, Pixel* dstLower); void scaleLine512( const Pixel* srcLine0, const Pixel* srcLine1, const Pixel* srcLine2, const Pixel* srcLine3, - Pixel* dstUpper, Pixel* dstLower ); + Pixel* dstUpper, Pixel* dstLower); Blender<Pixel> blender; }; Index: Scale2xScaler.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/Scale2xScaler.cc,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- Scale2xScaler.cc 7 Jul 2005 14:18:34 -0000 1.14 +++ Scale2xScaler.cc 21 Jul 2005 10:27:06 -0000 1.15 @@ -13,6 +13,7 @@ */ #include "Scale2xScaler.hh" +#include "RawFrame.hh" #include "HostCPU.hh" #include "openmsx.hh" #include <cassert> @@ -1080,42 +1081,44 @@ } template <class Pixel> -void Scale2xScaler<Pixel>::scale256( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) +void Scale2xScaler<Pixel>::scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - int prevY = srcY; - while (srcY < endSrcY) { - Pixel* srcPrev = Scaler<Pixel>::linePtr(src, prevY); - Pixel* srcCurr = Scaler<Pixel>::linePtr(src, srcY); - Pixel* srcNext = Scaler<Pixel>::linePtr(src, min(srcY + 1, endSrcY - 1)); + unsigned dstY = 2 * startY + (lower ? 1 : 0); + unsigned prevY = startY; + while (startY < endY) { + Pixel* dummy = 0; + const Pixel* srcPrev = src.getPixelPtr(0, prevY, dummy); + const Pixel* srcCurr = src.getPixelPtr(0, startY, dummy); + const Pixel* srcNext = src.getPixelPtr(0, min(startY + 1, endY - 1), dummy); Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, dstY++); scaleLine256Half(dstUpper, srcPrev, srcCurr, srcNext); - if (dstY == dst->h) break; + if (dstY == 480) break; Pixel* dstLower = Scaler<Pixel>::linePtr(dst, dstY++); scaleLine256Half(dstLower, srcNext, srcCurr, srcPrev); - prevY = srcY; - srcY++; + prevY = startY; + ++startY; } } template <class Pixel> -void Scale2xScaler<Pixel>::scale512( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY) +void Scale2xScaler<Pixel>::scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - int prevY = srcY; - while (srcY < endSrcY) { - Pixel* srcPrev = Scaler<Pixel>::linePtr(src, prevY); - Pixel* srcCurr = Scaler<Pixel>::linePtr(src, srcY); - Pixel* srcNext = Scaler<Pixel>::linePtr(src, min(srcY + 1, endSrcY - 1)); + unsigned dstY = 2 * startY + (lower ? 1 : 0); + unsigned prevY = startY; + while (startY < endY) { + Pixel* dummy = 0; + const Pixel* srcPrev = src.getPixelPtr(0, prevY, dummy); + const Pixel* srcCurr = src.getPixelPtr(0, startY, dummy); + const Pixel* srcNext = src.getPixelPtr(0, min(startY + 1, endY - 1), dummy); Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, dstY++); scaleLine512Half(dstUpper, srcPrev, srcCurr, srcNext); - if (dstY == dst->h) break; + if (dstY == 480) break; Pixel* dstLower = Scaler<Pixel>::linePtr(dst, dstY++); scaleLine512Half(dstLower, srcNext, srcCurr, srcPrev); - prevY = srcY; - srcY++; + prevY = startY; + ++startY; } } Index: Scale2xScaler.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/Scale2xScaler.hh,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- Scale2xScaler.hh 10 Mar 2005 20:15:49 -0000 1.9 +++ Scale2xScaler.hh 21 Jul 2005 10:27:06 -0000 1.10 @@ -13,10 +13,11 @@ class Scale2xScaler: public Scaler<Pixel> { public: - virtual void scale256(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); - virtual void scale512(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); + virtual void scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + virtual void scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + private: void scaleLine256Half(Pixel* dst, const Pixel* src0, const Pixel* src1, const Pixel* src2); Index: Scaler.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/Scaler.cc,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- Scaler.cc 20 Jul 2005 17:20:16 -0000 1.26 +++ Scaler.cc 21 Jul 2005 10:27:06 -0000 1.27 @@ -7,7 +7,9 @@ #include "HQ2xScaler.hh" #include "HQ2xLiteScaler.hh" #include "LowScaler.hh" +#include "RawFrame.hh" #include "HostCPU.hh" +#include <algorithm> #include <cstring> using std::auto_ptr; @@ -38,20 +40,10 @@ } template <class Pixel> -void Scaler<Pixel>::copyLine( - SDL_Surface* src, int srcY, SDL_Surface* dst, int dstY ) -{ - assert(src->w == dst->w); - Pixel* pIn = linePtr(src, srcY); - Pixel* pOut = linePtr(dst, dstY); - copyLine(pIn, pOut, src->w); -} - -template <class Pixel> void Scaler<Pixel>::copyLine(const Pixel* pIn, Pixel* pOut, unsigned width, bool inCache) { - const int nBytes = width * sizeof(Pixel); + unsigned nBytes = width * sizeof(Pixel); #ifdef ASM_X86 const HostCPU& cpu = HostCPU::getInstance(); @@ -144,16 +136,6 @@ } template <class Pixel> -void Scaler<Pixel>::scaleLine( - SDL_Surface* src, int srcY, SDL_Surface* dst, int dstY ) -{ - assert(dst->w == 640); - Pixel* pIn = linePtr(src, srcY); - Pixel* pOut = linePtr(dst, dstY); - scaleLine(pIn, pOut, 320); -} - -template <class Pixel> void Scaler<Pixel>::scaleLine(const Pixel* pIn, Pixel* pOut, unsigned width, bool inCache) { @@ -463,45 +445,56 @@ template <class Pixel> void Scaler<Pixel>::scaleBlank( - Pixel colour, - SDL_Surface* dst, int dstY, int endDstY) + Pixel color, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - while (dstY < endDstY) { - Pixel* dstLine = Scaler<Pixel>::linePtr(dst, dstY++); - fillLine(dstLine, colour, dst->w); + unsigned y1 = 2 * startY + (lower ? 1 : 0); + unsigned y2 = 2 * endY + (lower ? 1 : 0); + y2 = std::min(480u, y2); + for (unsigned y = y1; y < y2; ++y) { + Pixel* dstLine = Scaler<Pixel>::linePtr(dst, y); + fillLine(dstLine, color, dst->w); } } template <class Pixel> void Scaler<Pixel>::scale256( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) + RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - while (srcY < endSrcY) { - scaleLine(src, srcY, dst, dstY++); - if (dstY == dst->h) break; - scaleLine(src, srcY, dst, dstY++); - srcY++; + unsigned y1 = 2 * startY + (lower ? 1 : 0); + unsigned y2 = 2 * endY + (lower ? 1 : 0); + for (unsigned y = y1; y < y2; y += 2, ++startY) { + const Pixel* srcLine = src.getPixelPtr(0, startY, (Pixel*)0); + Pixel* dstLine1 = Scaler<Pixel>::linePtr(dst, y + 0); + scaleLine(srcLine, dstLine1, 320); + if (y == (480 - 1)) break; + Pixel* dstLine2 = Scaler<Pixel>::linePtr(dst, y + 1); + scaleLine(srcLine, dstLine2, 320); } } template <class Pixel> void Scaler<Pixel>::scale512( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) + RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - while (srcY < endSrcY) { - copyLine(src, srcY, dst, dstY++); - if (dstY == dst->h) break; - copyLine(src, srcY, dst, dstY++); - srcY++; + unsigned y1 = 2 * startY + (lower ? 1 : 0); + unsigned y2 = 2 * endY + (lower ? 1 : 0); + for (unsigned y = y1; y < y2; y += 2, ++startY) { + const Pixel* srcLine = src.getPixelPtr(0, startY, (Pixel*)0); + Pixel* dstLine1 = Scaler<Pixel>::linePtr(dst, y + 0); + copyLine(srcLine, dstLine1, 640); + if (y == (480 - 1)) break; + Pixel* dstLine2 = Scaler<Pixel>::linePtr(dst, y + 1); + copyLine(srcLine, dstLine2, 640); } } // Force template instantiation. template class Scaler<word>; -template class Scaler<unsigned int>; +template class Scaler<unsigned>; } // namespace openmsx Index: Scaler.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/Scaler.hh,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- Scaler.hh 20 Jul 2005 17:20:16 -0000 1.18 +++ Scaler.hh 21 Jul 2005 10:27:06 -0000 1.19 @@ -10,6 +10,8 @@ namespace openmsx { +class RawFrame; + /** Enumeration of Scalers known to openMSX. */ enum ScalerID { @@ -43,68 +45,50 @@ */ static std::auto_ptr<Scaler> createScaler(ScalerID id, SDL_PixelFormat* format); - /** Fills the given area, which contains only a single colour. - * @param colour Colour the area should be filled with. + /** Fills the given area, which contains only a single color. + * @param color Color the area should be filled with. * @param dst Destination: image to store the scaled output in. - * It should be 640 pixels wide. - * @param dstY Y-coordinate of the top destination line. - * @param endDstY Y-coordinate of the bottom destination line (exclusive). + * @param startY Y-coordinate of the top line. + * @param endY Y-coordinate of the bottom line (exclusive). + * @param lower True iff frame must be displayed half a line lower */ - virtual void scaleBlank( - Pixel colour, - SDL_Surface* dst, int dstY, int endDstY ); + virtual void scaleBlank(Pixel color, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); - /** Scales the given area 200% horizontally and vertically. + /** Scales the given area. Scaling factor depends on the concrete scaler * The default implementation scales each pixel to a 2x2 square. * @param src Source: the image to be scaled. * It should be 320 pixels wide. - * @param srcY Y-coordinate of the top source line (inclusive). - * @param endSrcY Y-coordinate of the bottom source line (exclusive). * @param dst Destination: image to store the scaled output in. - * It should be 640 pixels wide and twice as high as the source image. - * @param dstY Y-coordinate of the top destination line. - * Note: The scaler must be able to handle the case where dstY is - * inside the destination surface, but dstY + 1 is not. + * @param startY Y-coordinate of the top source line (inclusive). + * @param endY Y-coordinate of the bottom source line (exclusive). + * @param lower True iff frame must be displayed half a line lower */ - virtual void scale256( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ); + virtual void scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); - /** Scales the given area 200% vertically. + /** Scales the given area. Scaling factor depends on the concrete scaler * The default implementation scales each pixel to a 1x2 rectangle. * @param src Source: the image to be scaled. * It should be 640 pixels wide. - * @param srcY Y-coordinate of the top source line (inclusive). - * @param endSrcY Y-coordinate of the bottom source line (exclusive). * @param dst Destination: image to store the scaled output in. - * It should be 640 pixels wide and twice as high as the source image. - * @param dstY Y-coordinate of the top destination line. - * Note: The scaler must be able to handle the case where dstY is - * inside the destination surface, but dstY + 1 is not. + * @param startY Y-coordinate of the top source line (inclusive). + * @param endY Y-coordinate of the bottom source line (exclusive). + * @param lower True iff frame must be displayed half a line lower */ - virtual void scale512( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ); + virtual void scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); // Utility methods (put in seperate class?) /** Get the start address of a line in a surface */ - inline static Pixel* linePtr(SDL_Surface* surface, int y) { - assert(0 <= y && y < surface->h); + inline static Pixel* linePtr(SDL_Surface* surface, unsigned y) { + assert(y < (unsigned)surface->h); return (Pixel*)((byte*)surface->pixels + y * surface->pitch); } /** Copies the given line. - * @param src Source: surface to copy from. - * @param srcY Line number on source surface. - * @param dst Destination: surface to copy to. - * @param dstY Line number on destination surface. - */ - static void copyLine( - SDL_Surface* src, int srcY, SDL_Surface* dst, int dstY); - - /** Copies the given line. * @param pIn ptr to start of source line * @param pOut ptr to start of destination line * @param width the width of the line @@ -117,15 +101,6 @@ bool inCache = false); /** Scales the given line a factor 2 horizontally. - * @param src Source: surface to copy from. - * @param srcY Line number on source surface. - * @param dst Destination: surface to copy to. - * @param dstY Line number on destination surface. - */ - static void scaleLine( - SDL_Surface* src, int srcY, SDL_Surface* dst, int dstY); - - /** Scales the given line a factor 2 horizontally. * @param pIn ptr to start of source line * @param pOut ptr to start of destination line * @param width the width of the source line Index: SimpleScaler.cc =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/SimpleScaler.cc,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- SimpleScaler.cc 7 Jul 2005 14:18:34 -0000 1.30 +++ SimpleScaler.cc 21 Jul 2005 10:27:06 -0000 1.31 @@ -1,6 +1,7 @@ // $Id$ #include "SimpleScaler.hh" +#include "RawFrame.hh" #include "RenderSettings.hh" #include "IntegerSetting.hh" #include "HostCPU.hh" @@ -189,20 +190,22 @@ } template <class Pixel> -void SimpleScaler<Pixel>::scaleBlank(Pixel colour, SDL_Surface* dst, - int dstY, int endDstY) +void SimpleScaler<Pixel>::scaleBlank(Pixel color, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { - Pixel scanlineColour = scanlineSetting.getValue() == 0 - ? colour - : mult1.multiply(colour, + Pixel scanlineColor = scanlineSetting.getValue() == 0 + ? color + : mult1.multiply(color, 255 - (scanlineSetting.getValue() * 255) / 100); - while (dstY < endDstY) { - Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, dstY++); - Scaler<Pixel>::fillLine(dstUpper, colour, dst->w); - if (dstY == endDstY) break; - Pixel* dstLower = Scaler<Pixel>::linePtr(dst, dstY++); - Scaler<Pixel>::fillLine(dstLower, scanlineColour, dst->w); + unsigned y1 = 2 * startY + (lower ? 1 : 0); + unsigned y2 = 2 * endY + (lower ? 1 : 0); + for (unsigned y = y1; y < y2; y += 2) { + Pixel* dstUpper = Scaler<Pixel>::linePtr(dst, y + 0); + Scaler<Pixel>::fillLine(dstUpper, color, 640); + if (y == (480 - 1)) break; + Pixel* dstLower = Scaler<Pixel>::linePtr(dst, y + 1); + Scaler<Pixel>::fillLine(dstLower, scanlineColor, 640); } } @@ -752,19 +755,20 @@ } template <class Pixel> -void SimpleScaler<Pixel>::scale256(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) +void SimpleScaler<Pixel>::scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { int blur = (blurSetting.getValue() * 256) / 100; int scanline = 255 - (scanlineSetting.getValue() * 255) / 100; - Pixel* srcLine = Scaler<Pixel>::linePtr(src, srcY++); + unsigned dstY = 2 * startY + (lower ? 1 : 0); + const Pixel* srcLine = src.getPixelPtr(0, startY++, (Pixel*)0); Pixel* dstLine0 = Scaler<Pixel>::linePtr(dst, dstY++); Pixel* prevDstLine0 = dstLine0; blur256(srcLine, dstLine0, blur); - while (srcY < endSrcY) { - srcLine = Scaler<Pixel>::linePtr(src, srcY++); + while (startY < endY) { + srcLine = src.getPixelPtr(0, startY++, (Pixel*)0); dstLine0 = Scaler<Pixel>::linePtr(dst, dstY + 1); blur256(srcLine, dstLine0, blur); @@ -776,27 +780,27 @@ } // When interlace is enabled, bottom line can fall off the screen. - if (dstY < dst->h) { + if (dstY < 480) { Pixel* dstLine1 = Scaler<Pixel>::linePtr(dst, dstY); average(prevDstLine0, dstLine0, dstLine1, scanline); } } template <class Pixel> -void SimpleScaler<Pixel>::scale512( - SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY ) +void SimpleScaler<Pixel>::scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower) { int blur = (blurSetting.getValue() * 256) / 100; int scanline = 255 - (scanlineSetting.getValue() * 255) / 100; - Pixel* srcLine = Scaler<Pixel>::linePtr(src, srcY++); + unsigned dstY = 2 * startY + (lower ? 1 : 0); + const Pixel* srcLine = src.getPixelPtr(0, startY++, (Pixel*)0); Pixel* dstLine0 = Scaler<Pixel>::linePtr(dst, dstY++); Pixel* prevDstLine0 = dstLine0; blur512(srcLine, dstLine0, blur); - while (srcY < endSrcY) { - srcLine = Scaler<Pixel>::linePtr(src, srcY++); + while (startY < endY) { + srcLine = src.getPixelPtr(0, startY++, (Pixel*)0); dstLine0 = Scaler<Pixel>::linePtr(dst, dstY + 1); blur512(srcLine, dstLine0, blur); @@ -808,7 +812,7 @@ } // When interlace is enabled, bottom line can fall off the screen. - if (dstY < dst->h) { + if (dstY < 480) { Pixel* dstLine1 = Scaler<Pixel>::linePtr(dst, dstY); average(prevDstLine0, dstLine0, dstLine1, scanline); } Index: SimpleScaler.hh =================================================================== RCS file: /cvsroot/openmsx/openMSX/src/video/SimpleScaler.hh,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- SimpleScaler.hh 10 Mar 2005 20:15:49 -0000 1.10 +++ SimpleScaler.hh 21 Jul 2005 10:27:06 -0000 1.11 @@ -77,12 +77,12 @@ SimpleScaler(SDL_PixelFormat* format); virtual ~SimpleScaler(); - virtual void scaleBlank(Pixel colour, - SDL_Surface* dst, int dstY, int endDstY); - virtual void scale256(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); - virtual void scale512(SDL_Surface* src, int srcY, int endSrcY, - SDL_Surface* dst, int dstY); + virtual void scaleBlank(Pixel color, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + virtual void scale256(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); + virtual void scale512(RawFrame& src, SDL_Surface* dst, + unsigned startY, unsigned endY, bool lower); private: void blur256(const Pixel* pIn, Pixel* pOut, unsigned alpha); |