Ticket #8926: sdl_transaction_rollback_v3.1.patch

File sdl_transaction_rollback_v3.1.patch, 40.4 KB (added by lordhoto, 15 years ago)

Patch against r34845.

  • 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                        _videoMode.overlayWidth = _oldVideoMode.overlayWidth;
     128                        _videoMode.overlayHeight = _oldVideoMode.overlayHeight;
     129                }
     130
     131                if (_videoMode.fullscreen == _oldVideoMode.fullscreen &&
     132                        _videoMode.aspectRatio == _oldVideoMode.aspectRatio &&
     133                        _videoMode.mode == _oldVideoMode.mode &&
     134                        _videoMode.screenWidth == _oldVideoMode.screenWidth &&
     135                        _videoMode.screenHeight == _oldVideoMode.screenHeight) {
     136
     137                        // Our new video mode would now be exactly the same as the
     138                        // old one. Since we still can not assume SDL_SetVideoMode
     139                        // to be working fine, we need to invalidate the old video
     140                        // mode, so loadGFXMode would error out properly.
     141                        _oldVideoMode.setup = false;
     142                }
     143        }
     144
     145        if (_transactionDetails.sizeChanged) {
    129146                unloadGFXMode();
    130                 loadGFXMode();
    131                 clearOverlay();
    132         } else {
    133                 if (!_transactionDetails.fsChanged) {
    134                         if (_transactionDetails.needHotswap)
    135                                 hotswapGFXMode();
    136                         else if (_transactionDetails.needUpdatescreen)
     147                if (!loadGFXMode()) {
     148                        if (_oldVideoMode.setup) {
     149                                _transactionMode = kTransactionRollback;
     150                                errors |= endGFXTransaction();
     151                        }
     152                } else {
     153                        setGraphicsModeIntern();
     154                        clearOverlay();
     155
     156                        _videoMode.setup = true;
     157                        _modeChanged = true;
     158                }
     159        } else if (_transactionDetails.needHotswap) {
     160                setGraphicsModeIntern();
     161                if (!hotswapGFXMode()) {
     162                        if (_oldVideoMode.setup) {
     163                                _transactionMode = kTransactionRollback;
     164                                errors |= endGFXTransaction();
     165                        }
     166                } else {
     167                        _videoMode.setup = true;
     168                        _modeChanged = true;
     169
     170                        if (_transactionDetails.needUpdatescreen)
    137171                                internUpdateScreen();
    138172                }
    139173        }
    140174
    141         if (_transactionDetails.fsChanged)
    142                 setFullscreenMode(_transactionDetails.fs);
    143 
    144175        _transactionMode = kTransactionNone;
     176        return (kTransactionError)errors;
    145177}
    146178
    147179bool OSystem_SDL::setGraphicsMode(int mode) {
    148180        Common::StackLock lock(_graphicsMutex);
    149181
     182        assert(_transactionMode == kTransactionActive);
     183
     184        if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
     185                return true;
     186
    150187        int newScaleFactor = 1;
    151         ScalerProc *newScalerProc;
    152188
    153189        switch(mode) {
    154190        case GFX_NORMAL:
    155191                newScaleFactor = 1;
    156                 newScalerProc = Normal1x;
    157192                break;
    158193#ifndef DISABLE_SCALERS
    159194        case GFX_DOUBLESIZE:
    160195                newScaleFactor = 2;
    161                 newScalerProc = Normal2x;
    162196                break;
    163197        case GFX_TRIPLESIZE:
    164198                newScaleFactor = 3;
    165                 newScalerProc = Normal3x;
    166199                break;
    167200
    168201        case GFX_2XSAI:
    169202                newScaleFactor = 2;
    170                 newScalerProc = _2xSaI;
    171203                break;
    172204        case GFX_SUPER2XSAI:
    173205                newScaleFactor = 2;
    174                 newScalerProc = Super2xSaI;
    175206                break;
    176207        case GFX_SUPEREAGLE:
    177208                newScaleFactor = 2;
    178                 newScalerProc = SuperEagle;
    179209                break;
    180210        case GFX_ADVMAME2X:
    181211                newScaleFactor = 2;
    182                 newScalerProc = AdvMame2x;
    183212                break;
    184213        case GFX_ADVMAME3X:
    185214                newScaleFactor = 3;
    186                 newScalerProc = AdvMame3x;
    187215                break;
    188216#ifndef DISABLE_HQ_SCALERS
    189217        case GFX_HQ2X:
    190218                newScaleFactor = 2;
    191                 newScalerProc = HQ2x;
    192219                break;
    193220        case GFX_HQ3X:
    194221                newScaleFactor = 3;
    195                 newScalerProc = HQ3x;
    196222                break;
    197223#endif
    198224        case GFX_TV2X:
    199225                newScaleFactor = 2;
    200                 newScalerProc = TV2x;
    201226                break;
    202227        case GFX_DOTMATRIX:
    203228                newScaleFactor = 2;
    204                 newScalerProc = DotMatrix;
    205229                break;
    206230#endif // DISABLE_SCALERS
    207231
     
    211235        }
    212236
    213237        _transactionDetails.normal1xScaler = (mode == GFX_NORMAL);
     238        if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newScaleFactor)
     239                _transactionDetails.needHotswap = true;
    214240
    215         _mode = mode;
    216         _scalerProc = newScalerProc;
     241        _transactionDetails.needUpdatescreen = true;
    217242
    218         if (_transactionMode == kTransactionActive) {
    219                 _transactionDetails.mode = mode;
    220                 _transactionDetails.modeChanged = true;
     243        _videoMode.mode = mode;
     244        _videoMode.scaleFactor = newScaleFactor;
    221245
    222                 if (newScaleFactor != _scaleFactor) {
    223                         _transactionDetails.needHotswap = true;
    224                         _scaleFactor = newScaleFactor;
    225                 }
     246        return true;
     247}
    226248
    227                 _transactionDetails.needUpdatescreen = true;
     249void OSystem_SDL::setGraphicsModeIntern() {
     250        Common::StackLock lock(_graphicsMutex);
     251        ScalerProc *newScalerProc = 0;
    228252
    229                 return true;
    230         }
     253        switch (_videoMode.mode) {
     254        case GFX_NORMAL:
     255                newScalerProc = Normal1x;
     256                break;
     257#ifndef DISABLE_SCALERS
     258        case GFX_DOUBLESIZE:
     259                newScalerProc = Normal2x;
     260                break;
     261        case GFX_TRIPLESIZE:
     262                newScalerProc = Normal3x;
     263                break;
    231264
    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);
     265        case GFX_2XSAI:
     266                newScalerProc = _2xSaI;
     267                break;
     268        case GFX_SUPER2XSAI:
     269                newScalerProc = Super2xSaI;
     270                break;
     271        case GFX_SUPEREAGLE:
     272                newScalerProc = SuperEagle;
     273                break;
     274        case GFX_ADVMAME2X:
     275                newScalerProc = AdvMame2x;
     276                break;
     277        case GFX_ADVMAME3X:
     278                newScalerProc = AdvMame3x;
     279                break;
     280#ifndef DISABLE_HQ_SCALERS
     281        case GFX_HQ2X:
     282                newScalerProc = HQ2x;
     283                break;
     284        case GFX_HQ3X:
     285                newScalerProc = HQ3x;
     286                break;
     287#endif
     288        case GFX_TV2X:
     289                newScalerProc = TV2x;
     290                break;
     291        case GFX_DOTMATRIX:
     292                newScalerProc = DotMatrix;
     293                break;
     294#endif // DISABLE_SCALERS
    237295
    238                 _scaleFactor = newScaleFactor;
    239                 hotswapGFXMode();
     296        default:
     297                error("Unknown gfx mode %d", _videoMode.mode);
    240298        }
    241299
    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) {
     300        _scalerProc = newScalerProc;
     301       
     302        if (_videoMode.mode != GFX_NORMAL) {
    245303                for (int i = 0; i < ARRAYSIZE(s_gfxModeSwitchTable); i++) {
    246                         if (s_gfxModeSwitchTable[i][1] == _mode || s_gfxModeSwitchTable[i][2] == _mode) {
     304                        if (s_gfxModeSwitchTable[i][1] == _videoMode.mode || s_gfxModeSwitchTable[i][2] == _videoMode.mode) {
    247305                                _scalerType = i;
    248306                                break;
    249307                        }
    250308                }
    251309        }
    252310
    253         if (!_screen)
    254                 return true;
     311        if (!_screen || !_hwscreen)
     312                return;
    255313
    256314        // Blit everything to the screen
    257315        _forceFull = true;
     
    259317        // Even if the old and new scale factors are the same, we may have a
    260318        // different scaler for the cursor now.
    261319        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;
    270320}
    271321
    272322int OSystem_SDL::getGraphicsMode() const {
    273323        assert (_transactionMode == kTransactionNone);
    274         return _mode;
     324        return _videoMode.mode;
    275325}
    276326
    277327void OSystem_SDL::initSize(uint w, uint h) {
     328        assert(_transactionMode == kTransactionActive);
     329
    278330        // Avoid redundant res changes
    279         if ((int)w == _screenWidth && (int)h == _screenHeight &&
    280                 _transactionMode != kTransactionCommit)
     331        if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight)
    281332                return;
    282333
    283         _screenWidth = w;
    284         _screenHeight = h;
     334        _videoMode.screenWidth = w;
     335        _videoMode.screenHeight = h;
    285336
    286         _cksumNum = (_screenWidth * _screenHeight / (8 * 8));
     337        _cksumNum = (w * h / (8 * 8));
    287338
    288         if (_transactionMode == kTransactionActive) {
    289                 _transactionDetails.w = w;
    290                 _transactionDetails.h = h;
    291                 _transactionDetails.sizeChanged = true;
     339        _transactionDetails.sizeChanged = true;
    292340
    293                 _transactionDetails.needUnload = true;
    294 
    295                 return;
    296         }
    297 
    298341        free(_dirtyChecksums);
    299342        _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         }
    308343}
    309344
    310 void OSystem_SDL::loadGFXMode() {
     345bool OSystem_SDL::loadGFXMode() {
    311346        assert(_inited);
    312347        _forceFull = true;
    313348
    314349        int hwW, hwH;
    315350
    316351#ifndef __MAEMO__
    317         _overlayWidth = _screenWidth * _scaleFactor;
    318         _overlayHeight = _screenHeight * _scaleFactor;
     352        _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
     353        _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
    319354
    320         if (_screenHeight != 200 && _screenHeight != 400)
    321                 _adjustAspectRatio = false;
     355        if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400)
     356                _videoMode.aspectRatio = false;
    322357
    323         if (_adjustAspectRatio)
    324                 _overlayHeight = real2Aspect(_overlayHeight);
     358        if (_videoMode.aspectRatio)
     359                _videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
    325360
    326         hwW = _screenWidth * _scaleFactor;
     361        hwW = _videoMode.screenWidth * _videoMode.scaleFactor;
    327362        hwH = effectiveScreenHeight();
    328363#else
    329         hwW = _overlayWidth;
    330         hwH = _overlayHeight;
     364        hwW = _videoMode.overlayWidth;
     365        hwH = _videoMode.overlayHeight;
    331366#endif
    332367
    333368        //
    334369        // Create the surface that contains the 8 bit game data
    335370        //
    336         _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth, _screenHeight, 8, 0, 0, 0, 0);
     371        _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
    337372        if (_screen == NULL)
    338373                error("allocating _screen failed");
    339374
     
    342377        //
    343378
    344379        _hwscreen = SDL_SetVideoMode(hwW, hwH, 16,
    345                 _fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
     380                _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
    346381        );
    347382        if (_hwscreen == NULL) {
    348383                // DON'T use error(), as this tries to bring up the debug
    349384                // console, which WON'T WORK now that _hwscreen is hosed.
    350385
    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();
     386                if (!_oldVideoMode.setup) {
     387                        warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
     388                        quit();
     389                } else {
     390                        return false;
     391                }
    366392        }
    367393
    368394        //
     
    376402                InitScalers(565);
    377403
    378404        // Need some extra bytes around when using 2xSaI
    379         _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth + 3, _screenHeight + 3,
     405        _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3,
    380406                                                16,
    381407                                                _hwscreen->format->Rmask,
    382408                                                _hwscreen->format->Gmask,
     
    386412        if (_tmpscreen == NULL)
    387413                error("allocating _tmpscreen failed");
    388414
    389         _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth, _overlayHeight,
     415        _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight,
    390416                                                16,
    391417                                                _hwscreen->format->Rmask,
    392418                                                _hwscreen->format->Gmask,
     
    396422        if (_overlayscreen == NULL)
    397423                error("allocating _overlayscreen failed");
    398424
    399         _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth + 3, _overlayHeight + 3,
     425        _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3,
    400426                                                16,
    401427                                                _hwscreen->format->Rmask,
    402428                                                _hwscreen->format->Gmask,
     
    421447#endif
    422448
    423449        // keyboard cursor control, some other better place for it?
    424         _km.x_max = _screenWidth * _scaleFactor - 1;
     450        _km.x_max = _videoMode.screenWidth * _videoMode.scaleFactor - 1;
    425451        _km.y_max = effectiveScreenHeight() - 1;
    426452        _km.delay_time = 25;
    427453        _km.last_time = 0;
     454
     455        return true;
    428456}
    429457
    430458void OSystem_SDL::unloadGFXMode() {
     
    462490        DestroyScalers();
    463491}
    464492
    465 void OSystem_SDL::hotswapGFXMode() {
     493bool OSystem_SDL::hotswapGFXMode() {
    466494        if (!_screen)
    467                 return;
     495                return false;
    468496
    469497        // Keep around the old _screen & _overlayscreen so we can restore the screen data
    470498        // after the mode switch.
    471499        SDL_Surface *old_screen = _screen;
    472500        SDL_Surface *old_overlayscreen = _overlayscreen;
     501        _screen = NULL;
     502        _overlayscreen = NULL;
    473503
    474504        // Release the HW screen surface
    475         SDL_FreeSurface(_hwscreen);
     505        SDL_FreeSurface(_hwscreen); _hwscreen = NULL;
    476506
    477         SDL_FreeSurface(_tmpscreen);
    478         SDL_FreeSurface(_tmpscreen2);
     507        SDL_FreeSurface(_tmpscreen); _tmpscreen = NULL;
     508        SDL_FreeSurface(_tmpscreen2); _tmpscreen2 = NULL;
    479509
    480510#ifdef USE_OSD
    481511        // Release the OSD surface
    482         SDL_FreeSurface(_osdSurface);
     512        SDL_FreeSurface(_osdSurface); _osdSurface = NULL;
    483513#endif
    484514
    485515        // Setup the new GFX mode
    486         loadGFXMode();
     516        if (!loadGFXMode()) {
     517                unloadGFXMode();
    487518
     519                _screen = old_screen;
     520                _overlayscreen = old_overlayscreen;
     521
     522                return false;
     523        }
     524
    488525        // reset palette
    489526        SDL_SetColors(_screen, _currentPalette, 0, 256);
    490527
     
    502539        // Blit everything to the screen
    503540        internUpdateScreen();
    504541
    505         // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later
    506         _modeChanged = true;
     542        return true;
    507543}
    508544
    509545void OSystem_SDL::updateScreen() {
     
    527563
    528564        // If the shake position changed, fill the dirty area with blackness
    529565        if (_currentShakePos != _newShakePos) {
    530                 SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor};
     566                SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor};
    531567
    532                 if (_adjustAspectRatio && !_overlayVisible)
     568                if (_videoMode.aspectRatio && !_overlayVisible)
    533569                        blackrect.h = real2Aspect(blackrect.h - 1) + 1;
    534570
    535571                SDL_FillRect(_hwscreen, &blackrect, 0);
     
    574610        if (!_overlayVisible) {
    575611                origSurf = _screen;
    576612                srcSurf = _tmpscreen;
    577                 width = _screenWidth;
    578                 height = _screenHeight;
     613                width = _videoMode.screenWidth;
     614                height = _videoMode.screenHeight;
    579615                scalerProc = _scalerProc;
    580                 scale1 = _scaleFactor;
     616                scale1 = _videoMode.scaleFactor;
    581617        } else {
    582618                origSurf = _overlayscreen;
    583619                srcSurf = _tmpscreen2;
    584                 width = _overlayWidth;
    585                 height = _overlayHeight;
     620                width = _videoMode.overlayWidth;
     621                height = _videoMode.overlayHeight;
    586622                scalerProc = Normal1x;
    587623
    588624                scale1 = 1;
     
    635671                                orig_dst_y = dst_y;
    636672                                dst_y = dst_y * scale1;
    637673
    638                                 if (_adjustAspectRatio && !_overlayVisible)
     674                                if (_videoMode.aspectRatio && !_overlayVisible)
    639675                                        dst_y = real2Aspect(dst_y);
    640676
    641677                                assert(scalerProc != NULL);
     
    649685                        r->h = dst_h * scale1;
    650686
    651687#ifndef DISABLE_SCALERS
    652                         if (_adjustAspectRatio && orig_dst_y < height && !_overlayVisible)
     688                        if (_videoMode.aspectRatio && orig_dst_y < height && !_overlayVisible)
    653689                                r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
    654690#endif
    655691                }
     
    692728void OSystem_SDL::setFullscreenMode(bool enable) {
    693729        Common::StackLock lock(_graphicsMutex);
    694730       
    695         if (_fullscreen == enable)
     731        if (_oldVideoMode.setup && _oldVideoMode.fullscreen == enable)
    696732                return;
    697733
    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 
     734        if (_transactionMode == kTransactionActive) {
     735                _videoMode.fullscreen = enable;
    714736                _transactionDetails.needHotswap = true;
    715737        }
    716738}
    717739
    718740void OSystem_SDL::setAspectRatioCorrection(bool enable) {
    719         if (((_screenHeight == 200 || _screenHeight == 400) && _adjustAspectRatio != enable) ||
    720                 _transactionMode == kTransactionCommit) {
    721                 Common::StackLock lock(_graphicsMutex);
     741        Common::StackLock lock(_graphicsMutex);
    722742
    723                 //assert(_hwscreen != 0);
    724                 _adjustAspectRatio = enable;
     743        if (_oldVideoMode.setup && _oldVideoMode.aspectRatio == enable)
     744                return;
    725745
    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;
     746        if (_transactionMode == kTransactionActive) {
     747                _videoMode.aspectRatio = enable;
     748                _transactionDetails.needHotswap = true;
    740749        }
    741750}
    742751
     
    751760
    752761        Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
    753762
    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);
     763        assert(x >= 0 && x < _videoMode.screenWidth);
     764        assert(y >= 0 && y < _videoMode.screenHeight);
     765        assert(h > 0 && y + h <= _videoMode.screenHeight);
     766        assert(w > 0 && x + w <= _videoMode.screenWidth);
    758767
    759         if (((long)src & 3) == 0 && pitch == _screenWidth && x == 0 && y == 0 &&
    760                         w == _screenWidth && h == _screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) {
     768        if (((long)src & 3) == 0 && pitch == _videoMode.screenWidth && x == 0 && y == 0 &&
     769                        w == _videoMode.screenWidth && h == _videoMode.screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) {
    761770                /* Special, optimized case for full screen updates.
    762771                 * It tries to determine what areas were actually changed,
    763772                 * and just updates those, on the actual display. */
     
    776785                        y = 0;
    777786                }
    778787
    779                 if (w > _screenWidth - x) {
    780                         w = _screenWidth - x;
     788                if (w > _videoMode.screenWidth - x) {
     789                        w = _videoMode.screenWidth - x;
    781790                }
    782791
    783                 if (h > _screenHeight - y) {
    784                         h = _screenHeight - y;
     792                if (h > _videoMode.screenHeight - y) {
     793                        h = _videoMode.screenHeight - y;
    785794                }
    786795
    787796                if (w <= 0 || h <= 0)
     
    795804        if (SDL_LockSurface(_screen) == -1)
    796805                error("SDL_LockSurface failed: %s", SDL_GetError());
    797806
    798         byte *dst = (byte *)_screen->pixels + y * _screenWidth + x;
     807        byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
    799808
    800         if (_screenWidth == pitch && pitch == w) {
     809        if (_videoMode.screenWidth == pitch && pitch == w) {
    801810                memcpy(dst, src, h*w);
    802811        } else {
    803812                do {
    804813                        memcpy(dst, src, w);
    805814                        src += pitch;
    806                         dst += _screenWidth;
     815                        dst += _videoMode.screenWidth;
    807816                } while (--h);
    808817        }
    809818
     
    863872        int height, width;
    864873
    865874        if (!_overlayVisible && !realCoordinates) {
    866                 width = _screenWidth;
    867                 height = _screenHeight;
     875                width = _videoMode.screenWidth;
     876                height = _videoMode.screenHeight;
    868877        } else {
    869                 width = _overlayWidth;
    870                 height = _overlayHeight;
     878                width = _videoMode.overlayWidth;
     879                height = _videoMode.overlayHeight;
    871880        }
    872881
    873882        // Extend the dirty region by 1 pixel for scalers
     
    899908        }
    900909
    901910#ifndef DISABLE_SCALERS
    902         if (_adjustAspectRatio && !_overlayVisible && !realCoordinates) {
     911        if (_videoMode.aspectRatio && !_overlayVisible && !realCoordinates) {
    903912                makeRectStretchable(x, y, w, h);
    904913        }
    905914#endif
     
    924933        assert(buf);
    925934        uint32 *sums = _dirtyChecksums;
    926935        uint x,y;
    927         const uint last_x = (uint)_screenWidth / 8;
    928         const uint last_y = (uint)_screenHeight / 8;
     936        const uint last_x = (uint)_videoMode.screenWidth / 8;
     937        const uint last_y = (uint)_videoMode.screenHeight / 8;
    929938
    930939        const uint BASE = 65521; /* largest prime smaller than 65536 */
    931940
    932941        /* the 8x8 blocks in buf are enumerated starting in the top left corner and
    933942         * reading each line at a time from left to right */
    934         for (y = 0; y != last_y; y++, buf += _screenWidth * (8 - 1))
     943        for (y = 0; y != last_y; y++, buf += _videoMode.screenWidth * (8 - 1))
    935944                for (x = 0; x != last_x; x++, buf += 8) {
    936945                        // Adler32 checksum algorithm (from RFC1950, used by gzip and zlib).
    937946                        // This computes the Adler32 checksum of a 8x8 pixel block. Note
     
    947956                                        s1 += ptr[subX];
    948957                                        s2 += s1;
    949958                                }
    950                                 ptr += _screenWidth;
     959                                ptr += _videoMode.screenWidth;
    951960                        }
    952961
    953962                        s1 %= BASE;
     
    977986                int x, y, w;
    978987                uint32 *ck = _dirtyChecksums;
    979988
    980                 for (y = 0; y != _screenHeight / 8; y++) {
    981                         for (x = 0; x != _screenWidth / 8; x++, ck++) {
     989                for (y = 0; y != _videoMode.screenHeight / 8; y++) {
     990                        for (x = 0; x != _videoMode.screenWidth / 8; x++, ck++) {
    982991                                if (ck[0] != ck[_cksumNum]) {
    983992                                        /* found a dirty 8x8 block, now go as far to the right as possible,
    984993                                                 and at the same time, unmark the dirty status by setting old to new. */
     
    986995                                        do {
    987996                                                ck[w + _cksumNum] = ck[w];
    988997                                                w++;
    989                                         } while (x + w != _screenWidth / 8 && ck[w] != ck[w + _cksumNum]);
     998                                        } while (x + w != _videoMode.screenWidth / 8 && ck[w] != ck[w + _cksumNum]);
    990999
    9911000                                        addDirtyRect(x * 8, y * 8, w * 8, 8);
    9921001
     
    10031012}
    10041013
    10051014int16 OSystem_SDL::getHeight() {
    1006         return _screenHeight;
     1015        return _videoMode.screenHeight;
    10071016}
    10081017
    10091018int16 OSystem_SDL::getWidth() {
    1010         return _screenWidth;
     1019        return _videoMode.screenWidth;
    10111020}
    10121021
    10131022void OSystem_SDL::setPalette(const byte *colors, uint start, uint num) {
     
    10931102
    10941103        // Since resolution could change, put mouse to adjusted position
    10951104        // Fixes bug #1349059
    1096         x = _mouseCurState.x * _scaleFactor;
    1097         if (_adjustAspectRatio)
    1098                 y = real2Aspect(_mouseCurState.y) * _scaleFactor;
     1105        x = _mouseCurState.x * _videoMode.scaleFactor;
     1106        if (_videoMode.aspectRatio)
     1107                y = real2Aspect(_mouseCurState.y) * _videoMode.scaleFactor;
    10991108        else
    1100                 y = _mouseCurState.y * _scaleFactor;
     1109                y = _mouseCurState.y * _videoMode.scaleFactor;
    11011110
    11021111        warpMouse(x, y);
    11031112
     
    11161125
    11171126        // Since resolution could change, put mouse to adjusted position
    11181127        // Fixes bug #1349059
    1119         x = _mouseCurState.x / _scaleFactor;
    1120         y = _mouseCurState.y / _scaleFactor;
    1121         if (_adjustAspectRatio)
     1128        x = _mouseCurState.x / _videoMode.scaleFactor;
     1129        y = _mouseCurState.y / _videoMode.scaleFactor;
     1130        if (_videoMode.aspectRatio)
    11221131                y = aspect2Real(y);
    11231132
    11241133        warpMouse(x, y);
     
    11401149        SDL_Rect src, dst;
    11411150        src.x = src.y = 0;
    11421151        dst.x = dst.y = 1;
    1143         src.w = dst.w = _screenWidth;
    1144         src.h = dst.h = _screenHeight;
     1152        src.w = dst.w = _videoMode.screenWidth;
     1153        src.h = dst.h = _videoMode.screenHeight;
    11451154        if (SDL_BlitSurface(_screen, &src, _tmpscreen, &dst) != 0)
    11461155                error("SDL_BlitSurface failed: %s", SDL_GetError());
    11471156
    11481157        SDL_LockSurface(_tmpscreen);
    11491158        SDL_LockSurface(_overlayscreen);
    11501159        _scalerProc((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2, _tmpscreen->pitch,
    1151         (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight);
     1160        (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _videoMode.screenWidth, _videoMode.screenHeight);
    11521161
    11531162#ifndef DISABLE_SCALERS
    1154         if (_adjustAspectRatio)
     1163        if (_videoMode.aspectRatio)
    11551164                stretch200To240((uint8 *)_overlayscreen->pixels, _overlayscreen->pitch,
    1156                                                 _overlayWidth, _screenHeight * _scaleFactor, 0, 0, 0);
     1165                                                _videoMode.overlayWidth, _videoMode.screenHeight * _videoMode.scaleFactor, 0, 0, 0);
    11571166#endif
    11581167        SDL_UnlockSurface(_tmpscreen);
    11591168        SDL_UnlockSurface(_overlayscreen);
     
    11711180                error("SDL_LockSurface failed: %s", SDL_GetError());
    11721181
    11731182        byte *src = (byte *)_overlayscreen->pixels;
    1174         int h = _overlayHeight;
     1183        int h = _videoMode.overlayHeight;
    11751184        do {
    1176                 memcpy(buf, src, _overlayWidth * 2);
     1185                memcpy(buf, src, _videoMode.overlayWidth * 2);
    11771186                src += _overlayscreen->pitch;
    11781187                buf += pitch;
    11791188        } while (--h);
     
    11991208                y = 0;
    12001209        }
    12011210
    1202         if (w > _overlayWidth - x) {
    1203                 w = _overlayWidth - x;
     1211        if (w > _videoMode.overlayWidth - x) {
     1212                w = _videoMode.overlayWidth - x;
    12041213        }
    12051214
    1206         if (h > _overlayHeight - y) {
    1207                 h = _overlayHeight - y;
     1215        if (h > _videoMode.overlayHeight - y) {
     1216                h = _videoMode.overlayHeight - y;
    12081217        }
    12091218
    12101219        if (w <= 0 || h <= 0)
     
    12601269void OSystem_SDL::warpMouse(int x, int y) {
    12611270        int y1 = y;
    12621271
    1263         if (_adjustAspectRatio && !_overlayVisible)
     1272        if (_videoMode.aspectRatio && !_overlayVisible)
    12641273                y1 = real2Aspect(y);
    12651274
    12661275        if (_mouseCurState.x != x || _mouseCurState.y != y) {
    12671276                if (!_overlayVisible)
    1268                         SDL_WarpMouse(x * _scaleFactor, y1 * _scaleFactor);
     1277                        SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor);
    12691278                else
    12701279                        SDL_WarpMouse(x, y1);
    12711280
     
    13681377
    13691378        int rW, rH;
    13701379
    1371         if (_cursorTargetScale >= _scaleFactor) {
     1380        if (_cursorTargetScale >= _videoMode.scaleFactor) {
    13721381                // The cursor target scale is greater or equal to the scale at
    13731382                // which the rest of the screen is drawn. We do not downscale
    13741383                // the cursor image, we draw it at its original size. It will
     
    13811390
    13821391                // The virtual dimensions may be larger than the original.
    13831392
    1384                 _mouseCurState.vW = w * _cursorTargetScale / _scaleFactor;
    1385                 _mouseCurState.vH = h * _cursorTargetScale / _scaleFactor;
     1393                _mouseCurState.vW = w * _cursorTargetScale / _videoMode.scaleFactor;
     1394                _mouseCurState.vH = h * _cursorTargetScale / _videoMode.scaleFactor;
    13861395                _mouseCurState.vHotX = _mouseCurState.hotX * _cursorTargetScale /
    1387                         _scaleFactor;
     1396                        _videoMode.scaleFactor;
    13881397                _mouseCurState.vHotY = _mouseCurState.hotY * _cursorTargetScale /
    1389                         _scaleFactor;
     1398                        _videoMode.scaleFactor;
    13901399        } else {
    13911400                // The cursor target scale is smaller than the scale at which
    13921401                // the rest of the screen is drawn. We scale up the cursor
    13931402                // image to make it appear correct.
    13941403
    1395                 rW = w * _scaleFactor / _cursorTargetScale;
    1396                 rH = h * _scaleFactor / _cursorTargetScale;
    1397                 _mouseCurState.rHotX = _mouseCurState.hotX * _scaleFactor /
     1404                rW = w * _videoMode.scaleFactor / _cursorTargetScale;
     1405                rH = h * _videoMode.scaleFactor / _cursorTargetScale;
     1406                _mouseCurState.rHotX = _mouseCurState.hotX * _videoMode.scaleFactor /
    13981407                        _cursorTargetScale;
    1399                 _mouseCurState.rHotY = _mouseCurState.hotY * _scaleFactor /
     1408                _mouseCurState.rHotY = _mouseCurState.hotY * _videoMode.scaleFactor /
    14001409                        _cursorTargetScale;
    14011410
    14021411                // The virtual dimensions will be the same as the original.
     
    14111420        int rH1 = rH; // store original to pass to aspect-correction function later
    14121421#endif
    14131422
    1414         if (_adjustAspectRatio && _cursorTargetScale == 1) {
     1423        if (_videoMode.aspectRatio && _cursorTargetScale == 1) {
    14151424                rH = real2Aspect(rH - 1) + 1;
    14161425                _mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
    14171426        }
     
    14461455        // the game. This only works well with the non-blurring scalers so we
    14471456        // actually only use the 1x, 1.5x, 2x and AdvMame scalers.
    14481457
    1449         if (_cursorTargetScale == 1 && (_mode == GFX_DOUBLESIZE || _mode == GFX_TRIPLESIZE))
     1458        if (_cursorTargetScale == 1 && (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE))
    14501459                scalerProc = _scalerProc;
    14511460        else
    1452                 scalerProc = scalersMagn[_cursorTargetScale - 1][_scaleFactor - 1];
     1461                scalerProc = scalersMagn[_cursorTargetScale - 1][_videoMode.scaleFactor - 1];
    14531462
    14541463        scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2,
    14551464                _mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch,
    14561465                _mouseCurState.w, _mouseCurState.h);
    14571466
    14581467#ifndef DISABLE_SCALERS
    1459         if (_adjustAspectRatio && _cursorTargetScale == 1)
     1468        if (_videoMode.aspectRatio && _cursorTargetScale == 1)
    14601469                cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, rW, rH1, 0, 0, 0);
    14611470#endif
    14621471
     
    14991508
    15001509        // When we switch bigger overlay off mouse jumps. Argh!
    15011510        // This is intended to prevent undrawing offscreen mouse
    1502         if (!_overlayVisible && (x >= _screenWidth || y >= _screenHeight)) {
     1511        if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight)) {
    15031512                return;
    15041513        }
    15051514
     
    15221531        dst.y = _mouseCurState.y;
    15231532
    15241533        if (!_overlayVisible) {
    1525                 scale = _scaleFactor;
    1526                 width = _screenWidth;
    1527                 height = _screenHeight;
     1534                scale = _videoMode.scaleFactor;
     1535                width = _videoMode.screenWidth;
     1536                height = _videoMode.screenHeight;
    15281537                dst.w = _mouseCurState.vW;
    15291538                dst.h = _mouseCurState.vH;
    15301539                hotX = _mouseCurState.vHotX;
    15311540                hotY = _mouseCurState.vHotY;
    15321541        } else {
    15331542                scale = 1;
    1534                 width = _overlayWidth;
    1535                 height = _overlayHeight;
     1543                width = _videoMode.overlayWidth;
     1544                height = _videoMode.overlayHeight;
    15361545                dst.w = _mouseCurState.rW;
    15371546                dst.h = _mouseCurState.rH;
    15381547                hotX = _mouseCurState.rHotX;
     
    15541563                dst.y += _currentShakePos;
    15551564        }
    15561565
    1557         if (_adjustAspectRatio && !_overlayVisible)
     1566        if (_videoMode.aspectRatio && !_overlayVisible)
    15581567                dst.y = real2Aspect(dst.y);
    15591568
    15601569        dst.x = scale * dst.x - _mouseCurState.rHotX;
     
    16701679void OSystem_SDL::handleScalerHotkeys(const SDL_KeyboardEvent &key) {
    16711680        // Ctrl-Alt-a toggles aspect ratio correction
    16721681        if (key.keysym.sym == 'a') {
    1673                 setFeatureState(kFeatureAspectRatioCorrection, !_adjustAspectRatio);
     1682                beginGFXTransaction();
     1683                        setFeatureState(kFeatureAspectRatioCorrection, !_videoMode.aspectRatio);
     1684                endGFXTransaction();
    16741685#ifdef USE_OSD
    16751686                char buffer[128];
    1676                 if (_adjustAspectRatio)
     1687                if (_videoMode.aspectRatio)
    16771688                        sprintf(buffer, "Enabled aspect ratio correction\n%d x %d -> %d x %d",
    1678                                 _screenWidth, _screenHeight,
     1689                                _videoMode.screenWidth, _videoMode.screenHeight,
    16791690                                _hwscreen->w, _hwscreen->h
    16801691                                );
    16811692                else
    16821693                        sprintf(buffer, "Disabled aspect ratio correction\n%d x %d -> %d x %d",
    1683                                 _screenWidth, _screenHeight,
     1694                                _videoMode.screenWidth, _videoMode.screenHeight,
    16841695                                _hwscreen->w, _hwscreen->h
    16851696                                );
    16861697                displayMessageOnOSD(buffer);
     
    16901701        }
    16911702
    16921703        int newMode = -1;
    1693         int factor = _scaleFactor - 1;
     1704        int factor = _videoMode.scaleFactor - 1;
    16941705
    16951706        // Increase/decrease the scale factor
    16961707        if (key.keysym.sym == SDLK_EQUALS || key.keysym.sym == SDLK_PLUS || key.keysym.sym == SDLK_MINUS ||
     
    17161727        }
    17171728
    17181729        if (newMode >= 0) {
    1719                 setGraphicsMode(newMode);
     1730                beginGFXTransaction();
     1731                        setGraphicsMode(newMode);
     1732                endGFXTransaction();
    17201733#ifdef USE_OSD
    17211734                if (_osdSurface) {
    17221735                        const char *newScalerName = 0;
    17231736                        const GraphicsMode *g = getSupportedGraphicsModes();
    17241737                        while (g->name) {
    1725                                 if (g->id == _mode) {
     1738                                if (g->id == _videoMode.mode) {
    17261739                                        newScalerName = g->description;
    17271740                                        break;
    17281741                                }
     
    17321745                                char buffer[128];
    17331746                                sprintf(buffer, "Active graphics filter: %s\n%d x %d -> %d x %d",
    17341747                                        newScalerName,
    1735                                         _screenWidth, _screenHeight,
     1748                                        _videoMode.screenWidth, _videoMode.screenHeight,
    17361749                                        _hwscreen->w, _hwscreen->h
    17371750                                        );
    17381751                                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),
     
    421423
    422424        switch (f) {
    423425        case kFeatureFullscreenMode:
    424                 return _fullscreen;
     426                return _videoMode.fullscreen;
    425427        case kFeatureAspectRatioCorrection:
    426                 return _adjustAspectRatio;
     428                return _videoMode.aspectRatio;
    427429        case kFeatureAutoComputeDirtyRects:
    428430                return _modeFlags & DF_WANT_RECT_OPTIM;
    429431        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();