diff options
author | Eugene Sandulenko | 2006-05-17 23:52:45 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2006-05-17 23:52:45 +0000 |
commit | 14ec3f45fa08a0c0071693f4094fc088eb0062b5 (patch) | |
tree | 87e2af334bd1503eacc55c71cd5ccb94e5eb5751 | |
parent | 65091f7370ee118b8f99c6106d8cad1fd0ee719e (diff) | |
download | scummvm-rg350-14ec3f45fa08a0c0071693f4094fc088eb0062b5.tar.gz scummvm-rg350-14ec3f45fa08a0c0071693f4094fc088eb0062b5.tar.bz2 scummvm-rg350-14ec3f45fa08a0c0071693f4094fc088eb0062b5.zip |
- Heavily modified patch #1214784: "Disable overlay scaling"
- Eriktorbjorn's patch from same tracker item for scaling sword1/2 cutscenes
is applied as is. It lacks resolution switch on-the-fly.
- GUI widgets are repositioned on the fly and use most space, even aspect
ratio corrected screen is used without scaling
- Heavy tesing is required, but works for me in all cases except for bug
#1483272: "GUI: SCUMM pause dialog breaks upon scaler switch" which needs more
work.
- I probavly broke some backend or two
svn-id: r22505
36 files changed, 352 insertions, 220 deletions
@@ -494,7 +494,6 @@ arguments -- see the next section. --aspect-ratio Enable aspect ratio correction --render-mode=MODE Enable additional render modes (cga, ega, hercGreen, hercAmber, amiga) - --force-1x-overlay Make inner GUI 320x200 --alt-intro Use alternative intro for CD versions of Beneath a Steel Sky and Flight of the Amazon Queen diff --git a/backends/PalmOS/Src/base_gfx.cpp b/backends/PalmOS/Src/base_gfx.cpp index 9dddc0d14d..f9d3db5d4a 100755 --- a/backends/PalmOS/Src/base_gfx.cpp +++ b/backends/PalmOS/Src/base_gfx.cpp @@ -76,7 +76,7 @@ bool OSystem_PalmBase::setGraphicsMode(int mode) { * */ -void OSystem_PalmBase::initSize(uint w, uint h, int overlayScale) { +void OSystem_PalmBase::initSize(uint w, uint h) { _screenWidth = w; _screenHeight = h; @@ -88,7 +88,7 @@ void OSystem_PalmBase::initSize(uint w, uint h, int overlayScale) { load_gfx_mode(); warpMouse(200, 150); - int_initSize(w, h, overlayScale); + int_initSize(w, h); } /* diff --git a/backends/PalmOS/Src/be_base.h b/backends/PalmOS/Src/be_base.h index f5cad4a903..a5ef22a226 100755 --- a/backends/PalmOS/Src/be_base.h +++ b/backends/PalmOS/Src/be_base.h @@ -67,7 +67,7 @@ private: virtual const GraphicsMode *int_getSupportedGraphicsModes() const; virtual void int_updateScreen() = 0; - virtual void int_initSize(uint w, uint h, int overlayScale) = 0; + virtual void int_initSize(uint w, uint h) = 0; virtual void int_setShakePos(int shakeOffset) { } virtual void extras_palette(uint8 index, uint8 r, uint8 g, uint8 b) { } @@ -195,7 +195,7 @@ public: virtual bool setGraphicsMode(int mode); virtual bool grabRawScreen(Graphics::Surface *surf) { return false; } - void initSize(uint w, uint h, int overlayScale); + void initSize(uint w, uint h); int16 getWidth() { return _screenWidth; } int16 getHeight() { return _screenHeight; } diff --git a/backends/PalmOS/Src/be_os5.h b/backends/PalmOS/Src/be_os5.h index 51070fac23..40a8340820 100755 --- a/backends/PalmOS/Src/be_os5.h +++ b/backends/PalmOS/Src/be_os5.h @@ -112,7 +112,7 @@ private: virtual void int_initBackend(); virtual void int_updateScreen(); - virtual void int_initSize(uint w, uint h, int overlayScale); + virtual void int_initSize(uint w, uint h); virtual void unload_gfx_mode(); virtual void load_gfx_mode(); diff --git a/backends/PalmOS/Src/os5_gfx.cpp b/backends/PalmOS/Src/os5_gfx.cpp index 73dea43513..2e2ec68454 100755 --- a/backends/PalmOS/Src/os5_gfx.cpp +++ b/backends/PalmOS/Src/os5_gfx.cpp @@ -33,7 +33,7 @@ #include "oscalls.h" -void OSystem_PalmOS5::int_initSize(uint w, uint h, int overlayScale) { +void OSystem_PalmOS5::int_initSize(uint w, uint h) { } WinHandle OSystem_PalmOS5::alloc_screen(Coord w, Coord h) { diff --git a/backends/dc/dc.h b/backends/dc/dc.h index dd390c7f2d..aaf505bd64 100644 --- a/backends/dc/dc.h +++ b/backends/dc/dc.h @@ -69,7 +69,7 @@ class OSystem_Dreamcast : public OSystem { // Set the size of the video bitmap. // Typically, 320x200 - void initSize(uint w, uint h, int overlayScale); + void initSize(uint w, uint h); int16 getHeight() { return _screen_h; } int16 getWidth() { return _screen_w; } diff --git a/backends/dc/display.cpp b/backends/dc/display.cpp index 6d38ab866a..338138f912 100644 --- a/backends/dc/display.cpp +++ b/backends/dc/display.cpp @@ -192,7 +192,7 @@ void OSystem_Dreamcast::setScaling() } } -void OSystem_Dreamcast::initSize(uint w, uint h, int overlayScale) +void OSystem_Dreamcast::initSize(uint w, uint h) { assert(w <= SCREEN_W && h <= SCREEN_H); diff --git a/backends/gp32/gp32_osys.cpp b/backends/gp32/gp32_osys.cpp index 52dd1d32a5..da0b0a0475 100644 --- a/backends/gp32/gp32_osys.cpp +++ b/backends/gp32/gp32_osys.cpp @@ -98,7 +98,7 @@ int OSystem_GP32::getGraphicsMode() const { return -1; } -void OSystem_GP32::initSize(uint width, uint height, int overlayScale) { +void OSystem_GP32::initSize(uint width, uint height) { NP("OSys::initSize()"); if (width == _screenWidth && height == _screenHeight) diff --git a/backends/gp32/gp32_osys.h b/backends/gp32/gp32_osys.h index 4bb2bfb1f1..0833577bc2 100644 --- a/backends/gp32/gp32_osys.h +++ b/backends/gp32/gp32_osys.h @@ -95,7 +95,7 @@ public: virtual bool setGraphicsMode(int mode); bool setGraphicsMode(const char *name); virtual int getGraphicsMode() const; - virtual void initSize(uint width, uint height, int overlayScale); + virtual void initSize(uint width, uint height); virtual int16 getHeight(); virtual int16 getWidth(); virtual void setPalette(const byte *colors, uint start, uint num); diff --git a/backends/morphos/morphos.cpp b/backends/morphos/morphos.cpp index 541f56c73b..889976afc4 100644 --- a/backends/morphos/morphos.cpp +++ b/backends/morphos/morphos.cpp @@ -1456,7 +1456,7 @@ void OSystem_MorphOS::clearSoundCallback() } } -void OSystem_MorphOS::initSize(uint w, uint h, int overlayScale) +void OSystem_MorphOS::initSize(uint w, uint h) { if (ScummBuffer) { diff --git a/backends/morphos/morphos.h b/backends/morphos/morphos.h index 7f919f7080..67ed8a481e 100644 --- a/backends/morphos/morphos.h +++ b/backends/morphos/morphos.h @@ -48,7 +48,7 @@ class OSystem_MorphOS : public OSystem // Set the size of the video bitmap. // Typically, 320x200 - virtual void initSize(uint w, uint h, int overlayScale); + virtual void initSize(uint w, uint h); // Draw a bitmap to screen. // The screen will not be updated to reflect the new bitmap diff --git a/backends/null/null.cpp b/backends/null/null.cpp index fdc275178a..b44a1ee710 100644 --- a/backends/null/null.cpp +++ b/backends/null/null.cpp @@ -46,7 +46,7 @@ public: virtual bool setGraphicsMode(int mode); bool setGraphicsMode(const char *name); virtual int getGraphicsMode() const; - virtual void initSize(uint width, uint height, int overlayScale); + virtual void initSize(uint width, uint height); virtual int16 getHeight(); virtual int16 getWidth(); virtual void setPalette(const byte *colors, uint start, uint num); @@ -164,7 +164,7 @@ int OSystem_NULL::getGraphicsMode() const return -1; } -void OSystem_NULL::initSize(uint width, uint height, int overlayScale) +void OSystem_NULL::initSize(uint width, uint height) { } diff --git a/backends/ps2/systemps2.cpp b/backends/ps2/systemps2.cpp index 320ad78b8f..3f8ee9c969 100644 --- a/backends/ps2/systemps2.cpp +++ b/backends/ps2/systemps2.cpp @@ -416,7 +416,7 @@ void OSystem_PS2::loadModules(void) { sioprintf("Modules: UsbMouse %sloaded, UsbKbd %sloaded.", _useMouse ? "" : "not ", _useKbd ? "" : "not "); } -void OSystem_PS2::initSize(uint width, uint height, int overscale) { +void OSystem_PS2::initSize(uint width, uint height) { printf("initializing new size: (%d/%d)...", width, height); _screen->newScreenSize(width, height); _screen->setMouseXy(width / 2, height / 2); diff --git a/backends/ps2/systemps2.h b/backends/ps2/systemps2.h index a77ea7a31a..e3de3e1a4e 100644 --- a/backends/ps2/systemps2.h +++ b/backends/ps2/systemps2.h @@ -45,7 +45,7 @@ class OSystem_PS2 : public OSystem { public: OSystem_PS2(void); virtual ~OSystem_PS2(void); - virtual void initSize(uint width, uint height, int overScale = -1); + virtual void initSize(uint width, uint height); virtual int16 getHeight(void); virtual int16 getWidth(void); diff --git a/backends/psp/osys_psp.cpp b/backends/psp/osys_psp.cpp index 2cb4431994..8b9242299f 100644 --- a/backends/psp/osys_psp.cpp +++ b/backends/psp/osys_psp.cpp @@ -120,18 +120,17 @@ int OSystem_PSP::getGraphicsMode() const return -1; } -void OSystem_PSP::initSize(uint width, uint height, int overlayScale) { +void OSystem_PSP::initSize(uint width, uint height) { _screenWidth = width; _screenHeight = height; _offscreen = (byte *)malloc(width * height); - if(overlayScale == -1) - overlayScale = 1; - - _overlayScale = overlayScale; - _overlayBuffer = (OverlayColor *)malloc(width * overlayScale * height * overlayScale * sizeof(OverlayColor)); + // TODO: Fixme. This is not neede anymore + _overlayScale = 1; + + _overlayBuffer = (OverlayColor *)malloc(width * height * sizeof(OverlayColor)); bzero(_offscreen, width * height); - bzero(_overlayBuffer, width * overlayScale * height * overlayScale); + bzero(_overlayBuffer, width * height); _mouseVisible = false; } diff --git a/backends/psp/osys_psp.h b/backends/psp/osys_psp.h index 8131467b0b..b5e16df86d 100644 --- a/backends/psp/osys_psp.h +++ b/backends/psp/osys_psp.h @@ -80,7 +80,7 @@ public: virtual bool setGraphicsMode(int mode); bool setGraphicsMode(const char *name); virtual int getGraphicsMode() const; - virtual void initSize(uint width, uint height, int overlayScale); + virtual void initSize(uint width, uint height); virtual int16 getHeight(); virtual int16 getWidth(); virtual void setPalette(const byte *colors, uint start, uint num); diff --git a/backends/psp/osys_psp_gu.cpp b/backends/psp/osys_psp_gu.cpp index 53add476c5..1cee404655 100644 --- a/backends/psp/osys_psp_gu.cpp +++ b/backends/psp/osys_psp_gu.cpp @@ -132,20 +132,19 @@ OSystem_PSP_GU::~OSystem_PSP_GU() sceGuTerm(); } -void OSystem_PSP_GU::initSize(uint width, uint height, int overlayScale) { +void OSystem_PSP_GU::initSize(uint width, uint height) { PSPDebugTrace("initSize\n"); _screenWidth = width; _screenHeight = height; // _offscreen = (byte *)offscreen256; _overlayBuffer = (OverlayColor *)0x44000000 + PSP_FRAME_SIZE; - if(overlayScale == -1 || width == 640) - overlayScale = 1; - - _overlayScale = overlayScale; - _offscreen = (unsigned byte *)_overlayBuffer+_screenWidth*_screenHeight*_overlayScale*_overlayScale*sizeof(OverlayColor); + // FIXME: This is not needed anymore + _overlayScale = 1; + + _offscreen = (unsigned byte *)_overlayBuffer+_screenWidth*_screenHeight*sizeof(OverlayColor); bzero(_offscreen, width * height); - bzero(_overlayBuffer, width * overlayScale * height * overlayScale); + bzero(_overlayBuffer, width * height); _kbdClut[0] = 0xffff; _kbdClut[246] = 0x4ccc; _kbdClut[247] = 0x0000; diff --git a/backends/psp/osys_psp_gu.h b/backends/psp/osys_psp_gu.h index de3e4a3e65..b1445a520e 100644 --- a/backends/psp/osys_psp_gu.h +++ b/backends/psp/osys_psp_gu.h @@ -40,7 +40,7 @@ public: OSystem_PSP_GU(); ~OSystem_PSP_GU(); void updateScreen(); - void initSize(uint width, uint height, int overlayScale); + void initSize(uint width, uint height); int getDefaultGraphicsMode() const; bool setGraphicsMode(int mode); bool setGraphicsMode(const char *name); diff --git a/backends/sdl/events.cpp b/backends/sdl/events.cpp index ce4a3d53b7..3c296b8a45 100644 --- a/backends/sdl/events.cpp +++ b/backends/sdl/events.cpp @@ -76,14 +76,9 @@ void OSystem_SDL::fillMouseEvent(Event &event, int x, int y) { if (!_overlayVisible) { event.mouse.x /= _scaleFactor; event.mouse.y /= _scaleFactor; - } else { - event.mouse.x = event.mouse.x / _scaleFactor * _overlayScale; - event.mouse.y = event.mouse.y / _scaleFactor * _overlayScale; + if (_adjustAspectRatio) + event.mouse.y = aspect2Real(event.mouse.y); } - - // Optionally perform aspect ratio adjusting - if (_adjustAspectRatio) - event.mouse.y = aspect2Real(event.mouse.y); } void OSystem_SDL::handleKbdMouse() { diff --git a/backends/sdl/graphics.cpp b/backends/sdl/graphics.cpp index 8c40c26792..bf8396ca94 100644 --- a/backends/sdl/graphics.cpp +++ b/backends/sdl/graphics.cpp @@ -118,8 +118,7 @@ void OSystem_SDL::endGFXTransaction(void) { setGraphicsMode(_transactionDetails.mode); if (_transactionDetails.sizeChanged) - initSize(_transactionDetails.w, _transactionDetails.h, - _transactionDetails.overlayScale); + initSize(_transactionDetails.w, _transactionDetails.h); if (_transactionDetails.arChanged) setAspectRatioCorrection(_transactionDetails.ar); @@ -211,19 +210,6 @@ bool OSystem_SDL::setGraphicsMode(int mode) { _transactionDetails.normal1xScaler = (mode == GFX_NORMAL); -#ifndef DISABLE_SCALERS - // Do not let switch to lesser than overlay size resolutions - if (_screenWidth * newScaleFactor < _overlayWidth) { - if (_scaleFactor == 1) { // Force 2x mode - mode = GFX_DOUBLESIZE; - newScaleFactor = 2; - newScalerProc = Normal2x; - _scaleFactor = 2; - } else - return false; - } -#endif - _mode = mode; _scalerProc = newScalerProc; @@ -286,35 +272,24 @@ int OSystem_SDL::getGraphicsMode() const { return _mode; } -void OSystem_SDL::initSize(uint w, uint h, int overlayScale) { +void OSystem_SDL::initSize(uint w, uint h) { #ifdef DISABLE_SCALERS overlayScale = 1; #endif // Avoid redundant res changes if ((int)w == _screenWidth && (int)h == _screenHeight && - (int)overlayScale == _overlayScale && _transactionMode != kTransactionCommit) return; _screenWidth = w; _screenHeight = h; - if (overlayScale != -1) { - _overlayScale = overlayScale; - if (w != 320 && w != 256) // 256 is for MM NES - _overlayScale = 1; - - _overlayWidth = w * _overlayScale; - _overlayHeight = h * _overlayScale; - } - _cksumNum = (_screenWidth * _screenHeight / (8 * 8)); if (_transactionMode == kTransactionActive) { _transactionDetails.w = w; _transactionDetails.h = h; - _transactionDetails.overlayScale = _overlayScale; _transactionDetails.sizeChanged = true; _transactionDetails.needUnload = true; @@ -339,9 +314,15 @@ void OSystem_SDL::loadGFXMode() { _forceFull = true; _modeFlags |= DF_UPDATE_EXPAND_1_PIXEL; + _overlayWidth = _screenWidth * _scaleFactor; + _overlayHeight = _screenHeight * _scaleFactor; + if (_screenHeight != 200) _adjustAspectRatio = false; + if (_adjustAspectRatio) + _overlayHeight = real2Aspect(_overlayHeight); + // // Create the surface that contains the 8 bit game data // @@ -529,7 +510,7 @@ void OSystem_SDL::internUpdateScreen() { SDL_Surface *srcSurf, *origSurf; int height, width; ScalerProc *scalerProc; - int scale1, scale2; + int scale1; #if defined (DEBUG) && ! defined(_WIN32_WCE) // definitions not available for non-DEBUG here. (needed this to compile in SYMBIAN32 & linux?) assert(_hwscreen != NULL); @@ -540,7 +521,7 @@ void OSystem_SDL::internUpdateScreen() { if (_currentShakePos != _newShakePos) { SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor}; - if (_adjustAspectRatio) + if (_adjustAspectRatio && !_overlayVisible) blackrect.h = real2Aspect(blackrect.h - 1) + 1; SDL_FillRect(_hwscreen, &blackrect, 0); @@ -589,16 +570,14 @@ void OSystem_SDL::internUpdateScreen() { height = _screenHeight; scalerProc = _scalerProc; scale1 = _scaleFactor; - scale2 = 1; } else { origSurf = _overlayscreen; srcSurf = _tmpscreen2; width = _overlayWidth; height = _overlayHeight; - scalerProc = scalersMagn[_overlayScale - 1][_scaleFactor - 1]; + scalerProc = Normal1x; - scale1 = _scaleFactor; - scale2 = _overlayScale; + scale1 = 1; } // Force a full redraw if requested @@ -647,7 +626,7 @@ void OSystem_SDL::internUpdateScreen() { register int dst_y = r->y + _currentShakePos; register int dst_h = 0; register int orig_dst_y = 0; - register int rx1 = r->x * scale1 / scale2; + register int rx1 = r->x * scale1; if (dst_y < height) { dst_h = r->h; @@ -655,17 +634,11 @@ void OSystem_SDL::internUpdateScreen() { dst_h = height - dst_y; orig_dst_y = dst_y; - dst_y = dst_y * scale1 / scale2; + dst_y = dst_y * scale1; - if (_adjustAspectRatio) + if (_adjustAspectRatio && !_overlayVisible) dst_y = real2Aspect(dst_y); - if (scale1 == 3 && scale2 == 2 && _overlayVisible) { - if (r->y % 2) - r->y--; - dst_y -= dst_y % 3; - } - assert(scalerProc != NULL); scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch, (byte *)_hwscreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h); @@ -673,12 +646,12 @@ void OSystem_SDL::internUpdateScreen() { r->x = rx1; r->y = dst_y; - r->w = r->w * scale1 / scale2; - r->h = dst_h * scale1 / scale2; + r->w = r->w * scale1; + r->h = dst_h * scale1; #ifndef DISABLE_SCALERS - if (_adjustAspectRatio && orig_dst_y < height) - r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1 / scale2); + if (_adjustAspectRatio && orig_dst_y < height && !_overlayVisible) + r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1); #endif } SDL_UnlockSurface(srcSurf); @@ -943,12 +916,8 @@ void OSystem_SDL::addDirtyRect(int x, int y, int w, int h, bool mouseRect) { } #ifndef DISABLE_SCALERS - if (_adjustAspectRatio) { + if (_adjustAspectRatio && !_overlayVisible) { makeRectStretchable(x, y, w, h); - if (_scaleFactor == 3 && _overlayScale == 2 && _overlayVisible) { - if (y % 2) - y++; - } } #endif @@ -1126,8 +1095,8 @@ void OSystem_SDL::showOverlay() { // Since resolution could change, put mouse to adjusted position // Fixes bug #1349059 - x = _mouseCurState.x * _overlayScale; - y = _mouseCurState.y * _overlayScale; + x = _mouseCurState.x; + y = _mouseCurState.y; warpMouse(x, y); @@ -1146,8 +1115,8 @@ void OSystem_SDL::hideOverlay() { // Since resolution could change, put mouse to adjusted position // Fixes bug #1349059 - x = _mouseCurState.x / _overlayScale; - y = _mouseCurState.y / _overlayScale; + x = _mouseCurState.x; + y = _mouseCurState.y; warpMouse(x, y); @@ -1175,15 +1144,12 @@ void OSystem_SDL::clearOverlay() { SDL_LockSurface(_tmpscreen); SDL_LockSurface(_overlayscreen); - if (_overlayScale == _scaleFactor) { - _scalerProc((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2, - _tmpscreen->pitch, (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight); - } else { - // Quality is degraded here. It is possible to run one-less scaler here, but is it - // really needed? Quality will anyway be degraded because of 1.5x scaler. - (scalersMagn[0][_overlayScale - 1])((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2, - _tmpscreen->pitch, (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight); - } + _scalerProc((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2, _tmpscreen->pitch, + (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight); + + if (_adjustAspectRatio) + stretch200To240((uint8 *)_overlayscreen->pixels, _overlayscreen->pitch, + _overlayWidth, _screenHeight * _scaleFactor, 0, 0, 0); SDL_UnlockSurface(_tmpscreen); SDL_UnlockSurface(_overlayscreen); @@ -1287,14 +1253,13 @@ void OSystem_SDL::setMousePos(int x, int y) { } void OSystem_SDL::warpMouse(int x, int y) { + int y1 = y; + if (_adjustAspectRatio) - y = real2Aspect(y); + y1 = real2Aspect(y); if (_mouseCurState.x != x || _mouseCurState.y != y) { - if (_overlayVisible) - SDL_WarpMouse(x * _scaleFactor / _overlayScale, y * _scaleFactor / _overlayScale); - else - SDL_WarpMouse(x * _scaleFactor, y * _scaleFactor); + SDL_WarpMouse(x * _scaleFactor, y1 * _scaleFactor); // SDL_WarpMouse() generates a mouse movement event, so // setMousePos() would be called eventually. However, the @@ -1485,7 +1450,7 @@ void OSystem_SDL::toggleMouseGrab() { void OSystem_SDL::undrawMouse() { const int x = _mouseBackup.x; - const int y = _adjustAspectRatio ? aspect2Real(_mouseBackup.y) : _mouseBackup.y; + const int y = (_adjustAspectRatio && !_overlayVisible) ? aspect2Real(_mouseBackup.y) : _mouseBackup.y; // When we switch bigger overlay off mouse jumps. Argh! // This is intended to prevent undrawing offscreen mouse @@ -1493,9 +1458,8 @@ void OSystem_SDL::undrawMouse() { return; } - if (_mouseBackup.w != 0 && _mouseBackup.h != 0) { + if (_mouseBackup.w != 0 && _mouseBackup.h != 0) addDirtyRect(x, y, _mouseBackup.w, _mouseBackup.h); - } } void OSystem_SDL::drawMouse() { @@ -1503,106 +1467,73 @@ void OSystem_SDL::drawMouse() { _mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0; return; } - + SDL_Rect src, dst; - int scale1, scale2; + bool useCursorScaling; + int scale; int width, height; if (!_overlayVisible) { - scale1 = _scaleFactor; - scale2 = 1; + scale = _scaleFactor; width = _screenWidth; height = _screenHeight; } else { - scale1 = _scaleFactor; - scale2 = _overlayScale; + scale = 1; width = _overlayWidth; height = _overlayHeight; } - // Note: _mouseCurState is in *virtual* coordinates. That means if initSize - // was used to set a 320x200 game screen, then _mouseCurState is bounded - // by that; if the overlay is visible, then it is bounded by the overlay - // size (typically 640x400). - // - // _mouseBackup is stored in "virtual" coordinates, too. - // - // On the other hand, _mouseSurface was scaled to screen coordinates in - // OSystem_SDL::blitCursor(), including aspect ratio corection. Its - // scaling is determined by _scaleFactor, but *not* by whatever value - // _overlayScale has. - // Atop of that, it was scaled by _cursorTargetScale. - // That means, we have to scale it by "scale2". - // - // TODO/FIXME: Clean up and fix this code, see also bug #1185275. + useCursorScaling = (_scaleFactor > _cursorTargetScale); - const bool useScaling = (_scaleFactor > _cursorTargetScale); - - dst.x = _mouseCurState.x - _mouseHotspotX * scale2 / _cursorTargetScale; - dst.y = _mouseCurState.y - _mouseHotspotY * scale2 / _cursorTargetScale; + if (useCursorScaling) { + dst.x = _mouseCurState.x - _mouseHotspotX * scale / _cursorTargetScale; + dst.y = _mouseCurState.y - _mouseHotspotY * scale / _cursorTargetScale; + } else { + dst.x = _mouseCurState.x - _mouseHotspotX; + dst.y = _mouseCurState.y - _mouseHotspotY; + } dst.w = _mouseCurState.hW; dst.h = _mouseCurState.hH; src.x = src.y = 0; // clip the mouse rect, and adjust the src pointer accordingly + int dx, dy; + if (dst.x < 0) { - const int dx = useScaling ? dst.x * scale1 / scale2 / _cursorTargetScale : dst.x; + dx = useCursorScaling ? dst.x * scale / _cursorTargetScale : dst.x; dst.w += dx; src.x -= dx; dst.x = 0; } if (dst.y < 0) { - const int dy = useScaling ? dst.y * scale1 / scale2 / _cursorTargetScale : dst.y; + dy = useCursorScaling ? dst.y * scale / _cursorTargetScale : dst.y; dst.h += dy; src.y -= dy; dst.y = 0; } // Quick check to see if anything has to be drawn at all - if (dst.w <= 0 || dst.h <= 0 || dst.x >= width || dst.y >= height) + if (dst.w <= 0 || dst.h <= 0) return; - + src.w = dst.w; src.h = dst.h; - - // Patch #1258912 "GUI: SDL mouse dirty rects too big" - // - // At this point, dst.w and dst.h appear to be the correct values to - // assign to src.w and src.h above, but they are NOT the actual - // width and height of the mouse in virtual coordinates required for - // the dirty rects. If left uncorrected, the w and h values are 1.5x - // too large for 3x scalers when the overlay is visible, and 2x/3x too - // large for 2x/3x scalers when the overlay is not visible, resulting - // in dirty rects that are from 2.25x to 9x too large depending on the - // combination of scales. - if (!_overlayVisible) { - dst.w = _mouseCurState.w; - dst.h = _mouseCurState.h; - } else { - dst.w = _mouseCurState.w * _overlayScale; - dst.h = _mouseCurState.h * _overlayScale; - } - - if (_adjustAspectRatio) + + if (_adjustAspectRatio && !_overlayVisible) dst.y = real2Aspect(dst.y); - - // special case for 1o5x scaler to prevent backgound shaking - if (scale1 == 3 && scale2 == 2) { - if (dst.x % 2) - dst.x--; - if (dst.y % 2) - dst.y--; - } - - _mouseBackup = dst; - - dst.x = dst.x * scale1 / scale2; - dst.y = (dst.y + _currentShakePos) * scale1 / scale2; + + _mouseBackup.x = dst.x; + _mouseBackup.y = dst.y; + _mouseBackup.w = dst.w; + _mouseBackup.h = dst.h; + + dst.x *= scale; + dst.y *= scale; if (SDL_BlitSurface(_mouseSurface, &src, _hwscreen, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); - + addDirtyRect(dst.x, dst.y, dst.w, dst.h, true); } diff --git a/backends/sdl/sdl-common.h b/backends/sdl/sdl-common.h index c7d19281a7..dfa255b293 100644 --- a/backends/sdl/sdl-common.h +++ b/backends/sdl/sdl-common.h @@ -66,7 +66,7 @@ public: // Set the size of the video bitmap. // Typically, 320x200 - virtual void initSize(uint w, uint h, int overlayScale); // overloaded by CE backend + virtual void initSize(uint w, uint h); // overloaded by CE backend // Set colors of the palette void setPalette(const byte *colors, uint start, uint num); @@ -158,10 +158,6 @@ public: virtual int16 getWidth(); virtual int16 getOverlayHeight() { return _overlayHeight; } virtual int16 getOverlayWidth() { return _overlayWidth; } - virtual int screenToOverlayX(int x) { return x * _overlayScale; } - virtual int screenToOverlayY(int y) { return y * _overlayScale; } - virtual int overlayToScreenX(int x) { return x / _overlayScale; } - virtual int overlayToScreenY(int y) { return y / _overlayScale; } // Methods that convert RGB to/from colors suitable for the overlay. virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b); @@ -214,7 +210,6 @@ protected: // overlay SDL_Surface *_overlayscreen; int _overlayWidth, _overlayHeight; - int _overlayScale; bool _overlayVisible; // Audio @@ -241,7 +236,6 @@ protected: bool modeChanged; int w; int h; - int overlayScale; bool sizeChanged; bool fs; bool fsChanged; diff --git a/backends/sdl/sdl.cpp b/backends/sdl/sdl.cpp index cff313cea4..3c82765c1b 100644 --- a/backends/sdl/sdl.cpp +++ b/backends/sdl/sdl.cpp @@ -175,7 +175,7 @@ OSystem_SDL::OSystem_SDL() #endif _hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0), _tmpscreen(0), _overlayWidth(0), _overlayHeight(0), - _overlayVisible(false), _overlayScale(1), + _overlayVisible(false), _overlayscreen(0), _tmpscreen2(0), _samplesPerSec(0), _cdrom(0), _scalerProc(0), _modeChanged(false), _dirtyChecksums(0), diff --git a/backends/wince/wince-sdl.cpp b/backends/wince/wince-sdl.cpp index 1f877e77ba..8427da1882 100644 --- a/backends/wince/wince-sdl.cpp +++ b/backends/wince/wince-sdl.cpp @@ -756,7 +756,7 @@ void OSystem_WINCE3::update_game_settings() { get_sample_rate(); } -void OSystem_WINCE3::initSize(uint w, uint h, int overlayScale) { +void OSystem_WINCE3::initSize(uint w, uint h) { if (_hasSmartphoneResolution && h == 240) h = 200; // mainly for the launcher @@ -765,7 +765,6 @@ void OSystem_WINCE3::initSize(uint w, uint h, int overlayScale) { case kTransactionActive: _transactionDetails.w = w; _transactionDetails.h = h; - _transactionDetails.overlayScale = overlayScale; _transactionDetails.sizeChanged = true; _transactionDetails.needUnload = true; return; @@ -789,8 +788,7 @@ void OSystem_WINCE3::initSize(uint w, uint h, int overlayScale) { if (w != _screenWidth || h != _screenHeight) _scalersChanged = false; - //OSystem_SDL::initSize(w, h, overlayScale); - OSystem_SDL::initSize(w, h, 1); + OSystem_SDL::initSize(w, h); if (_scalersChanged) { unloadGFXMode(); diff --git a/backends/wince/wince-sdl.h b/backends/wince/wince-sdl.h index 238cc527a0..363f0ba515 100644 --- a/backends/wince/wince-sdl.h +++ b/backends/wince/wince-sdl.h @@ -48,7 +48,7 @@ public: // Update the dirty areas of the screen void internUpdateScreen(); - void initSize(uint w, uint h, int overlaySize); + void initSize(uint w, uint h); // Overloaded from SDL_Common (toolbar handling) bool pollEvent(Event &event); diff --git a/backends/x11/x11.cpp b/backends/x11/x11.cpp index e356bcc83d..915316a682 100644 --- a/backends/x11/x11.cpp +++ b/backends/x11/x11.cpp @@ -340,8 +340,8 @@ uint32 OSystem_X11::getMillis() { ((current_time.tv_usec - _start_time.tv_usec) / 1000)); } -void OSystem_X11::initSize(uint w, uint h, int overlaySize) { - //debug("initSize(%i, %i, %i)", w, h, overlaySize); +void OSystem_X11::initSize(uint w, uint h) { + //debug("initSize(%i, %i)", w, h); static XShmSegmentInfo shminfo; if (((uint)_fb_width != w) || ((uint)_fb_height != w)) { diff --git a/backends/x11/x11.h b/backends/x11/x11.h index 36085ccc00..ba29bc7eab 100644 --- a/backends/x11/x11.h +++ b/backends/x11/x11.h @@ -54,7 +54,7 @@ public: // Set the size of the video bitmap. // Typically, 320x200 - void initSize(uint w, uint h, int overlaySize); + void initSize(uint w, uint h); // Draw a bitmap to screen. // The screen will not be updated to reflect the new bitmap diff --git a/base/engine.cpp b/base/engine.cpp index ecc0f6dbf2..fcf0e7f513 100644 --- a/base/engine.cpp +++ b/base/engine.cpp @@ -253,7 +253,7 @@ void Engine::GUIErrorMessage(const Common::String msg) { _system->setWindowCaption("Error"); _system->beginGFXTransaction(); initCommonGFX(false); - _system->initSize(320, 200, 2); + _system->initSize(320, 200); _system->endGFXTransaction(); GUI::MessageDialog dialog(msg); diff --git a/base/main.cpp b/base/main.cpp index 683431b3c1..739d54a255 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -123,7 +123,7 @@ static bool launcherDialog(OSystem &system) { system.setGraphicsMode(ConfMan.get("gfx_mode").c_str()); // Make GUI 640 x 400 - system.initSize(320, 200, (ConfMan.getBool("force_1x_overlay") ? 1 : 2)); + system.initSize(320, 200); system.endGFXTransaction(); diff --git a/common/system.h b/common/system.h index 99a0d112fd..f5b8d334f1 100644 --- a/common/system.h +++ b/common/system.h @@ -306,11 +306,8 @@ public: * * @param width the new virtual screen width * @param height the new virtual screen height - * @param overlayScale optional: the scale to be used for the overlay, if different - * from the default scale (default is -1, which means the - * overlay uses the same scale) */ - virtual void initSize(uint width, uint height, int overlayScale = -1) = 0; + virtual void initSize(uint width, uint height) = 0; /** * Begin a new GFX transaction, which is a sequence of GFX mode changes. diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 7488bfb7b9..0c79a0b109 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -951,7 +951,7 @@ int ScummEngine::init() { _system->beginGFXTransaction(); bool defaultTo1XScaler = false; if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { - _system->initSize(Common::kHercW, Common::kHercH, 1); + _system->initSize(Common::kHercW, Common::kHercH); defaultTo1XScaler = true; } else { // FIXME: The way we now handle the force_1x_overlay setting implies @@ -959,7 +959,7 @@ int ScummEngine::init() { // set to true, it'll get reset to the default value (usually 'false' // except for Symbian) before launching a game. // This may or may not be the desired behavior... - _system->initSize(_screenWidth, _screenHeight, (ConfMan.getBool("force_1x_overlay") ? 1 : 2)); + _system->initSize(_screenWidth, _screenHeight); defaultTo1XScaler = (_screenWidth > 320); } initCommonGFX(defaultTo1XScaler); diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp index ff21d99de4..9d0fbb7788 100644 --- a/engines/sword1/animation.cpp +++ b/engines/sword1/animation.cpp @@ -48,6 +48,9 @@ void AnimationState::setPalette(byte *pal) { #endif void AnimationState::drawYUV(int width, int height, byte *const *dat) { + _frameWidth = width; + _frameHeight = height; + #ifdef BACKEND_8BIT _scr->plotYUV(_lut, width, height, dat); #else @@ -57,7 +60,13 @@ void AnimationState::drawYUV(int width, int height, byte *const *dat) { void AnimationState::updateScreen(void) { #ifndef BACKEND_8BIT - _sys->copyRectToOverlay(_overlay, _movieWidth, 0, 40, _movieWidth, _movieHeight); + int width = _movieScale * _frameWidth; + int height = _movieScale * _frameHeight; + int pitch = _movieScale * _movieWidth; + int x = _movieScale * ((_movieWidth - _frameWidth) / 2); + int y = _movieScale * ((_movieHeight - _frameHeight) / 2); + + _sys->copyRectToOverlay(_overlay + y * pitch + x, pitch, x, y + _movieScale * 40, width, height); #endif _sys->updateScreen(); } diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h index 378116fe6a..6e1fa11c3d 100644 --- a/engines/sword1/animation.h +++ b/engines/sword1/animation.h @@ -61,6 +61,9 @@ class AnimationState : public Graphics::BaseAnimationState { private: Screen *_scr; + int _frameWidth; + int _frameHeight; + public: AnimationState(Screen *scr, Audio::Mixer *snd, OSystem *sys); ~AnimationState(); diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp index c40f69acad..e8d17e88b0 100644 --- a/engines/sword2/animation.cpp +++ b/engines/sword2/animation.cpp @@ -53,27 +53,47 @@ void AnimationState::setPalette(byte *pal) { #else void AnimationState::drawTextObject(SpriteInfo *s, byte *src) { - OverlayColor *dst = _overlay + RENDERWIDE * s->y + s->x; - - // FIXME: These aren't the "right" colours, but look good to me. + OverlayColor *dst = _overlay + _movieScale * _movieWidth * _movieScale * s->y + _movieScale * s->x; OverlayColor pen = _sys->RGBToColor(255, 255, 255); OverlayColor border = _sys->RGBToColor(0, 0, 0); + // TODO: Use the AdvMame scalers for the text? Pre-scale it? + for (int y = 0; y < s->h; y++) { + OverlayColor *ptr = dst; + for (int x = 0; x < s->w; x++) { switch (src[x]) { case 1: - dst[x] = border; + *ptr++ = border; + if (_movieScale > 1) { + *ptr++ = border; + if (_movieScale > 2) + *ptr++ = border; + } break; case 255: - dst[x] = pen; + *ptr++ = pen; + if (_movieScale > 1) { + *ptr++ = pen; + if (_movieScale > 2) + *ptr++ = pen; + } break; default: + ptr += _movieScale; break; } } - dst += RENDERWIDE; + + if (_movieScale > 1) { + memcpy(dst + _movieScale * _movieWidth, dst, _movieScale * s->w * sizeof(OverlayColor)); + if (_movieScale > 2) + memcpy(dst + 2 * _movieScale * _movieWidth, dst, _movieScale * s->w * sizeof(OverlayColor)); + } + + dst += _movieScale * _movieScale * _movieWidth; src += s->w; } } @@ -81,28 +101,46 @@ void AnimationState::drawTextObject(SpriteInfo *s, byte *src) { #endif void AnimationState::clearScreen() { + _frameWidth = _movieWidth; + _frameHeight = _movieHeight; + #ifdef BACKEND_8BIT memset(_vm->_screen->getScreen(), 0, _movieWidth * _movieHeight); #else OverlayColor black = _sys->RGBToColor(0, 0, 0); - for (int i = 0; i < _movieWidth * _movieHeight; i++) + for (int i = 0; i < _movieScale * _movieWidth * _movieScale * _movieHeight; i++) _overlay[i] = black; #endif } void AnimationState::updateScreen() { + int x, y; + + x = (_movieWidth - _frameWidth) / 2; + y = (_movieHeight - _frameHeight) / 2; + #ifdef BACKEND_8BIT - byte *buf = _vm->_screen->getScreen() + ((480 - _movieHeight) / 2) * RENDERWIDE + (640 - _movieWidth) / 2; + byte *buf = _vm->_screen->getScreen() + y * RENDERWIDE + x; _vm->_system->copyRectToScreen(buf, _movieWidth, (640 - _movieWidth) / 2, (480 - _movieHeight) / 2, _movieWidth, _movieHeight); #else - _sys->copyRectToOverlay(_overlay, _movieWidth, 0, 0, _movieWidth, _movieHeight); + int width = _movieScale * _frameWidth; + int height = _movieScale * _frameHeight; + int pitch = _movieScale * _movieWidth; + + x *= _movieScale; + y *= _movieScale; + + _sys->copyRectToOverlay(_overlay + y * pitch + x, pitch, x, y, width, height); #endif _vm->_system->updateScreen(); } void AnimationState::drawYUV(int width, int height, byte *const *dat) { + _frameWidth = width; + _frameHeight = height; + #ifdef BACKEND_8BIT _vm->_screen->plotYUV(_lut, width, height, dat); #else diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h index ef3ea67d02..960721b8a1 100644 --- a/engines/sword2/animation.h +++ b/engines/sword2/animation.h @@ -45,6 +45,9 @@ class AnimationState : public ::Graphics::BaseAnimationState { private: Sword2Engine *_vm; + int _frameWidth; + int _frameHeight; + public: AnimationState(Sword2Engine *vm); ~AnimationState(); diff --git a/graphics/animation.cpp b/graphics/animation.cpp index c1fb87f5b9..731fe595e7 100644 --- a/graphics/animation.cpp +++ b/graphics/animation.cpp @@ -34,6 +34,15 @@ namespace Graphics { BaseAnimationState::BaseAnimationState(Audio::Mixer *snd, OSystem *sys, int width, int height) : _movieWidth(width), _movieHeight(height), _snd(snd), _sys(sys) { #ifndef BACKEND_8BIT + const int screenW = _sys->getOverlayWidth(); + const int screenH = _sys->getOverlayHeight(); + + _movieScale = MIN(screenW / _movieWidth, screenH / _movieHeight); + + assert (_movieScale >= 1); + if (_movieScale > 3) + _movieScale = 3; + _colorTab = NULL; _rgbToPix = NULL; _bitFormat = 0; @@ -116,7 +125,7 @@ bool BaseAnimationState::init(const char *name, void *audioArg) { _lutCalcNum = (BITDEPTH + _palettes[_palNum].end + 2) / (_palettes[_palNum].end + 2); #else buildLookup(); - _overlay = (OverlayColor*)calloc(_movieWidth * _movieHeight, sizeof(OverlayColor)); + _overlay = (OverlayColor*)calloc(_movieScale * _movieWidth * _movieScale * _movieHeight, sizeof(OverlayColor)); _sys->showOverlay(); #endif @@ -422,7 +431,21 @@ void BaseAnimationState::buildLookup() { } void BaseAnimationState::plotYUV(int width, int height, byte *const *dat) { - OverlayColor *ptr = _overlay + (_movieHeight - height) / 2 * _movieWidth + (_movieWidth - width) / 2; + switch (_movieScale) { + case 1: + plotYUV1x(width, height, dat); + break; + case 2: + plotYUV2x(width, height, dat); + break; + case 3: + plotYUV3x(width, height, dat); + break; + } +} + +void BaseAnimationState::plotYUV1x(int width, int height, byte *const *dat) { + OverlayColor *ptr = _overlay + _movieWidth * (_movieHeight - height) / 2 + (_movieWidth - width) / 2; byte *lum = dat[0]; byte *cr = dat[2]; @@ -440,6 +463,9 @@ void BaseAnimationState::plotYUV(int width, int height, byte *const *dat) { int x, y; for (y = 0; y < height; y += 2) { + OverlayColor *r1 = row1; + OverlayColor *r2 = row2; + for (x = 0; x < width; x += 2) { register byte L; @@ -450,26 +476,160 @@ void BaseAnimationState::plotYUV(int width, int height, byte *const *dat) { ++cb; L = *lum++; - *row1++ = (_rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]); + *r1++ = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = *lum++; - *row1++ = (_rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]); + *r1++ = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + + // Now, do second row. + + L = *lum2++; + *r2++ = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + + L = *lum2++; + *r2++ = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + } + + lum += width; + lum2 += width; + row1 += 2 * _movieWidth; + row2 += 2 * _movieWidth; + } +} + +void BaseAnimationState::plotYUV2x(int width, int height, byte *const *dat) { + OverlayColor *ptr = _overlay + 2 * _movieWidth * (_movieHeight - height) + _movieWidth - width; + + byte *lum = dat[0]; + byte *cr = dat[2]; + byte *cb = dat[1]; + + byte *lum2 = lum + width; + + int16 cr_r; + int16 crb_g; + int16 cb_b; + + OverlayColor *row1 = ptr; + OverlayColor *row2 = ptr + 2 * 2 * _movieWidth; + int x, y; + + for (y = 0; y < height; y += 2) { + OverlayColor *r1 = row1; + OverlayColor *r2 = row2; + + for (x = 0; x < width; x += 2) { + register byte L; + register OverlayColor C; + + cr_r = 0 * 768 + 256 + _colorTab[*cr + 0 * 256]; + crb_g = 1 * 768 + 256 + _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256]; + cb_b = 2 * 768 + 256 + _colorTab[*cb + 3 * 256]; + ++cr; + ++cb; + + L = *lum++; + C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + *r1++ = C; + *r1++ = C; + + L = *lum++; + C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + *r1++ = C; + *r1++ = C; + // Now, do second row. L = *lum2++; - *row2++ = (_rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]); + C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + *r2++ = C; + *r2++ = C; + + L = *lum2++; + C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + *r2++ = C; + *r2++ = C; + } + + memcpy(row1 + 2 * _movieWidth, row1, 2 * _movieWidth * sizeof(OverlayColor)); + memcpy(row2 + 2 * _movieWidth, row2, 2 * _movieWidth * sizeof(OverlayColor)); + + lum += width; + lum2 += width; + row1 += 4 * 2 * _movieWidth; + row2 += 4 * 2 * _movieWidth; + } +} + +void BaseAnimationState::plotYUV3x(int width, int height, byte *const *dat) { + OverlayColor *ptr = _overlay + (3 * (_movieHeight - height) / 2) * 3 * _movieWidth + 3 * (_movieWidth - width ) / 2; + + byte *lum = dat[0]; + byte *cr = dat[2]; + byte *cb = dat[1]; + + byte *lum2 = lum + width; + + int16 cr_r; + int16 crb_g; + int16 cb_b; + + OverlayColor *row1 = ptr; + OverlayColor *row2 = ptr + 3 * 3 * _movieWidth; + + int x, y; + + for (y = 0; y < height; y += 2) { + OverlayColor *r1 = row1; + OverlayColor *r2 = row2; + + for (x = 0; x < width; x += 2) { + register byte L; + register OverlayColor C; + + cr_r = 0 * 768 + 256 + _colorTab[*cr + 0 * 256]; + crb_g = 1 * 768 + 256 + _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256]; + cb_b = 2 * 768 + 256 + _colorTab[*cb + 3 * 256]; + ++cr; + ++cb; + + L = *lum++; + C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + *r1++ = C; + *r1++ = C; + *r1++ = C; + + L = *lum++; + C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + *r1++ = C; + *r1++ = C; + *r1++ = C; + + // Now, do second row. + + L = *lum2++; + C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + *r2++ = C; + *r2++ = C; + *r2++ = C; + L = *lum2++; - *row2++ = (_rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]); + C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + *r2++ = C; + *r2++ = C; + *r2++ = C; } - // These values are at the start of the next line, (due - // to the ++'s above), but they need to be at the start - // of the line after that. + memcpy(row1 + 3 * _movieWidth, row1, 3 * _movieWidth * sizeof(OverlayColor)); + memcpy(row1 + 2 * 3 * _movieWidth, row1, 3 * _movieWidth * sizeof(OverlayColor)); + memcpy(row2 + 3 * _movieWidth, row2, 3 * _movieWidth * sizeof(OverlayColor)); + memcpy(row2 + 2 * 3 * _movieWidth, row2, 3 * _movieWidth * sizeof(OverlayColor)); lum += width; lum2 += width; - row1 += (2 * _movieWidth - width); - row2 += (2 * _movieWidth - width); + row1 += 6 * 3 * _movieWidth; + row2 += 6 * 3 * _movieWidth; } } diff --git a/graphics/animation.h b/graphics/animation.h index 9b7f49352c..42c1c899f3 100644 --- a/graphics/animation.h +++ b/graphics/animation.h @@ -78,6 +78,10 @@ protected: const int _movieWidth; const int _movieHeight; +#ifndef BACKEND_8BIT + int _movieScale; +#endif + Audio::Mixer *_snd; OSystem *_sys; @@ -141,6 +145,9 @@ protected: virtual void setPalette(byte *pal) = 0; #else void plotYUV(int width, int height, byte *const *dat); + void plotYUV1x(int width, int height, byte *const *dat); + void plotYUV2x(int width, int height, byte *const *dat); + void plotYUV3x(int width, int height, byte *const *dat); #endif }; |