Ticket #8792: float-scaler-fixed.patch

File float-scaler-fixed.patch, 12.5 KB (added by SF/ignazb, 16 years ago)
  • common/scummsys.h

     
    441441        typedef unsigned short uint16;
    442442        typedef signed short int16;
    443443
     444
    444445        #ifdef SCUMMVM_USE_LONG_INT
    445446        typedef unsigned long uint32;
    446447        typedef signed long int32;
     
    453454#endif
    454455
    455456
     457#ifndef DISABLE_FLOAT_SCALER
     458        typedef float scale_t;
     459#else
     460        typedef int scale_t;
     461#endif
    456462
    457463//
    458464// Overlay color type (FIXME: shouldn't be declared here)
  • graphics/scaler.cpp

     
    320320        }
    321321}
    322322
     323#ifndef DISABLE_FLOAT_SCALER
     324
     325float gScale;
     326void UserScaler(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
     327                                int width, int height) {
     328       
     329        float scale = gScale;
     330        if (scale <= 0.0f || scale > 3.0f)
     331                scale = 1.0f;
     332
     333        for (int y = 0; y < height; y++) {
     334                for (int x = 0; x < width; x++) {
     335                        int xMin, yMin;
     336                        uint16 pixel = *((uint16 *)(srcPtr + srcPitch * y) + x);
     337                        // calculate the point where this pixel would be on a scalar coordinate system
     338                        xMin = x * scale;
     339                        yMin = y * scale;
     340
     341#define DESTOF(a, b, c) do { *(uint16 *)((dstPtr + (dstPitch * (b)) + (a)*2)) = pixel; } while (0)
     342                        DESTOF(xMin, yMin, pixel);
     343                        if (scale > 1.0) {
     344                                DESTOF(xMin + 1, yMin, pixel);
     345                                DESTOF(xMin, yMin + 1, pixel);
     346                                DESTOF(xMin + 1, yMin + 1, pixel);
     347                                if (scale > 2.0 && x < width - 1 && y < height - 1) {
     348                                        DESTOF(xMin + 2, yMin, pixel);
     349                                        DESTOF(xMin + 2, yMin + 1, pixel);
     350                                        DESTOF(xMin + 2, yMin + 2, pixel);
     351                                        DESTOF(xMin + 1, yMin + 2, pixel);
     352                                        DESTOF(xMin, yMin + 2, pixel);
     353                                }
     354                        }
     355                }
     356        }
     357}
     358#endif // DISABLE_FLOAT_SCALER
     359
    323360#endif
  • graphics/scaler.h

     
    4848DECLARE_SCALER(Normal1o5x);
    4949DECLARE_SCALER(TV2x);
    5050DECLARE_SCALER(DotMatrix);
     51DECLARE_SCALER(UserScaler);
    5152
    5253#ifndef DISABLE_HQ_SCALERS
    5354DECLARE_SCALER(HQ2x);
  • backends/platform/sdl/graphics.cpp

     
    3030#include "graphics/scaler.h"
    3131#include "graphics/surface.h"
    3232
     33#ifndef DISABLE_FLOAT_SCALER
     34#include "common/config-manager.h"
     35#include "common/singleton.h"
     36extern float gScale; // from scaler.cpp
     37#endif
     38
    3339static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
    3440        {"1x", "Normal (no scaling)", GFX_NORMAL},
    3541        {"2x", "2x", GFX_DOUBLESIZE},
     
    4551#endif
    4652        {"tv2x", "TV2x", GFX_TV2X},
    4753        {"dotmatrix", "DotMatrix", GFX_DOTMATRIX},
     54        {"user", "User defined float scaling", GFX_FLOAT},
    4855        {0, 0, 0}
    4956};
    5057
     
    7077                { GFX_NORMAL, GFX_SUPER2XSAI, -1, -1 },
    7178                { GFX_NORMAL, GFX_SUPEREAGLE, -1, -1 },
    7279                { GFX_NORMAL, GFX_TV2X, -1, -1 },
    73                 { GFX_NORMAL, GFX_DOTMATRIX, -1, -1 }
     80                { GFX_NORMAL, GFX_DOTMATRIX, -1, -1 },
     81                { GFX_NORMAL, GFX_FLOAT, -1, -1 }
    7482        };
    7583
    7684#ifndef DISABLE_SCALERS
     
    147155bool OSystem_SDL::setGraphicsMode(int mode) {
    148156        Common::StackLock lock(_graphicsMutex);
    149157
    150         int newScaleFactor = 1;
     158        scale_t newScaleFactor = 1;
    151159        ScalerProc *newScalerProc;
     160#ifndef DISABLE_FLOAT_SCALER
     161        float f;
     162        Common::String s;
     163#endif
    152164
    153165        switch(mode) {
    154166        case GFX_NORMAL:
     
    203215                newScaleFactor = 2;
    204216                newScalerProc = DotMatrix;
    205217                break;
     218#ifndef DISABLE_FLOAT_SCALER
     219        case GFX_FLOAT:
     220                s = Common::Singleton<Common::ConfigManager>::instance().get("gfx_scale");
     221                f = atof(s.c_str());
     222                if (f > 0.0f && f <= 3.0f) {
     223                        newScaleFactor = f;
     224                        gScale = f;
     225                } else {
     226                        newScaleFactor = 1.0f;
     227                        gScale = 1.0f;
     228                }
     229                newScalerProc = UserScaler;
     230                break;
     231#endif // DISABLE_FLOAT_SCALER
    206232#endif // DISABLE_SCALERS
    207233
    208234        default:
     
    314340        int hwW, hwH;
    315341
    316342#ifndef __MAEMO__
    317         _overlayWidth = _screenWidth * _scaleFactor;
    318         _overlayHeight = _screenHeight * _scaleFactor;
     343        _overlayWidth = (int)(_screenWidth * _scaleFactor);
     344        _overlayHeight = (int)(_screenHeight * _scaleFactor);
    319345
    320346        if (_screenHeight != 200 && _screenHeight != 400)
    321347                _adjustAspectRatio = false;
     
    323349        if (_adjustAspectRatio)
    324350                _overlayHeight = real2Aspect(_overlayHeight);
    325351
    326         hwW = _screenWidth * _scaleFactor;
     352        hwW = (int)(_screenWidth * _scaleFactor);
    327353        hwH = effectiveScreenHeight();
    328354#else
    329355        hwW = _overlayWidth;
     
    421447#endif
    422448
    423449        // keyboard cursor control, some other better place for it?
    424         _km.x_max = _screenWidth * _scaleFactor - 1;
     450        _km.x_max = (int)(_screenWidth * _scaleFactor - 1);
    425451        _km.y_max = effectiveScreenHeight() - 1;
    426452        _km.delay_time = 25;
    427453        _km.last_time = 0;
     
    517543        SDL_Surface *srcSurf, *origSurf;
    518544        int height, width;
    519545        ScalerProc *scalerProc;
    520         int scale1;
     546        scale_t scale1;
    521547
    522548#if defined (DEBUG) && ! defined(_WIN32_WCE) // definitions not available for non-DEBUG here. (needed this to compile in SYMBIAN32 & linux?)
    523549        assert(_hwscreen != NULL);
     
    526552
    527553        // If the shake position changed, fill the dirty area with blackness
    528554        if (_currentShakePos != _newShakePos) {
    529                 SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor};
     555                SDL_Rect blackrect = {0, 0, (int)(_screenWidth * _scaleFactor), (int)(_newShakePos * _scaleFactor)};
    530556
    531557                if (_adjustAspectRatio && !_overlayVisible)
    532558                        blackrect.h = real2Aspect(blackrect.h - 1) + 1;
     
    624650                        register int dst_y = r->y + _currentShakePos;
    625651                        register int dst_h = 0;
    626652                        register int orig_dst_y = 0;
    627                         register int rx1 = r->x * scale1;
     653                        register int rx1 = (int)(r->x * scale1);
    628654
    629655                        if (dst_y < height) {
    630656                                dst_h = r->h;
     
    632658                                        dst_h = height - dst_y;
    633659
    634660                                orig_dst_y = dst_y;
    635                                 dst_y = dst_y * scale1;
     661                                dst_y = (int)(dst_y * scale1);
    636662
    637663                                if (_adjustAspectRatio && !_overlayVisible)
    638664                                        dst_y = real2Aspect(dst_y);
     
    644670
    645671                        r->x = rx1;
    646672                        r->y = dst_y;
    647                         r->w = r->w * scale1;
    648                         r->h = dst_h * scale1;
     673                        r->w = (int)(r->w * scale1);
     674                        r->h = (int)(dst_h * scale1);
    649675
    650676#ifndef DISABLE_SCALERS
    651677                        if (_adjustAspectRatio && orig_dst_y < height && !_overlayVisible)
    652                                 r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
     678                                r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, (int)(orig_dst_y * scale1));
    653679#endif
    654680                }
    655681                SDL_UnlockSurface(srcSurf);
     
    10931119
    10941120        // Since resolution could change, put mouse to adjusted position
    10951121        // Fixes bug #1349059
    1096         x = _mouseCurState.x * _scaleFactor;
     1122        x = (int)(_mouseCurState.x * _scaleFactor);
    10971123        if (_adjustAspectRatio)
    1098                 y = real2Aspect(_mouseCurState.y) * _scaleFactor;
     1124                y = (int)(real2Aspect(_mouseCurState.y) * _scaleFactor);
    10991125        else
    1100                 y = _mouseCurState.y * _scaleFactor;
     1126                y = (int)(_mouseCurState.y * _scaleFactor);
    11011127
    11021128        warpMouse(x, y);
    11031129
     
    11161142
    11171143        // Since resolution could change, put mouse to adjusted position
    11181144        // Fixes bug #1349059
    1119         x = _mouseCurState.x / _scaleFactor;
    1120         y = _mouseCurState.y / _scaleFactor;
     1145        x = (int)(_mouseCurState.x / _scaleFactor);
     1146        y = (int)(_mouseCurState.y / _scaleFactor);
    11211147        if (_adjustAspectRatio)
    11221148                y = aspect2Real(y);
    11231149
     
    11531179#ifndef DISABLE_SCALERS
    11541180        if (_adjustAspectRatio)
    11551181                stretch200To240((uint8 *)_overlayscreen->pixels, _overlayscreen->pitch,
    1156                                                 _overlayWidth, _screenHeight * _scaleFactor, 0, 0, 0);
     1182                                                _overlayWidth, (int)(_screenHeight * _scaleFactor), 0, 0, 0);
    11571183#endif
    11581184        SDL_UnlockSurface(_tmpscreen);
    11591185        SDL_UnlockSurface(_overlayscreen);
     
    12651291
    12661292        if (_mouseCurState.x != x || _mouseCurState.y != y) {
    12671293                if (!_overlayVisible)
    1268                         SDL_WarpMouse(x * _scaleFactor, y1 * _scaleFactor);
     1294                        SDL_WarpMouse((int)(x * _scaleFactor), (int)(y1 * _scaleFactor));
    12691295                else
    12701296                        SDL_WarpMouse(x, y1);
    12711297
     
    13811407
    13821408                // The virtual dimensions may be larger than the original.
    13831409
    1384                 _mouseCurState.vW = w * _cursorTargetScale / _scaleFactor;
    1385                 _mouseCurState.vH = h * _cursorTargetScale / _scaleFactor;
    1386                 _mouseCurState.vHotX = _mouseCurState.hotX * _cursorTargetScale /
    1387                         _scaleFactor;
    1388                 _mouseCurState.vHotY = _mouseCurState.hotY * _cursorTargetScale /
    1389                         _scaleFactor;
     1410                _mouseCurState.vW = (int)(w * _cursorTargetScale / _scaleFactor);
     1411                _mouseCurState.vH = (int)(h * _cursorTargetScale / _scaleFactor);
     1412                _mouseCurState.vHotX = (int)(_mouseCurState.hotX * _cursorTargetScale /
     1413                        _scaleFactor);
     1414                _mouseCurState.vHotY = (int)(_mouseCurState.hotY * _cursorTargetScale /
     1415                        _scaleFactor);
    13901416        } else {
    13911417                // The cursor target scale is smaller than the scale at which
    13921418                // the rest of the screen is drawn. We scale up the cursor
    13931419                // image to make it appear correct.
    13941420
    1395                 rW = w * _scaleFactor / _cursorTargetScale;
    1396                 rH = h * _scaleFactor / _cursorTargetScale;
    1397                 _mouseCurState.rHotX = _mouseCurState.hotX * _scaleFactor /
    1398                         _cursorTargetScale;
    1399                 _mouseCurState.rHotY = _mouseCurState.hotY * _scaleFactor /
    1400                         _cursorTargetScale;
     1421                rW = (int)(w * _scaleFactor / _cursorTargetScale);
     1422                rH = (int)(h * _scaleFactor / _cursorTargetScale);
     1423                _mouseCurState.rHotX = (int)(_mouseCurState.hotX * _scaleFactor /
     1424                        _cursorTargetScale);
     1425                _mouseCurState.rHotY = (int)(_mouseCurState.hotY * _scaleFactor /
     1426                        _cursorTargetScale);
    14011427
    14021428                // The virtual dimensions will be the same as the original.
    14031429
     
    14461472        // the game. This only works well with the non-blurring scalers so we
    14471473        // actually only use the 1x, 1.5x, 2x and AdvMame scalers.
    14481474
    1449         if (_cursorTargetScale == 1 && (_mode == GFX_DOUBLESIZE || _mode == GFX_TRIPLESIZE))
     1475        if (_cursorTargetScale == 1 && (_mode == GFX_DOUBLESIZE || _mode == GFX_TRIPLESIZE) ||
     1476                        _mode == GFX_FLOAT)
    14501477                scalerProc = _scalerProc;
    14511478        else
    1452                 scalerProc = scalersMagn[_cursorTargetScale - 1][_scaleFactor - 1];
     1479                scalerProc = scalersMagn[(int)_cursorTargetScale - 1][(int)_scaleFactor - 1];
    14531480
    14541481        scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2,
    14551482                _mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch,
     
    15141541        }
    15151542
    15161543        SDL_Rect dst;
    1517         int scale;
     1544        scale_t scale;
    15181545        int width, height;
    15191546        int hotX, hotY;
    15201547
     
    15571584        if (_adjustAspectRatio && !_overlayVisible)
    15581585                dst.y = real2Aspect(dst.y);
    15591586
    1560         dst.x = scale * dst.x - _mouseCurState.rHotX;
    1561         dst.y = scale * dst.y - _mouseCurState.rHotY;
     1587        dst.x = (int)(scale * dst.x - _mouseCurState.rHotX);
     1588        dst.y = (int)(scale * dst.y - _mouseCurState.rHotY);
    15621589        dst.w = _mouseCurState.rW;
    15631590        dst.h = _mouseCurState.rH;
    15641591
     
    16901717        }
    16911718
    16921719        int newMode = -1;
    1693         int factor = _scaleFactor - 1;
     1720        int factor = (int)(_scaleFactor - 1);
    16941721
    16951722        // Increase/decrease the scale factor
    16961723        if (key.keysym.sym == SDLK_EQUALS || key.keysym.sym == SDLK_PLUS || key.keysym.sym == SDLK_MINUS ||
  • backends/platform/sdl/events.cpp

     
    7777
    7878        // Adjust for the screen scaling
    7979        if (!_overlayVisible) {
    80                 event.mouse.x /= _scaleFactor;
    81                 event.mouse.y /= _scaleFactor;
     80                event.mouse.x = (int)(event.mouse.x / _scaleFactor);
     81                event.mouse.y = (int)(event.mouse.y / _scaleFactor);
    8282                if (_adjustAspectRatio)
    8383                        event.mouse.y = aspect2Real(event.mouse.y);
    8484        }
  • backends/platform/sdl/sdl.h

     
    6464        GFX_HQ2X = 8,
    6565        GFX_HQ3X = 9,
    6666        GFX_TV2X = 10,
    67         GFX_DOTMATRIX = 11
     67        GFX_DOTMATRIX = 11,
     68        GFX_FLOAT = 12
    6869};
    6970
    7071
     
    270271        bool _forceFull;
    271272        ScalerProc *_scalerProc;
    272273        int _scalerType;
    273         int _scaleFactor;
     274        scale_t _scaleFactor;
    274275        int _mode;
    275276        int _transactionMode;
    276277        bool _fullscreen;
     
    339340        SDL_Rect _mouseBackup;
    340341        MousePos _mouseCurState;
    341342        byte _mouseKeyColor;
    342         int _cursorTargetScale;
     343        scale_t _cursorTargetScale;
    343344        bool _cursorPaletteDisabled;
    344345        SDL_Surface *_mouseOrigSurface;
    345346        SDL_Surface *_mouseSurface;
     
    402403        virtual bool saveScreenshot(const char *filename); // overloaded by CE backend
    403404
    404405        int effectiveScreenHeight() const {
    405                 return (_adjustAspectRatio ? real2Aspect(_screenHeight) : _screenHeight)
    406                         * _scaleFactor;
     406                return (int)((_adjustAspectRatio ? real2Aspect(_screenHeight) : _screenHeight)
     407                        * _scaleFactor);
    407408        }
    408409
    409410        void setupIcon();