Ticket #8926: sdl_transaction_rollback_v3.patch

File sdl_transaction_rollback_v3.patch, 39.9 KB (added by lordhoto, 16 years ago)

Patch against r34827

  • common/system.h

     
    391391         */
    392392        virtual void beginGFXTransaction() {}
    393393
     394        /**
     395         * This type is able to save the different errors which can happen while
     396         * changing GFX config values inside GFX transactions.
     397         *
     398         * endGFXTransaction returns a ORed combination of the '*Failed' values
     399         * if any problem occures, on success 0.
     400         *
     401         * @see endGFXTransaction
     402         */
     403        enum kTransactionError {
     404                kTransactionSuccess = 0,                                        /**< Everything fine (use EQUAL check for this one!) */
     405                kTransactionAspectRatioFailed = (1 << 0),       /**< Failed switchting aspect ratio correction mode */
     406                kTransactionFullscreenFailed = (1 << 1),        /**< Failed switchting fullscreen mode */
     407                kTransactionModeSwitchFailed = (1 << 2),        /**< Failed switchting the GFX graphics mode (setGraphicsMode) */
     408                kTransactionSizeChangeFailed = (1 << 3)         /**< Failed switchting the screen dimensions (initSize) */
     409        };
    394410
    395411        /**
    396412         * End (and thereby commit) the current GFX transaction.
    397413         * @see beginGFXTransaction
     414         * @see kTransactionError
     415         * @return returns a ORed combination of kTransactionError values or 0 on success
    398416         */
    399         virtual void endGFXTransaction() {}
     417        virtual kTransactionError endGFXTransaction() { return kTransactionSuccess; }
    400418
    401419
    402420        /**
  • backends/platform/sdl/graphics.cpp

     
    4949};
    5050
    5151// Table of relative scalers magnitudes
    52 // [definedScale - 1][_scaleFactor - 1]
     52// [definedScale - 1][scaleFactor - 1]
    5353static ScalerProc *scalersMagn[3][3] = {
    5454#ifndef DISABLE_SCALERS
    5555        { Normal1x, AdvMame2x, AdvMame3x },
     
    8686}
    8787
    8888void OSystem_SDL::beginGFXTransaction(void) {
    89         assert (_transactionMode == kTransactionNone);
     89        assert(_transactionMode == kTransactionNone);
    9090
    9191        _transactionMode = kTransactionActive;
    9292
    93         _transactionDetails.modeChanged = false;
    9493        _transactionDetails.sizeChanged = false;
    95         _transactionDetails.arChanged = false;
    96         _transactionDetails.fsChanged = false;
    9794
    9895        _transactionDetails.needHotswap = false;
    9996        _transactionDetails.needUpdatescreen = false;
    100         _transactionDetails.needUnload = false;
    10197
    10298        _transactionDetails.normal1xScaler = false;
     99
     100        _oldVideoMode = _videoMode;
    103101}
    104102
    105 void OSystem_SDL::endGFXTransaction(void) {
    106         // for each engine we run initCommonGFX() as first thing in the transaction
    107         // and initSize() is called later. If user runs launcher at 320x200 with
    108         // 2x overlay, setting to Nomral1x sclaler in that case will be suppressed
    109         // and backend is forced to 2x
    110         //
    111         // This leads to bad results such as 1280x960 window for 640x480 engines.
    112         // To prevent that we rerun setGraphicsMode() if there was 1x scaler request
    113         if (_transactionDetails.normal1xScaler)
    114                 setGraphicsMode(GFX_NORMAL);
     103OSystem::kTransactionError OSystem_SDL::endGFXTransaction(void) {
     104        int errors = kTransactionSuccess;
    115105
    116         assert (_transactionMode == kTransactionActive);
     106        assert(_transactionMode != kTransactionNone);
    117107
    118         _transactionMode = kTransactionCommit;
    119         if (_transactionDetails.modeChanged)
    120                 setGraphicsMode(_transactionDetails.mode);
     108        if (_transactionMode == kTransactionRollback) {
     109                if (_videoMode.fullscreen != _oldVideoMode.fullscreen) {
     110                        errors |= kTransactionFullscreenFailed;
    121111
    122         if (_transactionDetails.sizeChanged)
    123                 initSize(_transactionDetails.w, _transactionDetails.h);
     112                        _videoMode.fullscreen = _oldVideoMode.fullscreen;
     113                } else if (_videoMode.aspectRatio != _oldVideoMode.aspectRatio) {
     114                        errors |= kTransactionAspectRatioFailed;
    124115
    125         if (_transactionDetails.arChanged)
    126                 setAspectRatioCorrection(_transactionDetails.ar);
     116                        _videoMode.aspectRatio = _oldVideoMode.aspectRatio;
     117                } else if (_videoMode.mode != _oldVideoMode.mode) {
     118                        errors |= kTransactionModeSwitchFailed;
    127119
    128         if (_transactionDetails.needUnload) {
     120                        _videoMode.mode = _oldVideoMode.mode;
     121                        _videoMode.scaleFactor = _oldVideoMode.scaleFactor;
     122                } else if (_videoMode.screenWidth != _oldVideoMode.screenWidth || _videoMode.screenHeight != _oldVideoMode.screenHeight) {
     123                        errors |= kTransactionSizeChangeFailed;
     124
     125                        _videoMode.screenWidth = _oldVideoMode.screenWidth;
     126                        _videoMode.screenHeight = _oldVideoMode.screenHeight;
     127
     128                        // Since this is the last resort of falling back to the old
     129                        // video mode setup, we invalidate the old mode here, because
     130                        // of the way we handle gfx rollback
     131                        _oldVideoMode.setup = false;
     132                }
     133        }
     134
     135        if (_transactionDetails.sizeChanged) {
    129136                unloadGFXMode();
    130                 loadGFXMode();
    131                 clearOverlay();
    132         } else {
    133                 if (!_transactionDetails.fsChanged) {
    134                         if (_transactionDetails.needHotswap)
    135                                 hotswapGFXMode();
    136                         else if (_transactionDetails.needUpdatescreen)
     137                if (!loadGFXMode()) {
     138                        if (_oldVideoMode.setup) {
     139                                _transactionMode = kTransactionRollback;
     140                                errors |= endGFXTransaction();
     141                        }
     142                } else {
     143                        setGraphicsModeIntern();
     144                        clearOverlay();
     145
     146                        _videoMode.setup = true;
     147                        _modeChanged = true;
     148                }
     149        } else if (_transactionDetails.needHotswap) {
     150                setGraphicsModeIntern();
     151                if (!hotswapGFXMode()) {
     152                        if (_oldVideoMode.setup) {
     153                                _transactionMode = kTransactionRollback;
     154                                errors |= endGFXTransaction();
     155                        }
     156                } else {
     157                        _videoMode.setup = true;
     158                        _modeChanged = true;
     159
     160                        if (_transactionDetails.needUpdatescreen)
    137161                                internUpdateScreen();
    138162                }
    139163        }
    140164
    141         if (_transactionDetails.fsChanged)
    142                 setFullscreenMode(_transactionDetails.fs);
    143 
    144165        _transactionMode = kTransactionNone;
     166        return (kTransactionError)errors;
    145167}
    146168
    147169bool OSystem_SDL::setGraphicsMode(int mode) {
    148170        Common::StackLock lock(_graphicsMutex);
    149171
     172        assert(_transactionMode == kTransactionActive);
     173
     174        if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
     175                return true;
     176
    150177        int newScaleFactor = 1;
    151         ScalerProc *newScalerProc;
    152178
    153179        switch(mode) {
    154180        case GFX_NORMAL:
    155181                newScaleFactor = 1;
    156                 newScalerProc = Normal1x;
    157182                break;
    158183#ifndef DISABLE_SCALERS
    159184        case GFX_DOUBLESIZE:
    160185                newScaleFactor = 2;
    161                 newScalerProc = Normal2x;
    162186                break;
    163187        case GFX_TRIPLESIZE:
    164188                newScaleFactor = 3;
    165                 newScalerProc = Normal3x;
    166189                break;
    167190
    168191        case GFX_2XSAI:
    169192                newScaleFactor = 2;
    170                 newScalerProc = _2xSaI;
    171193                break;
    172194        case GFX_SUPER2XSAI:
    173195                newScaleFactor = 2;
    174                 newScalerProc = Super2xSaI;
    175196                break;
    176197        case GFX_SUPEREAGLE:
    177198                newScaleFactor = 2;
    178                 newScalerProc = SuperEagle;
    179199                break;
    180200        case GFX_ADVMAME2X:
    181201                newScaleFactor = 2;
    182                 newScalerProc = AdvMame2x;
    183202                break;
    184203        case GFX_ADVMAME3X:
    185204                newScaleFactor = 3;
    186                 newScalerProc = AdvMame3x;
    187205                break;
    188206#ifndef DISABLE_HQ_SCALERS
    189207        case GFX_HQ2X:
    190208                newScaleFactor = 2;
    191                 newScalerProc = HQ2x;
    192209                break;
    193210        case GFX_HQ3X:
    194211                newScaleFactor = 3;
    195                 newScalerProc = HQ3x;
    196212                break;
    197213#endif
    198214        case GFX_TV2X:
    199215                newScaleFactor = 2;
    200                 newScalerProc = TV2x;
    201216                break;
    202217        case GFX_DOTMATRIX:
    203218                newScaleFactor = 2;
    204                 newScalerProc = DotMatrix;
    205219                break;
    206220#endif // DISABLE_SCALERS
    207221
     
    211225        }
    212226
    213227        _transactionDetails.normal1xScaler = (mode == GFX_NORMAL);
     228        if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newScaleFactor)
     229                _transactionDetails.needHotswap = true;
    214230
    215         _mode = mode;
    216         _scalerProc = newScalerProc;
     231        _transactionDetails.needUpdatescreen = true;
    217232
    218         if (_transactionMode == kTransactionActive) {
    219                 _transactionDetails.mode = mode;
    220                 _transactionDetails.modeChanged = true;
     233        _videoMode.mode = mode;
     234        _videoMode.scaleFactor = newScaleFactor;
    221235
    222                 if (newScaleFactor != _scaleFactor) {
    223                         _transactionDetails.needHotswap = true;
    224                         _scaleFactor = newScaleFactor;
    225                 }
     236        return true;
     237}
    226238
    227                 _transactionDetails.needUpdatescreen = true;
     239void OSystem_SDL::setGraphicsModeIntern() {
     240        Common::StackLock lock(_graphicsMutex);
     241        ScalerProc *newScalerProc = 0;
    228242
    229                 return true;
    230         }
     243        switch (_videoMode.mode) {
     244        case GFX_NORMAL:
     245                newScalerProc = Normal1x;
     246                break;
     247#ifndef DISABLE_SCALERS
     248        case GFX_DOUBLESIZE:
     249                newScalerProc = Normal2x;
     250                break;
     251        case GFX_TRIPLESIZE:
     252                newScalerProc = Normal3x;
     253                break;
    231254
    232         // NOTE: This should not be executed at transaction commit
    233         //   Otherwise there is some unsolicited setGraphicsMode() call
    234         //   which should be properly removed
    235         if (newScaleFactor != _scaleFactor) {
    236                 assert(_transactionMode != kTransactionCommit);
     255        case GFX_2XSAI:
     256                newScalerProc = _2xSaI;
     257                break;
     258        case GFX_SUPER2XSAI:
     259                newScalerProc = Super2xSaI;
     260                break;
     261        case GFX_SUPEREAGLE:
     262                newScalerProc = SuperEagle;
     263                break;
     264        case GFX_ADVMAME2X:
     265                newScalerProc = AdvMame2x;
     266                break;
     267        case GFX_ADVMAME3X:
     268                newScalerProc = AdvMame3x;
     269                break;
     270#ifndef DISABLE_HQ_SCALERS
     271        case GFX_HQ2X:
     272                newScalerProc = HQ2x;
     273                break;
     274        case GFX_HQ3X:
     275                newScalerProc = HQ3x;
     276                break;
     277#endif
     278        case GFX_TV2X:
     279                newScalerProc = TV2x;
     280                break;
     281        case GFX_DOTMATRIX:
     282                newScalerProc = DotMatrix;
     283                break;
     284#endif // DISABLE_SCALERS
    237285
    238                 _scaleFactor = newScaleFactor;
    239                 hotswapGFXMode();
     286        default:
     287                error("Unknown gfx mode %d", _videoMode.mode);
    240288        }
    241289
    242         // Determine the "scaler type", i.e. essentially an index into the
    243         // s_gfxModeSwitchTable array defined in events.cpp.
    244         if (_mode != GFX_NORMAL) {
     290        _scalerProc = newScalerProc;
     291       
     292        if (_videoMode.mode != GFX_NORMAL) {
    245293                for (int i = 0; i < ARRAYSIZE(s_gfxModeSwitchTable); i++) {
    246                         if (s_gfxModeSwitchTable[i][1] == _mode || s_gfxModeSwitchTable[i][2] == _mode) {
     294                        if (s_gfxModeSwitchTable[i][1] == _videoMode.mode || s_gfxModeSwitchTable[i][2] == _videoMode.mode) {
    247295                                _scalerType = i;
    248296                                break;
    249297                        }
    250298                }
    251299        }
    252300
    253         if (!_screen)
    254                 return true;
     301        if (!_screen || !_hwscreen)
     302                return;
    255303
    256304        // Blit everything to the screen
    257305        _forceFull = true;
     
    259307        // Even if the old and new scale factors are the same, we may have a
    260308        // different scaler for the cursor now.
    261309        blitCursor();
    262 
    263         if (_transactionMode != kTransactionCommit)
    264                 internUpdateScreen();
    265 
    266         // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later
    267         _modeChanged = true;
    268 
    269         return true;
    270310}
    271311
    272312int OSystem_SDL::getGraphicsMode() const {
    273313        assert (_transactionMode == kTransactionNone);
    274         return _mode;
     314        return _videoMode.mode;
    275315}
    276316
    277317void OSystem_SDL::initSize(uint w, uint h) {
     318        assert(_transactionMode == kTransactionActive);
     319
    278320        // Avoid redundant res changes
    279         if ((int)w == _screenWidth && (int)h == _screenHeight &&
    280                 _transactionMode != kTransactionCommit)
     321        if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight)
    281322                return;
    282323
    283         _screenWidth = w;
    284         _screenHeight = h;
     324        _videoMode.screenWidth = w;
     325        _videoMode.screenHeight = h;
    285326
    286         _cksumNum = (_screenWidth * _screenHeight / (8 * 8));
     327        _cksumNum = (w * h / (8 * 8));
    287328
    288         if (_transactionMode == kTransactionActive) {
    289                 _transactionDetails.w = w;
    290                 _transactionDetails.h = h;
    291                 _transactionDetails.sizeChanged = true;
     329        _transactionDetails.sizeChanged = true;
    292330
    293                 _transactionDetails.needUnload = true;
    294 
    295                 return;
    296         }
    297 
    298331        free(_dirtyChecksums);
    299332        _dirtyChecksums = (uint32 *)calloc(_cksumNum * 2, sizeof(uint32));
    300 
    301         if (_transactionMode != kTransactionCommit) {
    302                 unloadGFXMode();
    303                 loadGFXMode();
    304 
    305                 // if initSize() gets called in the middle, overlay is not transparent
    306                 clearOverlay();
    307         }
    308333}
    309334
    310 void OSystem_SDL::loadGFXMode() {
     335bool OSystem_SDL::loadGFXMode() {
    311336        assert(_inited);
    312337        _forceFull = true;
    313338
    314339        int hwW, hwH;
    315340
    316341#ifndef __MAEMO__
    317         _overlayWidth = _screenWidth * _scaleFactor;
    318         _overlayHeight = _screenHeight * _scaleFactor;
     342        _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
     343        _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
    319344
    320         if (_screenHeight != 200 && _screenHeight != 400)
    321                 _adjustAspectRatio = false;
     345        if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400)
     346                _videoMode.aspectRatio = false;
    322347
    323         if (_adjustAspectRatio)
    324                 _overlayHeight = real2Aspect(_overlayHeight);
     348        if (_videoMode.aspectRatio)
     349                _videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
    325350
    326         hwW = _screenWidth * _scaleFactor;
     351        hwW = _videoMode.screenWidth * _videoMode.scaleFactor;
    327352        hwH = effectiveScreenHeight();
    328353#else
    329         hwW = _overlayWidth;
    330         hwH = _overlayHeight;
     354        hwW = _videoMode.overlayWidth;
     355        hwH = _videoMode.overlayHeight;
    331356#endif
    332357
    333358        //
    334359        // Create the surface that contains the 8 bit game data
    335360        //
    336         _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth, _screenHeight, 8, 0, 0, 0, 0);
     361        _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
    337362        if (_screen == NULL)
    338363                error("allocating _screen failed");
    339364
     
    342367        //
    343368
    344369        _hwscreen = SDL_SetVideoMode(hwW, hwH, 16,
    345                 _fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
     370                _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
    346371        );
    347372        if (_hwscreen == NULL) {
    348373                // DON'T use error(), as this tries to bring up the debug
    349374                // console, which WON'T WORK now that _hwscreen is hosed.
    350375
    351                 // FIXME: We should be able to continue the game without
    352                 // shutting down or bringing up the debug console, but at
    353                 // this point we've already screwed up all our member vars.
    354                 // We need to find a way to call SDL_SetVideoMode *before*
    355                 // that happens and revert to all the old settings if we
    356                 // can't pull off the switch to the new settings.
    357                 //
    358                 // Fingolfin says: the "easy" way to do that is not to modify
    359                 // the member vars before we are sure everything is fine. Think
    360                 // of "transactions, commit, rollback" style... we use local vars
    361                 // in place of the member vars, do everything etc. etc.. In case
    362                 // of a failure, rollback is trivial. Only if everything worked fine
    363                 // do we "commit" the changed values to the member vars.
    364                 warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
    365                 quit();
     376                if (!_oldVideoMode.setup) {
     377                        warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
     378                        quit();
     379                } else {
     380                        return false;
     381                }
    366382        }
    367383
    368384        //
     
    376392                InitScalers(565);
    377393
    378394        // Need some extra bytes around when using 2xSaI
    379         _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth + 3, _screenHeight + 3,
     395        _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3,
    380396                                                16,
    381397                                                _hwscreen->format->Rmask,
    382398                                                _hwscreen->format->Gmask,
     
    386402        if (_tmpscreen == NULL)
    387403                error("allocating _tmpscreen failed");
    388404
    389         _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth, _overlayHeight,
     405        _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight,
    390406                                                16,
    391407                                                _hwscreen->format->Rmask,
    392408                                                _hwscreen->format->Gmask,
     
    396412        if (_overlayscreen == NULL)
    397413                error("allocating _overlayscreen failed");
    398414
    399         _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth + 3, _overlayHeight + 3,
     415        _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3,
    400416                                                16,
    401417                                                _hwscreen->format->Rmask,
    402418                                                _hwscreen->format->Gmask,
     
    421437#endif
    422438
    423439        // keyboard cursor control, some other better place for it?
    424         _km.x_max = _screenWidth * _scaleFactor - 1;
     440        _km.x_max = _videoMode.screenWidth * _videoMode.scaleFactor - 1;
    425441        _km.y_max = effectiveScreenHeight() - 1;
    426442        _km.delay_time = 25;
    427443        _km.last_time = 0;
     444
     445        return true;
    428446}
    429447
    430448void OSystem_SDL::unloadGFXMode() {
     
    462480        DestroyScalers();
    463481}
    464482
    465 void OSystem_SDL::hotswapGFXMode() {
     483bool OSystem_SDL::hotswapGFXMode() {
    466484        if (!_screen)
    467                 return;
     485                return false;
    468486
    469487        // Keep around the old _screen & _overlayscreen so we can restore the screen data
    470488        // after the mode switch.
    471489        SDL_Surface *old_screen = _screen;
    472490        SDL_Surface *old_overlayscreen = _overlayscreen;
     491        _screen = NULL;
     492        _overlayscreen = NULL;
    473493
    474494        // Release the HW screen surface
    475         SDL_FreeSurface(_hwscreen);
     495        SDL_FreeSurface(_hwscreen); _hwscreen = NULL;
    476496
    477         SDL_FreeSurface(_tmpscreen);
    478         SDL_FreeSurface(_tmpscreen2);
     497        SDL_FreeSurface(_tmpscreen); _tmpscreen = NULL;
     498        SDL_FreeSurface(_tmpscreen2); _tmpscreen2 = NULL;
    479499
    480500#ifdef USE_OSD
    481501        // Release the OSD surface
    482         SDL_FreeSurface(_osdSurface);
     502        SDL_FreeSurface(_osdSurface); _osdSurface = NULL;
    483503#endif
    484504
    485505        // Setup the new GFX mode
    486         loadGFXMode();
     506        if (!loadGFXMode()) {
     507                unloadGFXMode();
    487508
     509                _screen = old_screen;
     510                _overlayscreen = old_overlayscreen;
     511
     512                return false;
     513        }
     514
    488515        // reset palette
    489516        SDL_SetColors(_screen, _currentPalette, 0, 256);
    490517
     
    502529        // Blit everything to the screen
    503530        internUpdateScreen();
    504531
    505         // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later
    506         _modeChanged = true;
     532        return true;
    507533}
    508534
    509535void OSystem_SDL::updateScreen() {
     
    527553
    528554        // If the shake position changed, fill the dirty area with blackness
    529555        if (_currentShakePos != _newShakePos) {
    530                 SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor};
     556                SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor};
    531557
    532                 if (_adjustAspectRatio && !_overlayVisible)
     558                if (_videoMode.aspectRatio && !_overlayVisible)
    533559                        blackrect.h = real2Aspect(blackrect.h - 1) + 1;
    534560
    535561                SDL_FillRect(_hwscreen, &blackrect, 0);
     
    574600        if (!_overlayVisible) {
    575601                origSurf = _screen;
    576602                srcSurf = _tmpscreen;
    577                 width = _screenWidth;
    578                 height = _screenHeight;
     603                width = _videoMode.screenWidth;
     604                height = _videoMode.screenHeight;
    579605                scalerProc = _scalerProc;
    580                 scale1 = _scaleFactor;
     606                scale1 = _videoMode.scaleFactor;
    581607        } else {
    582608                origSurf = _overlayscreen;
    583609                srcSurf = _tmpscreen2;
    584                 width = _overlayWidth;
    585                 height = _overlayHeight;
     610                width = _videoMode.overlayWidth;
     611                height = _videoMode.overlayHeight;
    586612                scalerProc = Normal1x;
    587613
    588614                scale1 = 1;
     
    635661                                orig_dst_y = dst_y;
    636662                                dst_y = dst_y * scale1;
    637663
    638                                 if (_adjustAspectRatio && !_overlayVisible)
     664                                if (_videoMode.aspectRatio && !_overlayVisible)
    639665                                        dst_y = real2Aspect(dst_y);
    640666
    641667                                assert(scalerProc != NULL);
     
    649675                        r->h = dst_h * scale1;
    650676
    651677#ifndef DISABLE_SCALERS
    652                         if (_adjustAspectRatio && orig_dst_y < height && !_overlayVisible)
     678                        if (_videoMode.aspectRatio && orig_dst_y < height && !_overlayVisible)
    653679                                r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
    654680#endif
    655681                }
     
    692718void OSystem_SDL::setFullscreenMode(bool enable) {
    693719        Common::StackLock lock(_graphicsMutex);
    694720       
    695         if (_fullscreen == enable)
     721        if (_oldVideoMode.setup && _oldVideoMode.fullscreen == enable)
    696722                return;
    697723
    698         if (_transactionMode == kTransactionCommit) {
    699                 assert(_hwscreen != 0);
    700                 _fullscreen = enable;
    701 
    702                 // Switch between fullscreen and windowed mode by invoking hotswapGFXMode().
    703                 // We used to use SDL_WM_ToggleFullScreen() in the past, but this caused various
    704                 // problems. E.g. on OS X, it was implemented incorrectly for a long time; on
    705                 // the MAEMO platform, it seems to have caused problems, too.
    706                 // And on Linux, there were some troubles, too (see bug #1705410).
    707                 // So, we just do it "manually" now. There shouldn't be any drawbacks to that
    708                 // anyway.
    709                 hotswapGFXMode();
    710         } else if (_transactionMode == kTransactionActive) {
    711                 _transactionDetails.fs = enable;
    712                 _transactionDetails.fsChanged = true;
    713 
     724        if (_transactionMode == kTransactionActive) {
     725                _videoMode.fullscreen = enable;
    714726                _transactionDetails.needHotswap = true;
    715727        }
    716728}
    717729
    718730void OSystem_SDL::setAspectRatioCorrection(bool enable) {
    719         if (((_screenHeight == 200 || _screenHeight == 400) && _adjustAspectRatio != enable) ||
    720                 _transactionMode == kTransactionCommit) {
    721                 Common::StackLock lock(_graphicsMutex);
     731        Common::StackLock lock(_graphicsMutex);
    722732
    723                 //assert(_hwscreen != 0);
    724                 _adjustAspectRatio = enable;
     733        if (_oldVideoMode.setup && _oldVideoMode.aspectRatio == enable)
     734                return;
    725735
    726                 if (_transactionMode == kTransactionActive) {
    727                         _transactionDetails.ar = enable;
    728                         _transactionDetails.arChanged = true;
    729 
    730                         _transactionDetails.needHotswap = true;
    731 
    732                         return;
    733                 } else {
    734                         if (_transactionMode != kTransactionCommit)
    735                                 hotswapGFXMode();
    736                 }
    737 
    738                 // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later
    739                 _modeChanged = true;
     736        if (_transactionMode == kTransactionActive) {
     737                _videoMode.aspectRatio = enable;
     738                _transactionDetails.needHotswap = true;
    740739        }
    741740}
    742741
     
    751750
    752751        Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
    753752
    754         assert(x >= 0 && x < _screenWidth);
    755         assert(y >= 0 && y < _screenHeight);
    756         assert(h > 0 && y + h <= _screenHeight);
    757         assert(w > 0 && x + w <= _screenWidth);
     753        assert(x >= 0 && x < _videoMode.screenWidth);
     754        assert(y >= 0 && y < _videoMode.screenHeight);
     755        assert(h > 0 && y + h <= _videoMode.screenHeight);
     756        assert(w > 0 && x + w <= _videoMode.screenWidth);
    758757
    759         if (((long)src & 3) == 0 && pitch == _screenWidth && x == 0 && y == 0 &&
    760                         w == _screenWidth && h == _screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) {
     758        if (((long)src & 3) == 0 && pitch == _videoMode.screenWidth && x == 0 && y == 0 &&
     759                        w == _videoMode.screenWidth && h == _videoMode.screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) {
    761760                /* Special, optimized case for full screen updates.
    762761                 * It tries to determine what areas were actually changed,
    763762                 * and just updates those, on the actual display. */
     
    776775                        y = 0;
    777776                }
    778777
    779                 if (w > _screenWidth - x) {
    780                         w = _screenWidth - x;
     778                if (w > _videoMode.screenWidth - x) {
     779                        w = _videoMode.screenWidth - x;
    781780                }
    782781
    783                 if (h > _screenHeight - y) {
    784                         h = _screenHeight - y;
     782                if (h > _videoMode.screenHeight - y) {
     783                        h = _videoMode.screenHeight - y;
    785784                }
    786785
    787786                if (w <= 0 || h <= 0)
     
    795794        if (SDL_LockSurface(_screen) == -1)
    796795                error("SDL_LockSurface failed: %s", SDL_GetError());
    797796
    798         byte *dst = (byte *)_screen->pixels + y * _screenWidth + x;
     797        byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
    799798
    800         if (_screenWidth == pitch && pitch == w) {
     799        if (_videoMode.screenWidth == pitch && pitch == w) {
    801800                memcpy(dst, src, h*w);
    802801        } else {
    803802                do {
    804803                        memcpy(dst, src, w);
    805804                        src += pitch;
    806                         dst += _screenWidth;
     805                        dst += _videoMode.screenWidth;
    807806                } while (--h);
    808807        }
    809808
     
    863862        int height, width;
    864863
    865864        if (!_overlayVisible && !realCoordinates) {
    866                 width = _screenWidth;
    867                 height = _screenHeight;
     865                width = _videoMode.screenWidth;
     866                height = _videoMode.screenHeight;
    868867        } else {
    869                 width = _overlayWidth;
    870                 height = _overlayHeight;
     868                width = _videoMode.overlayWidth;
     869                height = _videoMode.overlayHeight;
    871870        }
    872871
    873872        // Extend the dirty region by 1 pixel for scalers
     
    899898        }
    900899
    901900#ifndef DISABLE_SCALERS
    902         if (_adjustAspectRatio && !_overlayVisible && !realCoordinates) {
     901        if (_videoMode.aspectRatio && !_overlayVisible && !realCoordinates) {
    903902                makeRectStretchable(x, y, w, h);
    904903        }
    905904#endif
     
    924923        assert(buf);
    925924        uint32 *sums = _dirtyChecksums;
    926925        uint x,y;
    927         const uint last_x = (uint)_screenWidth / 8;
    928         const uint last_y = (uint)_screenHeight / 8;
     926        const uint last_x = (uint)_videoMode.screenWidth / 8;
     927        const uint last_y = (uint)_videoMode.screenHeight / 8;
    929928
    930929        const uint BASE = 65521; /* largest prime smaller than 65536 */
    931930
    932931        /* the 8x8 blocks in buf are enumerated starting in the top left corner and
    933932         * reading each line at a time from left to right */
    934         for (y = 0; y != last_y; y++, buf += _screenWidth * (8 - 1))
     933        for (y = 0; y != last_y; y++, buf += _videoMode.screenWidth * (8 - 1))
    935934                for (x = 0; x != last_x; x++, buf += 8) {
    936935                        // Adler32 checksum algorithm (from RFC1950, used by gzip and zlib).
    937936                        // This computes the Adler32 checksum of a 8x8 pixel block. Note
     
    947946                                        s1 += ptr[subX];
    948947                                        s2 += s1;
    949948                                }
    950                                 ptr += _screenWidth;
     949                                ptr += _videoMode.screenWidth;
    951950                        }
    952951
    953952                        s1 %= BASE;
     
    977976                int x, y, w;
    978977                uint32 *ck = _dirtyChecksums;
    979978
    980                 for (y = 0; y != _screenHeight / 8; y++) {
    981                         for (x = 0; x != _screenWidth / 8; x++, ck++) {
     979                for (y = 0; y != _videoMode.screenHeight / 8; y++) {
     980                        for (x = 0; x != _videoMode.screenWidth / 8; x++, ck++) {
    982981                                if (ck[0] != ck[_cksumNum]) {
    983982                                        /* found a dirty 8x8 block, now go as far to the right as possible,
    984983                                                 and at the same time, unmark the dirty status by setting old to new. */
     
    986985                                        do {
    987986                                                ck[w + _cksumNum] = ck[w];
    988987                                                w++;
    989                                         } while (x + w != _screenWidth / 8 && ck[w] != ck[w + _cksumNum]);
     988                                        } while (x + w != _videoMode.screenWidth / 8 && ck[w] != ck[w + _cksumNum]);
    990989
    991990                                        addDirtyRect(x * 8, y * 8, w * 8, 8);
    992991
     
    10031002}
    10041003
    10051004int16 OSystem_SDL::getHeight() {
    1006         return _screenHeight;
     1005        return _videoMode.screenHeight;
    10071006}
    10081007
    10091008int16 OSystem_SDL::getWidth() {
    1010         return _screenWidth;
     1009        return _videoMode.screenWidth;
    10111010}
    10121011
    10131012void OSystem_SDL::setPalette(const byte *colors, uint start, uint num) {
     
    10931092
    10941093        // Since resolution could change, put mouse to adjusted position
    10951094        // Fixes bug #1349059
    1096         x = _mouseCurState.x * _scaleFactor;
    1097         if (_adjustAspectRatio)
    1098                 y = real2Aspect(_mouseCurState.y) * _scaleFactor;
     1095        x = _mouseCurState.x * _videoMode.scaleFactor;
     1096        if (_videoMode.aspectRatio)
     1097                y = real2Aspect(_mouseCurState.y) * _videoMode.scaleFactor;
    10991098        else
    1100                 y = _mouseCurState.y * _scaleFactor;
     1099                y = _mouseCurState.y * _videoMode.scaleFactor;
    11011100
    11021101        warpMouse(x, y);
    11031102
     
    11161115
    11171116        // Since resolution could change, put mouse to adjusted position
    11181117        // Fixes bug #1349059
    1119         x = _mouseCurState.x / _scaleFactor;
    1120         y = _mouseCurState.y / _scaleFactor;
    1121         if (_adjustAspectRatio)
     1118        x = _mouseCurState.x / _videoMode.scaleFactor;
     1119        y = _mouseCurState.y / _videoMode.scaleFactor;
     1120        if (_videoMode.aspectRatio)
    11221121                y = aspect2Real(y);
    11231122
    11241123        warpMouse(x, y);
     
    11401139        SDL_Rect src, dst;
    11411140        src.x = src.y = 0;
    11421141        dst.x = dst.y = 1;
    1143         src.w = dst.w = _screenWidth;
    1144         src.h = dst.h = _screenHeight;
     1142        src.w = dst.w = _videoMode.screenWidth;
     1143        src.h = dst.h = _videoMode.screenHeight;
    11451144        if (SDL_BlitSurface(_screen, &src, _tmpscreen, &dst) != 0)
    11461145                error("SDL_BlitSurface failed: %s", SDL_GetError());
    11471146
    11481147        SDL_LockSurface(_tmpscreen);
    11491148        SDL_LockSurface(_overlayscreen);
    11501149        _scalerProc((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2, _tmpscreen->pitch,
    1151         (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight);
     1150        (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _videoMode.screenWidth, _videoMode.screenHeight);
    11521151
    11531152#ifndef DISABLE_SCALERS
    1154         if (_adjustAspectRatio)
     1153        if (_videoMode.aspectRatio)
    11551154                stretch200To240((uint8 *)_overlayscreen->pixels, _overlayscreen->pitch,
    1156                                                 _overlayWidth, _screenHeight * _scaleFactor, 0, 0, 0);
     1155                                                _videoMode.overlayWidth, _videoMode.screenHeight * _videoMode.scaleFactor, 0, 0, 0);
    11571156#endif
    11581157        SDL_UnlockSurface(_tmpscreen);
    11591158        SDL_UnlockSurface(_overlayscreen);
     
    11711170                error("SDL_LockSurface failed: %s", SDL_GetError());
    11721171
    11731172        byte *src = (byte *)_overlayscreen->pixels;
    1174         int h = _overlayHeight;
     1173        int h = _videoMode.overlayHeight;
    11751174        do {
    1176                 memcpy(buf, src, _overlayWidth * 2);
     1175                memcpy(buf, src, _videoMode.overlayWidth * 2);
    11771176                src += _overlayscreen->pitch;
    11781177                buf += pitch;
    11791178        } while (--h);
     
    11991198                y = 0;
    12001199        }
    12011200
    1202         if (w > _overlayWidth - x) {
    1203                 w = _overlayWidth - x;
     1201        if (w > _videoMode.overlayWidth - x) {
     1202                w = _videoMode.overlayWidth - x;
    12041203        }
    12051204
    1206         if (h > _overlayHeight - y) {
    1207                 h = _overlayHeight - y;
     1205        if (h > _videoMode.overlayHeight - y) {
     1206                h = _videoMode.overlayHeight - y;
    12081207        }
    12091208
    12101209        if (w <= 0 || h <= 0)
     
    12601259void OSystem_SDL::warpMouse(int x, int y) {
    12611260        int y1 = y;
    12621261
    1263         if (_adjustAspectRatio && !_overlayVisible)
     1262        if (_videoMode.aspectRatio && !_overlayVisible)
    12641263                y1 = real2Aspect(y);
    12651264
    12661265        if (_mouseCurState.x != x || _mouseCurState.y != y) {
    12671266                if (!_overlayVisible)
    1268                         SDL_WarpMouse(x * _scaleFactor, y1 * _scaleFactor);
     1267                        SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor);
    12691268                else
    12701269                        SDL_WarpMouse(x, y1);
    12711270
     
    13681367
    13691368        int rW, rH;
    13701369
    1371         if (_cursorTargetScale >= _scaleFactor) {
     1370        if (_cursorTargetScale >= _videoMode.scaleFactor) {
    13721371                // The cursor target scale is greater or equal to the scale at
    13731372                // which the rest of the screen is drawn. We do not downscale
    13741373                // the cursor image, we draw it at its original size. It will
     
    13811380
    13821381                // The virtual dimensions may be larger than the original.
    13831382
    1384                 _mouseCurState.vW = w * _cursorTargetScale / _scaleFactor;
    1385                 _mouseCurState.vH = h * _cursorTargetScale / _scaleFactor;
     1383                _mouseCurState.vW = w * _cursorTargetScale / _videoMode.scaleFactor;
     1384                _mouseCurState.vH = h * _cursorTargetScale / _videoMode.scaleFactor;
    13861385                _mouseCurState.vHotX = _mouseCurState.hotX * _cursorTargetScale /
    1387                         _scaleFactor;
     1386                        _videoMode.scaleFactor;
    13881387                _mouseCurState.vHotY = _mouseCurState.hotY * _cursorTargetScale /
    1389                         _scaleFactor;
     1388                        _videoMode.scaleFactor;
    13901389        } else {
    13911390                // The cursor target scale is smaller than the scale at which
    13921391                // the rest of the screen is drawn. We scale up the cursor
    13931392                // image to make it appear correct.
    13941393
    1395                 rW = w * _scaleFactor / _cursorTargetScale;
    1396                 rH = h * _scaleFactor / _cursorTargetScale;
    1397                 _mouseCurState.rHotX = _mouseCurState.hotX * _scaleFactor /
     1394                rW = w * _videoMode.scaleFactor / _cursorTargetScale;
     1395                rH = h * _videoMode.scaleFactor / _cursorTargetScale;
     1396                _mouseCurState.rHotX = _mouseCurState.hotX * _videoMode.scaleFactor /
    13981397                        _cursorTargetScale;
    1399                 _mouseCurState.rHotY = _mouseCurState.hotY * _scaleFactor /
     1398                _mouseCurState.rHotY = _mouseCurState.hotY * _videoMode.scaleFactor /
    14001399                        _cursorTargetScale;
    14011400
    14021401                // The virtual dimensions will be the same as the original.
     
    14111410        int rH1 = rH; // store original to pass to aspect-correction function later
    14121411#endif
    14131412
    1414         if (_adjustAspectRatio && _cursorTargetScale == 1) {
     1413        if (_videoMode.aspectRatio && _cursorTargetScale == 1) {
    14151414                rH = real2Aspect(rH - 1) + 1;
    14161415                _mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
    14171416        }
     
    14461445        // the game. This only works well with the non-blurring scalers so we
    14471446        // actually only use the 1x, 1.5x, 2x and AdvMame scalers.
    14481447
    1449         if (_cursorTargetScale == 1 && (_mode == GFX_DOUBLESIZE || _mode == GFX_TRIPLESIZE))
     1448        if (_cursorTargetScale == 1 && (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE))
    14501449                scalerProc = _scalerProc;
    14511450        else
    1452                 scalerProc = scalersMagn[_cursorTargetScale - 1][_scaleFactor - 1];
     1451                scalerProc = scalersMagn[_cursorTargetScale - 1][_videoMode.scaleFactor - 1];
    14531452
    14541453        scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2,
    14551454                _mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch,
    14561455                _mouseCurState.w, _mouseCurState.h);
    14571456
    14581457#ifndef DISABLE_SCALERS
    1459         if (_adjustAspectRatio && _cursorTargetScale == 1)
     1458        if (_videoMode.aspectRatio && _cursorTargetScale == 1)
    14601459                cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, rW, rH1, 0, 0, 0);
    14611460#endif
    14621461
     
    14991498
    15001499        // When we switch bigger overlay off mouse jumps. Argh!
    15011500        // This is intended to prevent undrawing offscreen mouse
    1502         if (!_overlayVisible && (x >= _screenWidth || y >= _screenHeight)) {
     1501        if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight)) {
    15031502                return;
    15041503        }
    15051504
     
    15221521        dst.y = _mouseCurState.y;
    15231522
    15241523        if (!_overlayVisible) {
    1525                 scale = _scaleFactor;
    1526                 width = _screenWidth;
    1527                 height = _screenHeight;
     1524                scale = _videoMode.scaleFactor;
     1525                width = _videoMode.screenWidth;
     1526                height = _videoMode.screenHeight;
    15281527                dst.w = _mouseCurState.vW;
    15291528                dst.h = _mouseCurState.vH;
    15301529                hotX = _mouseCurState.vHotX;
    15311530                hotY = _mouseCurState.vHotY;
    15321531        } else {
    15331532                scale = 1;
    1534                 width = _overlayWidth;
    1535                 height = _overlayHeight;
     1533                width = _videoMode.overlayWidth;
     1534                height = _videoMode.overlayHeight;
    15361535                dst.w = _mouseCurState.rW;
    15371536                dst.h = _mouseCurState.rH;
    15381537                hotX = _mouseCurState.rHotX;
     
    15541553                dst.y += _currentShakePos;
    15551554        }
    15561555
    1557         if (_adjustAspectRatio && !_overlayVisible)
     1556        if (_videoMode.aspectRatio && !_overlayVisible)
    15581557                dst.y = real2Aspect(dst.y);
    15591558
    15601559        dst.x = scale * dst.x - _mouseCurState.rHotX;
     
    16701669void OSystem_SDL::handleScalerHotkeys(const SDL_KeyboardEvent &key) {
    16711670        // Ctrl-Alt-a toggles aspect ratio correction
    16721671        if (key.keysym.sym == 'a') {
    1673                 setFeatureState(kFeatureAspectRatioCorrection, !_adjustAspectRatio);
     1672                beginGFXTransaction();
     1673                        setFeatureState(kFeatureAspectRatioCorrection, !_videoMode.aspectRatio);
     1674                endGFXTransaction();
    16741675#ifdef USE_OSD
    16751676                char buffer[128];
    1676                 if (_adjustAspectRatio)
     1677                if (_videoMode.aspectRatio)
    16771678                        sprintf(buffer, "Enabled aspect ratio correction\n%d x %d -> %d x %d",
    1678                                 _screenWidth, _screenHeight,
     1679                                _videoMode.screenWidth, _videoMode.screenHeight,
    16791680                                _hwscreen->w, _hwscreen->h
    16801681                                );
    16811682                else
    16821683                        sprintf(buffer, "Disabled aspect ratio correction\n%d x %d -> %d x %d",
    1683                                 _screenWidth, _screenHeight,
     1684                                _videoMode.screenWidth, _videoMode.screenHeight,
    16841685                                _hwscreen->w, _hwscreen->h
    16851686                                );
    16861687                displayMessageOnOSD(buffer);
     
    16901691        }
    16911692
    16921693        int newMode = -1;
    1693         int factor = _scaleFactor - 1;
     1694        int factor = _videoMode.scaleFactor - 1;
    16941695
    16951696        // Increase/decrease the scale factor
    16961697        if (key.keysym.sym == SDLK_EQUALS || key.keysym.sym == SDLK_PLUS || key.keysym.sym == SDLK_MINUS ||
     
    17161717        }
    17171718
    17181719        if (newMode >= 0) {
    1719                 setGraphicsMode(newMode);
     1720                beginGFXTransaction();
     1721                        setGraphicsMode(newMode);
     1722                endGFXTransaction();
    17201723#ifdef USE_OSD
    17211724                if (_osdSurface) {
    17221725                        const char *newScalerName = 0;
    17231726                        const GraphicsMode *g = getSupportedGraphicsModes();
    17241727                        while (g->name) {
    1725                                 if (g->id == _mode) {
     1728                                if (g->id == _videoMode.mode) {
    17261729                                        newScalerName = g->description;
    17271730                                        break;
    17281731                                }
     
    17321735                                char buffer[128];
    17331736                                sprintf(buffer, "Active graphics filter: %s\n%d x %d -> %d x %d",
    17341737                                        newScalerName,
    1735                                         _screenWidth, _screenHeight,
     1738                                        _videoMode.screenWidth, _videoMode.screenHeight,
    17361739                                        _hwscreen->w, _hwscreen->h
    17371740                                        );
    17381741                                displayMessageOnOSD(buffer);
  • backends/platform/sdl/sdl.cpp

     
    112112        // Enable unicode support if possible
    113113        SDL_EnableUNICODE(1);
    114114
     115        _oldVideoMode.setup = false;
     116        _videoMode.setup = false;
     117
    115118        _cksumValid = false;
    116119#if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) && !defined(DISABLE_SCALERS)
    117         _mode = GFX_DOUBLESIZE;
    118         _scaleFactor = 2;
     120        _videoMode.mode = GFX_DOUBLESIZE;
     121        _videoMode.scaleFactor = 2;
     122        _videoMode.aspectRatio = ConfMan.getBool("aspect_ratio");
    119123        _scalerProc = Normal2x;
    120         _adjustAspectRatio = ConfMan.getBool("aspect_ratio");
    121124#else // for small screen platforms
    122         _mode = GFX_NORMAL;
    123         _scaleFactor = 1;
     125        _videoMode.mode = GFX_NORMAL;
     126        _videoMode.scaleFactor = 1;
     127        _videoMode.aspectRatio = false;
    124128        _scalerProc = Normal1x;
    125         _adjustAspectRatio = false;
    126129#endif
    127130        _scalerType = 0;
    128131        _modeFlags = 0;
    129132
    130133#if !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
    131         _fullscreen = ConfMan.getBool("fullscreen");
     134        _videoMode.fullscreen = ConfMan.getBool("fullscreen");
    132135#else
    133         _fullscreen = true;
     136        _videoMode.fullscreen = true;
    134137#endif
    135138
    136139#if !defined(MACOSX) && !defined(__SYMBIAN32__)
     
    184187#ifdef USE_OSD
    185188        _osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0),
    186189#endif
    187         _hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0),
    188         _tmpscreen(0), _overlayWidth(0), _overlayHeight(0),
     190        _hwscreen(0), _screen(0), _tmpscreen(0),
    189191        _overlayVisible(false),
    190192        _overlayscreen(0), _tmpscreen2(0),
    191193        _samplesPerSec(0),
     
    423425
    424426        switch (f) {
    425427        case kFeatureFullscreenMode:
    426                 return _fullscreen;
     428                return _videoMode.fullscreen;
    427429        case kFeatureAspectRatioCorrection:
    428                 return _adjustAspectRatio;
     430                return _videoMode.aspectRatio;
    429431        case kFeatureAutoComputeDirtyRects:
    430432                return _modeFlags & DF_WANT_RECT_OPTIM;
    431433        default:
  • 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;
    82                 if (_adjustAspectRatio)
     80                event.mouse.x /= _videoMode.scaleFactor;
     81                event.mouse.y /= _videoMode.scaleFactor;
     82                if (_videoMode.aspectRatio)
    8383                        event.mouse.y = aspect2Real(event.mouse.y);
    8484        }
    8585}
     
    196196                        if (b == Common::KBD_ALT && (ev.key.keysym.sym == SDLK_RETURN
    197197                                          || ev.key.keysym.sym == SDLK_KP_ENTER)) {
    198198                                beginGFXTransaction();
    199                                 setFullscreenMode(!_fullscreen);
     199                                        setFullscreenMode(!_videoMode.fullscreen);
    200200                                endGFXTransaction();
    201201#ifdef USE_OSD
    202                                 if (_fullscreen)
     202                                if (_videoMode.fullscreen)
    203203                                        displayMessageOnOSD("Fullscreen mode");
    204204                                else
    205205                                        displayMessageOnOSD("Windowed mode");
  • backends/platform/sdl/sdl.h

     
    8585        virtual void initBackend();
    8686
    8787        void beginGFXTransaction(void);
    88         void endGFXTransaction(void);
     88        kTransactionError endGFXTransaction(void);
    8989
    9090        // Set the size of the video bitmap.
    9191        // Typically, 320x200
     
    183183        virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
    184184        virtual int16 getHeight();
    185185        virtual int16 getWidth();
    186         virtual int16 getOverlayHeight()  { return _overlayHeight; }
    187         virtual int16 getOverlayWidth()   { return _overlayWidth; }
     186        virtual int16 getOverlayHeight()  { return _videoMode.overlayHeight; }
     187        virtual int16 getOverlayWidth()   { return _videoMode.overlayWidth; }
    188188
    189189        // Methods that convert RGB to/from colors suitable for the overlay.
    190190        virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b);
     
    235235        // unseen game screen
    236236        SDL_Surface *_screen;
    237237
    238         // TODO: We could get rid of the following two vars and just use _screen instead
    239         int _screenWidth, _screenHeight;
    240 
    241238        // temporary screen (for scalers)
    242239        SDL_Surface *_tmpscreen;
    243240        SDL_Surface *_tmpscreen2;
    244241
    245242        // overlay
    246243        SDL_Surface *_overlayscreen;
    247         int _overlayWidth, _overlayHeight;
    248244        bool _overlayVisible;
    249245
    250246        // Audio
     
    261257
    262258        enum {
    263259                kTransactionNone = 0,
    264                 kTransactionCommit = 1,
    265                 kTransactionActive = 2
     260                kTransactionActive = 1,
     261                kTransactionRollback = 2
    266262        };
    267263
    268264        struct TransactionDetails {
    269                 int mode;
    270                 bool modeChanged;
    271                 int w;
    272                 int h;
    273265                bool sizeChanged;
    274                 bool fs;
    275                 bool fsChanged;
    276                 bool ar;
    277                 bool arChanged;
    278266                bool needHotswap;
    279267                bool needUpdatescreen;
    280                 bool needUnload;
    281                 bool needToggle;
    282268                bool normal1xScaler;
    283269        };
    284270        TransactionDetails _transactionDetails;
    285271
     272        struct VideoState {
     273                bool setup;
     274
     275                bool fullscreen;
     276                bool aspectRatio;
     277
     278                int mode;
     279                int scaleFactor;
     280
     281                int screenWidth, screenHeight;
     282                int overlayWidth, overlayHeight;
     283        };
     284        VideoState _videoMode, _oldVideoMode;
     285
     286        void setGraphicsModeIntern();
     287
    286288        /** Force full redraw on next updateScreen */
    287289        bool _forceFull;
    288290        ScalerProc *_scalerProc;
    289291        int _scalerType;
    290         int _scaleFactor;
    291         int _mode;
    292292        int _transactionMode;
    293         bool _fullscreen;
    294293
    295294        bool _screenIsLocked;
    296295        Graphics::Surface _framebuffer;
     
    300299        bool _modeChanged;
    301300        int _screenChangeCount;
    302301
    303         /** True if aspect ratio correction is enabled. */
    304         bool _adjustAspectRatio;
    305 
    306302        enum {
    307303                NUM_DIRTY_RECT = 100,
    308304                MAX_SCALING = 3
     
    425421
    426422        virtual void internUpdateScreen(); // overloaded by CE backend
    427423
    428         virtual void loadGFXMode(); // overloaded by CE backend
     424        virtual bool loadGFXMode(); // overloaded by CE backend
    429425        virtual void unloadGFXMode(); // overloaded by CE backend
    430         virtual void hotswapGFXMode(); // overloaded by CE backend
     426        virtual bool hotswapGFXMode(); // overloaded by CE backend
    431427
    432428        void setFullscreenMode(bool enable);
    433429        void setAspectRatioCorrection(bool enable);
     
    435431        virtual bool saveScreenshot(const char *filename); // overloaded by CE backend
    436432
    437433        int effectiveScreenHeight() const {
    438                 return (_adjustAspectRatio ? real2Aspect(_screenHeight) : _screenHeight)
    439                         * _scaleFactor;
     434                return (_videoMode.aspectRatio ? real2Aspect(_videoMode.screenHeight) : _videoMode.screenHeight)
     435                        * _videoMode.scaleFactor;
    440436        }
    441437
    442438        void setupIcon();