Ticket #8926: sdl_transaction_rollback_v2.patch

File sdl_transaction_rollback_v2.patch, 37.2 KB (added by lordhoto, 16 years ago)

Patch against r34636

  • 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
    105103void OSystem_SDL::endGFXTransaction(void) {
     104        assert(_transactionMode != kTransactionNone);
     105
     106        if (_transactionMode == kTransactionRollback) {
     107                _videoMode = _oldVideoMode;
     108
     109                // Since loadGFXMode relies on _oldVideoMode.setup to be true
     110                // if there was a mode setup before, we clear it so if resetting
     111                // to the old video mode does not start a endless reset loop
     112                // instead of erroring out
     113                _oldVideoMode.setup = false;
     114        }
     115
    106116        // for each engine we run initCommonGFX() as first thing in the transaction
    107117        // 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
     118        // 2x overlay, setting to Normal1x scaler in that case will be suppressed
    109119        // and backend is forced to 2x
    110120        //
    111121        // This leads to bad results such as 1280x960 window for 640x480 engines.
    112122        // To prevent that we rerun setGraphicsMode() if there was 1x scaler request
    113         if (_transactionDetails.normal1xScaler)
     123        if (_transactionMode != kTransactionRollback && _transactionDetails.normal1xScaler)
    114124                setGraphicsMode(GFX_NORMAL);
    115125
    116         assert (_transactionMode == kTransactionActive);
    117 
    118         _transactionMode = kTransactionCommit;
    119         if (_transactionDetails.modeChanged)
    120                 setGraphicsMode(_transactionDetails.mode);
    121 
    122         if (_transactionDetails.sizeChanged)
    123                 initSize(_transactionDetails.w, _transactionDetails.h);
    124 
    125         if (_transactionDetails.arChanged)
    126                 setAspectRatioCorrection(_transactionDetails.ar);
    127 
    128         if (_transactionDetails.needUnload) {
     126        if (_transactionDetails.sizeChanged) {
    129127                unloadGFXMode();
    130128                loadGFXMode();
     129                setGraphicsModeIntern();
    131130                clearOverlay();
    132         } else {
    133                 if (!_transactionDetails.fsChanged) {
    134                         if (_transactionDetails.needHotswap)
    135                                 hotswapGFXMode();
    136                         else if (_transactionDetails.needUpdatescreen)
    137                                 internUpdateScreen();
    138                 }
    139         }
    140131
    141         if (_transactionDetails.fsChanged)
    142                 setFullscreenMode(_transactionDetails.fs);
     132                _videoMode.setup = true;
     133                _modeChanged = true;
     134        } else if (_transactionDetails.needHotswap) {
     135                setGraphicsModeIntern();
     136                hotswapGFXMode();
    143137
     138                _videoMode.setup = true;
     139                _modeChanged = true;
     140
     141                if (_transactionDetails.needUpdatescreen)
     142                        internUpdateScreen();
     143        }
     144
    144145        _transactionMode = kTransactionNone;
     146
     147        // TODO: endGFXTransaction should indicate error/success
    145148}
    146149
    147150bool OSystem_SDL::setGraphicsMode(int mode) {
    148151        Common::StackLock lock(_graphicsMutex);
    149152
     153        assert(_transactionMode == kTransactionActive);
     154
     155        if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
     156                return true;
     157
    150158        int newScaleFactor = 1;
    151         ScalerProc *newScalerProc;
    152159
    153160        switch(mode) {
    154161        case GFX_NORMAL:
    155162                newScaleFactor = 1;
    156                 newScalerProc = Normal1x;
    157163                break;
    158164#ifndef DISABLE_SCALERS
    159165        case GFX_DOUBLESIZE:
    160166                newScaleFactor = 2;
    161                 newScalerProc = Normal2x;
    162167                break;
    163168        case GFX_TRIPLESIZE:
    164169                newScaleFactor = 3;
    165                 newScalerProc = Normal3x;
    166170                break;
    167171
    168172        case GFX_2XSAI:
    169173                newScaleFactor = 2;
    170                 newScalerProc = _2xSaI;
    171174                break;
    172175        case GFX_SUPER2XSAI:
    173176                newScaleFactor = 2;
    174                 newScalerProc = Super2xSaI;
    175177                break;
    176178        case GFX_SUPEREAGLE:
    177179                newScaleFactor = 2;
    178                 newScalerProc = SuperEagle;
    179180                break;
    180181        case GFX_ADVMAME2X:
    181182                newScaleFactor = 2;
    182                 newScalerProc = AdvMame2x;
    183183                break;
    184184        case GFX_ADVMAME3X:
    185185                newScaleFactor = 3;
    186                 newScalerProc = AdvMame3x;
    187186                break;
    188187#ifndef DISABLE_HQ_SCALERS
    189188        case GFX_HQ2X:
    190189                newScaleFactor = 2;
    191                 newScalerProc = HQ2x;
    192190                break;
    193191        case GFX_HQ3X:
    194192                newScaleFactor = 3;
    195                 newScalerProc = HQ3x;
    196193                break;
    197194#endif
    198195        case GFX_TV2X:
    199196                newScaleFactor = 2;
    200                 newScalerProc = TV2x;
    201197                break;
    202198        case GFX_DOTMATRIX:
    203199                newScaleFactor = 2;
    204                 newScalerProc = DotMatrix;
    205200                break;
    206201#endif // DISABLE_SCALERS
    207202
     
    211206        }
    212207
    213208        _transactionDetails.normal1xScaler = (mode == GFX_NORMAL);
     209        if (_oldVideoMode.setup && _oldVideoMode.scaleFactor != newScaleFactor)
     210                _transactionDetails.needHotswap = true;
    214211
    215         _mode = mode;
    216         _scalerProc = newScalerProc;
     212        _transactionDetails.needUpdatescreen = true;
    217213
    218         if (_transactionMode == kTransactionActive) {
    219                 _transactionDetails.mode = mode;
    220                 _transactionDetails.modeChanged = true;
     214        _videoMode.mode = mode;
     215        _videoMode.scaleFactor = newScaleFactor;
    221216
    222                 if (newScaleFactor != _scaleFactor) {
    223                         _transactionDetails.needHotswap = true;
    224                         _scaleFactor = newScaleFactor;
    225                 }
     217        return true;
     218}
    226219
    227                 _transactionDetails.needUpdatescreen = true;
     220void OSystem_SDL::setGraphicsModeIntern() {
     221        Common::StackLock lock(_graphicsMutex);
     222        ScalerProc *newScalerProc = 0;
    228223
    229                 return true;
    230         }
     224        switch (_videoMode.mode) {
     225        case GFX_NORMAL:
     226                newScalerProc = Normal1x;
     227                break;
     228#ifndef DISABLE_SCALERS
     229        case GFX_DOUBLESIZE:
     230                newScalerProc = Normal2x;
     231                break;
     232        case GFX_TRIPLESIZE:
     233                newScalerProc = Normal3x;
     234                break;
    231235
    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);
     236        case GFX_2XSAI:
     237                newScalerProc = _2xSaI;
     238                break;
     239        case GFX_SUPER2XSAI:
     240                newScalerProc = Super2xSaI;
     241                break;
     242        case GFX_SUPEREAGLE:
     243                newScalerProc = SuperEagle;
     244                break;
     245        case GFX_ADVMAME2X:
     246                newScalerProc = AdvMame2x;
     247                break;
     248        case GFX_ADVMAME3X:
     249                newScalerProc = AdvMame3x;
     250                break;
     251#ifndef DISABLE_HQ_SCALERS
     252        case GFX_HQ2X:
     253                newScalerProc = HQ2x;
     254                break;
     255        case GFX_HQ3X:
     256                newScalerProc = HQ3x;
     257                break;
     258#endif
     259        case GFX_TV2X:
     260                newScalerProc = TV2x;
     261                break;
     262        case GFX_DOTMATRIX:
     263                newScalerProc = DotMatrix;
     264                break;
     265#endif // DISABLE_SCALERS
    237266
    238                 _scaleFactor = newScaleFactor;
    239                 hotswapGFXMode();
     267        default:
     268                error("Unknown gfx mode %d", _videoMode.mode);
    240269        }
    241270
    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) {
     271        _scalerProc = newScalerProc;
     272       
     273        if (_videoMode.mode != GFX_NORMAL) {
    245274                for (int i = 0; i < ARRAYSIZE(s_gfxModeSwitchTable); i++) {
    246                         if (s_gfxModeSwitchTable[i][1] == _mode || s_gfxModeSwitchTable[i][2] == _mode) {
     275                        if (s_gfxModeSwitchTable[i][1] == _videoMode.mode || s_gfxModeSwitchTable[i][2] == _videoMode.mode) {
    247276                                _scalerType = i;
    248277                                break;
    249278                        }
    250279                }
    251280        }
    252281
    253         if (!_screen)
    254                 return true;
     282        if (!_screen || !_hwscreen)
     283                return;
    255284
    256285        // Blit everything to the screen
    257286        _forceFull = true;
     
    259288        // Even if the old and new scale factors are the same, we may have a
    260289        // different scaler for the cursor now.
    261290        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;
    270291}
    271292
    272293int OSystem_SDL::getGraphicsMode() const {
    273294        assert (_transactionMode == kTransactionNone);
    274         return _mode;
     295        return _videoMode.mode;
    275296}
    276297
    277298void OSystem_SDL::initSize(uint w, uint h) {
     299        assert(_transactionMode == kTransactionActive);
     300
    278301        // Avoid redundant res changes
    279         if ((int)w == _screenWidth && (int)h == _screenHeight &&
    280                 _transactionMode != kTransactionCommit)
     302        if ((int)w == _videoMode.screenWidth && (int)h == _videoMode.screenHeight)
    281303                return;
    282304
    283         _screenWidth = w;
    284         _screenHeight = h;
     305        _videoMode.screenWidth = w;
     306        _videoMode.screenHeight = h;
    285307
    286         _cksumNum = (_screenWidth * _screenHeight / (8 * 8));
     308        _cksumNum = (w * h / (8 * 8));
    287309
    288         if (_transactionMode == kTransactionActive) {
    289                 _transactionDetails.w = w;
    290                 _transactionDetails.h = h;
    291                 _transactionDetails.sizeChanged = true;
     310        _transactionDetails.sizeChanged = true;
    292311
    293                 _transactionDetails.needUnload = true;
    294 
    295                 return;
    296         }
    297 
    298312        free(_dirtyChecksums);
    299313        _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         }
    308314}
    309315
    310 void OSystem_SDL::loadGFXMode() {
     316bool OSystem_SDL::loadGFXMode() {
    311317        assert(_inited);
    312318        _forceFull = true;
    313319
    314320        int hwW, hwH;
    315321
    316322#ifndef __MAEMO__
    317         _overlayWidth = _screenWidth * _scaleFactor;
    318         _overlayHeight = _screenHeight * _scaleFactor;
     323        _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
     324        _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
    319325
    320         if (_screenHeight != 200 && _screenHeight != 400)
    321                 _adjustAspectRatio = false;
     326        if (_videoMode.screenHeight != 200 && _videoMode.screenHeight != 400)
     327                _videoMode.aspectRatio = false;
    322328
    323         if (_adjustAspectRatio)
    324                 _overlayHeight = real2Aspect(_overlayHeight);
     329        if (_videoMode.aspectRatio)
     330                _videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
    325331
    326         hwW = _screenWidth * _scaleFactor;
     332        hwW = _videoMode.screenWidth * _videoMode.scaleFactor;
    327333        hwH = effectiveScreenHeight();
    328334#else
    329         hwW = _overlayWidth;
    330         hwH = _overlayHeight;
     335        hwW = _videoMode.overlayWidth;
     336        hwH = _videoMode.overlayHeight;
    331337#endif
    332338
    333339        //
    334340        // Create the surface that contains the 8 bit game data
    335341        //
    336         _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth, _screenHeight, 8, 0, 0, 0, 0);
     342        _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth, _videoMode.screenHeight, 8, 0, 0, 0, 0);
    337343        if (_screen == NULL)
    338344                error("allocating _screen failed");
    339345
     
    342348        //
    343349
    344350        _hwscreen = SDL_SetVideoMode(hwW, hwH, 16,
    345                 _fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
     351                _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
    346352        );
    347353        if (_hwscreen == NULL) {
    348354                // DON'T use error(), as this tries to bring up the debug
    349355                // console, which WON'T WORK now that _hwscreen is hosed.
    350356
    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();
     357                if (!_oldVideoMode.setup) {
     358                        warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
     359                        quit();
     360                } else {
     361                        return false;
     362                }
    366363        }
    367364
    368365        //
     
    376373                InitScalers(565);
    377374
    378375        // Need some extra bytes around when using 2xSaI
    379         _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth + 3, _screenHeight + 3,
     376        _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.screenWidth + 3, _videoMode.screenHeight + 3,
    380377                                                16,
    381378                                                _hwscreen->format->Rmask,
    382379                                                _hwscreen->format->Gmask,
     
    386383        if (_tmpscreen == NULL)
    387384                error("allocating _tmpscreen failed");
    388385
    389         _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth, _overlayHeight,
     386        _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth, _videoMode.overlayHeight,
    390387                                                16,
    391388                                                _hwscreen->format->Rmask,
    392389                                                _hwscreen->format->Gmask,
     
    396393        if (_overlayscreen == NULL)
    397394                error("allocating _overlayscreen failed");
    398395
    399         _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth + 3, _overlayHeight + 3,
     396        _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _videoMode.overlayWidth + 3, _videoMode.overlayHeight + 3,
    400397                                                16,
    401398                                                _hwscreen->format->Rmask,
    402399                                                _hwscreen->format->Gmask,
     
    421418#endif
    422419
    423420        // keyboard cursor control, some other better place for it?
    424         _km.x_max = _screenWidth * _scaleFactor - 1;
     421        _km.x_max = _videoMode.screenWidth * _videoMode.scaleFactor - 1;
    425422        _km.y_max = effectiveScreenHeight() - 1;
    426423        _km.delay_time = 25;
    427424        _km.last_time = 0;
     425
     426        return true;
    428427}
    429428
    430429void OSystem_SDL::unloadGFXMode() {
     
    470469        // after the mode switch.
    471470        SDL_Surface *old_screen = _screen;
    472471        SDL_Surface *old_overlayscreen = _overlayscreen;
     472        _screen = NULL;
     473        _overlayscreen = NULL;
    473474
    474475        // Release the HW screen surface
    475         SDL_FreeSurface(_hwscreen);
     476        SDL_FreeSurface(_hwscreen); _hwscreen = NULL;
    476477
    477         SDL_FreeSurface(_tmpscreen);
    478         SDL_FreeSurface(_tmpscreen2);
     478        SDL_FreeSurface(_tmpscreen); _tmpscreen = NULL;
     479        SDL_FreeSurface(_tmpscreen2); _tmpscreen2 = NULL;
    479480
    480481#ifdef USE_OSD
    481482        // Release the OSD surface
    482         SDL_FreeSurface(_osdSurface);
     483        SDL_FreeSurface(_osdSurface); _osdSurface = NULL;
    483484#endif
    484485
    485486        // Setup the new GFX mode
    486         loadGFXMode();
     487        if (!loadGFXMode()) {
     488                unloadGFXMode();
    487489
     490                _screen = old_screen;
     491                _overlayscreen = old_overlayscreen;
     492
     493                _transactionMode = kTransactionRollback;
     494                // TODO: endGFXTransaction should indicate error/success which we should rather
     495                // return to caller instead of doing this
     496                endGFXTransaction();
     497                return;
     498        }
     499
    488500        // reset palette
    489501        SDL_SetColors(_screen, _currentPalette, 0, 256);
    490502
     
    501513
    502514        // Blit everything to the screen
    503515        internUpdateScreen();
    504 
    505         // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later
    506         _modeChanged = true;
    507516}
    508517
    509518void OSystem_SDL::updateScreen() {
     
    527536
    528537        // If the shake position changed, fill the dirty area with blackness
    529538        if (_currentShakePos != _newShakePos) {
    530                 SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor};
     539                SDL_Rect blackrect = {0, 0, _videoMode.screenWidth * _videoMode.scaleFactor, _newShakePos * _videoMode.scaleFactor};
    531540
    532                 if (_adjustAspectRatio && !_overlayVisible)
     541                if (_videoMode.aspectRatio && !_overlayVisible)
    533542                        blackrect.h = real2Aspect(blackrect.h - 1) + 1;
    534543
    535544                SDL_FillRect(_hwscreen, &blackrect, 0);
     
    574583        if (!_overlayVisible) {
    575584                origSurf = _screen;
    576585                srcSurf = _tmpscreen;
    577                 width = _screenWidth;
    578                 height = _screenHeight;
     586                width = _videoMode.screenWidth;
     587                height = _videoMode.screenHeight;
    579588                scalerProc = _scalerProc;
    580                 scale1 = _scaleFactor;
     589                scale1 = _videoMode.scaleFactor;
    581590        } else {
    582591                origSurf = _overlayscreen;
    583592                srcSurf = _tmpscreen2;
    584                 width = _overlayWidth;
    585                 height = _overlayHeight;
     593                width = _videoMode.overlayWidth;
     594                height = _videoMode.overlayHeight;
    586595                scalerProc = Normal1x;
    587596
    588597                scale1 = 1;
     
    635644                                orig_dst_y = dst_y;
    636645                                dst_y = dst_y * scale1;
    637646
    638                                 if (_adjustAspectRatio && !_overlayVisible)
     647                                if (_videoMode.aspectRatio && !_overlayVisible)
    639648                                        dst_y = real2Aspect(dst_y);
    640649
    641650                                assert(scalerProc != NULL);
     
    649658                        r->h = dst_h * scale1;
    650659
    651660#ifndef DISABLE_SCALERS
    652                         if (_adjustAspectRatio && orig_dst_y < height && !_overlayVisible)
     661                        if (_videoMode.aspectRatio && orig_dst_y < height && !_overlayVisible)
    653662                                r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y * scale1);
    654663#endif
    655664                }
     
    692701void OSystem_SDL::setFullscreenMode(bool enable) {
    693702        Common::StackLock lock(_graphicsMutex);
    694703       
    695         if (_fullscreen == enable)
     704        if (_oldVideoMode.setup && _oldVideoMode.fullscreen == enable)
    696705                return;
    697706
    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 
     707        if (_transactionMode == kTransactionActive) {
     708                _videoMode.fullscreen = enable;
    714709                _transactionDetails.needHotswap = true;
    715710        }
    716711}
    717712
    718713void OSystem_SDL::setAspectRatioCorrection(bool enable) {
    719         if (((_screenHeight == 200 || _screenHeight == 400) && _adjustAspectRatio != enable) ||
    720                 _transactionMode == kTransactionCommit) {
    721                 Common::StackLock lock(_graphicsMutex);
     714        Common::StackLock lock(_graphicsMutex);
    722715
    723                 //assert(_hwscreen != 0);
    724                 _adjustAspectRatio = enable;
     716        if (_oldVideoMode.setup && _oldVideoMode.aspectRatio == enable)
     717                return;
    725718
    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;
     719        if (_transactionMode == kTransactionActive) {
     720                _videoMode.aspectRatio = enable;
     721                _transactionDetails.needHotswap = true;
    740722        }
    741723}
    742724
     
    751733
    752734        Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends
    753735
    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);
     736        assert(x >= 0 && x < _videoMode.screenWidth);
     737        assert(y >= 0 && y < _videoMode.screenHeight);
     738        assert(h > 0 && y + h <= _videoMode.screenHeight);
     739        assert(w > 0 && x + w <= _videoMode.screenWidth);
    758740
    759         if (((long)src & 3) == 0 && pitch == _screenWidth && x == 0 && y == 0 &&
    760                         w == _screenWidth && h == _screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) {
     741        if (((long)src & 3) == 0 && pitch == _videoMode.screenWidth && x == 0 && y == 0 &&
     742                        w == _videoMode.screenWidth && h == _videoMode.screenHeight && _modeFlags & DF_WANT_RECT_OPTIM) {
    761743                /* Special, optimized case for full screen updates.
    762744                 * It tries to determine what areas were actually changed,
    763745                 * and just updates those, on the actual display. */
     
    776758                        y = 0;
    777759                }
    778760
    779                 if (w > _screenWidth - x) {
    780                         w = _screenWidth - x;
     761                if (w > _videoMode.screenWidth - x) {
     762                        w = _videoMode.screenWidth - x;
    781763                }
    782764
    783                 if (h > _screenHeight - y) {
    784                         h = _screenHeight - y;
     765                if (h > _videoMode.screenHeight - y) {
     766                        h = _videoMode.screenHeight - y;
    785767                }
    786768
    787769                if (w <= 0 || h <= 0)
     
    795777        if (SDL_LockSurface(_screen) == -1)
    796778                error("SDL_LockSurface failed: %s", SDL_GetError());
    797779
    798         byte *dst = (byte *)_screen->pixels + y * _screenWidth + x;
     780        byte *dst = (byte *)_screen->pixels + y * _videoMode.screenWidth + x;
    799781
    800         if (_screenWidth == pitch && pitch == w) {
     782        if (_videoMode.screenWidth == pitch && pitch == w) {
    801783                memcpy(dst, src, h*w);
    802784        } else {
    803785                do {
    804786                        memcpy(dst, src, w);
    805787                        src += pitch;
    806                         dst += _screenWidth;
     788                        dst += _videoMode.screenWidth;
    807789                } while (--h);
    808790        }
    809791
     
    863845        int height, width;
    864846
    865847        if (!_overlayVisible && !realCoordinates) {
    866                 width = _screenWidth;
    867                 height = _screenHeight;
     848                width = _videoMode.screenWidth;
     849                height = _videoMode.screenHeight;
    868850        } else {
    869                 width = _overlayWidth;
    870                 height = _overlayHeight;
     851                width = _videoMode.overlayWidth;
     852                height = _videoMode.overlayHeight;
    871853        }
    872854
    873855        // Extend the dirty region by 1 pixel for scalers
     
    899881        }
    900882
    901883#ifndef DISABLE_SCALERS
    902         if (_adjustAspectRatio && !_overlayVisible && !realCoordinates) {
     884        if (_videoMode.aspectRatio && !_overlayVisible && !realCoordinates) {
    903885                makeRectStretchable(x, y, w, h);
    904886        }
    905887#endif
     
    924906        assert(buf);
    925907        uint32 *sums = _dirtyChecksums;
    926908        uint x,y;
    927         const uint last_x = (uint)_screenWidth / 8;
    928         const uint last_y = (uint)_screenHeight / 8;
     909        const uint last_x = (uint)_videoMode.screenWidth / 8;
     910        const uint last_y = (uint)_videoMode.screenHeight / 8;
    929911
    930912        const uint BASE = 65521; /* largest prime smaller than 65536 */
    931913
    932914        /* the 8x8 blocks in buf are enumerated starting in the top left corner and
    933915         * reading each line at a time from left to right */
    934         for (y = 0; y != last_y; y++, buf += _screenWidth * (8 - 1))
     916        for (y = 0; y != last_y; y++, buf += _videoMode.screenWidth * (8 - 1))
    935917                for (x = 0; x != last_x; x++, buf += 8) {
    936918                        // Adler32 checksum algorithm (from RFC1950, used by gzip and zlib).
    937919                        // This computes the Adler32 checksum of a 8x8 pixel block. Note
     
    947929                                        s1 += ptr[subX];
    948930                                        s2 += s1;
    949931                                }
    950                                 ptr += _screenWidth;
     932                                ptr += _videoMode.screenWidth;
    951933                        }
    952934
    953935                        s1 %= BASE;
     
    977959                int x, y, w;
    978960                uint32 *ck = _dirtyChecksums;
    979961
    980                 for (y = 0; y != _screenHeight / 8; y++) {
    981                         for (x = 0; x != _screenWidth / 8; x++, ck++) {
     962                for (y = 0; y != _videoMode.screenHeight / 8; y++) {
     963                        for (x = 0; x != _videoMode.screenWidth / 8; x++, ck++) {
    982964                                if (ck[0] != ck[_cksumNum]) {
    983965                                        /* found a dirty 8x8 block, now go as far to the right as possible,
    984966                                                 and at the same time, unmark the dirty status by setting old to new. */
     
    986968                                        do {
    987969                                                ck[w + _cksumNum] = ck[w];
    988970                                                w++;
    989                                         } while (x + w != _screenWidth / 8 && ck[w] != ck[w + _cksumNum]);
     971                                        } while (x + w != _videoMode.screenWidth / 8 && ck[w] != ck[w + _cksumNum]);
    990972
    991973                                        addDirtyRect(x * 8, y * 8, w * 8, 8);
    992974
     
    1003985}
    1004986
    1005987int16 OSystem_SDL::getHeight() {
    1006         return _screenHeight;
     988        return _videoMode.screenHeight;
    1007989}
    1008990
    1009991int16 OSystem_SDL::getWidth() {
    1010         return _screenWidth;
     992        return _videoMode.screenWidth;
    1011993}
    1012994
    1013995void OSystem_SDL::setPalette(const byte *colors, uint start, uint num) {
     
    10931075
    10941076        // Since resolution could change, put mouse to adjusted position
    10951077        // Fixes bug #1349059
    1096         x = _mouseCurState.x * _scaleFactor;
    1097         if (_adjustAspectRatio)
    1098                 y = real2Aspect(_mouseCurState.y) * _scaleFactor;
     1078        x = _mouseCurState.x * _videoMode.scaleFactor;
     1079        if (_videoMode.aspectRatio)
     1080                y = real2Aspect(_mouseCurState.y) * _videoMode.scaleFactor;
    10991081        else
    1100                 y = _mouseCurState.y * _scaleFactor;
     1082                y = _mouseCurState.y * _videoMode.scaleFactor;
    11011083
    11021084        warpMouse(x, y);
    11031085
     
    11161098
    11171099        // Since resolution could change, put mouse to adjusted position
    11181100        // Fixes bug #1349059
    1119         x = _mouseCurState.x / _scaleFactor;
    1120         y = _mouseCurState.y / _scaleFactor;
    1121         if (_adjustAspectRatio)
     1101        x = _mouseCurState.x / _videoMode.scaleFactor;
     1102        y = _mouseCurState.y / _videoMode.scaleFactor;
     1103        if (_videoMode.aspectRatio)
    11221104                y = aspect2Real(y);
    11231105
    11241106        warpMouse(x, y);
     
    11401122        SDL_Rect src, dst;
    11411123        src.x = src.y = 0;
    11421124        dst.x = dst.y = 1;
    1143         src.w = dst.w = _screenWidth;
    1144         src.h = dst.h = _screenHeight;
     1125        src.w = dst.w = _videoMode.screenWidth;
     1126        src.h = dst.h = _videoMode.screenHeight;
    11451127        if (SDL_BlitSurface(_screen, &src, _tmpscreen, &dst) != 0)
    11461128                error("SDL_BlitSurface failed: %s", SDL_GetError());
    11471129
    11481130        SDL_LockSurface(_tmpscreen);
    11491131        SDL_LockSurface(_overlayscreen);
    11501132        _scalerProc((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2, _tmpscreen->pitch,
    1151         (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight);
     1133        (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _videoMode.screenWidth, _videoMode.screenHeight);
    11521134
    11531135#ifndef DISABLE_SCALERS
    1154         if (_adjustAspectRatio)
     1136        if (_videoMode.aspectRatio)
    11551137                stretch200To240((uint8 *)_overlayscreen->pixels, _overlayscreen->pitch,
    1156                                                 _overlayWidth, _screenHeight * _scaleFactor, 0, 0, 0);
     1138                                                _videoMode.overlayWidth, _videoMode.screenHeight * _videoMode.scaleFactor, 0, 0, 0);
    11571139#endif
    11581140        SDL_UnlockSurface(_tmpscreen);
    11591141        SDL_UnlockSurface(_overlayscreen);
     
    11711153                error("SDL_LockSurface failed: %s", SDL_GetError());
    11721154
    11731155        byte *src = (byte *)_overlayscreen->pixels;
    1174         int h = _overlayHeight;
     1156        int h = _videoMode.overlayHeight;
    11751157        do {
    1176                 memcpy(buf, src, _overlayWidth * 2);
     1158                memcpy(buf, src, _videoMode.overlayWidth * 2);
    11771159                src += _overlayscreen->pitch;
    11781160                buf += pitch;
    11791161        } while (--h);
     
    11991181                y = 0;
    12001182        }
    12011183
    1202         if (w > _overlayWidth - x) {
    1203                 w = _overlayWidth - x;
     1184        if (w > _videoMode.overlayWidth - x) {
     1185                w = _videoMode.overlayWidth - x;
    12041186        }
    12051187
    1206         if (h > _overlayHeight - y) {
    1207                 h = _overlayHeight - y;
     1188        if (h > _videoMode.overlayHeight - y) {
     1189                h = _videoMode.overlayHeight - y;
    12081190        }
    12091191
    12101192        if (w <= 0 || h <= 0)
     
    12601242void OSystem_SDL::warpMouse(int x, int y) {
    12611243        int y1 = y;
    12621244
    1263         if (_adjustAspectRatio && !_overlayVisible)
     1245        if (_videoMode.aspectRatio && !_overlayVisible)
    12641246                y1 = real2Aspect(y);
    12651247
    12661248        if (_mouseCurState.x != x || _mouseCurState.y != y) {
    12671249                if (!_overlayVisible)
    1268                         SDL_WarpMouse(x * _scaleFactor, y1 * _scaleFactor);
     1250                        SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor);
    12691251                else
    12701252                        SDL_WarpMouse(x, y1);
    12711253
     
    13681350
    13691351        int rW, rH;
    13701352
    1371         if (_cursorTargetScale >= _scaleFactor) {
     1353        if (_cursorTargetScale >= _videoMode.scaleFactor) {
    13721354                // The cursor target scale is greater or equal to the scale at
    13731355                // which the rest of the screen is drawn. We do not downscale
    13741356                // the cursor image, we draw it at its original size. It will
     
    13811363
    13821364                // The virtual dimensions may be larger than the original.
    13831365
    1384                 _mouseCurState.vW = w * _cursorTargetScale / _scaleFactor;
    1385                 _mouseCurState.vH = h * _cursorTargetScale / _scaleFactor;
     1366                _mouseCurState.vW = w * _cursorTargetScale / _videoMode.scaleFactor;
     1367                _mouseCurState.vH = h * _cursorTargetScale / _videoMode.scaleFactor;
    13861368                _mouseCurState.vHotX = _mouseCurState.hotX * _cursorTargetScale /
    1387                         _scaleFactor;
     1369                        _videoMode.scaleFactor;
    13881370                _mouseCurState.vHotY = _mouseCurState.hotY * _cursorTargetScale /
    1389                         _scaleFactor;
     1371                        _videoMode.scaleFactor;
    13901372        } else {
    13911373                // The cursor target scale is smaller than the scale at which
    13921374                // the rest of the screen is drawn. We scale up the cursor
    13931375                // image to make it appear correct.
    13941376
    1395                 rW = w * _scaleFactor / _cursorTargetScale;
    1396                 rH = h * _scaleFactor / _cursorTargetScale;
    1397                 _mouseCurState.rHotX = _mouseCurState.hotX * _scaleFactor /
     1377                rW = w * _videoMode.scaleFactor / _cursorTargetScale;
     1378                rH = h * _videoMode.scaleFactor / _cursorTargetScale;
     1379                _mouseCurState.rHotX = _mouseCurState.hotX * _videoMode.scaleFactor /
    13981380                        _cursorTargetScale;
    1399                 _mouseCurState.rHotY = _mouseCurState.hotY * _scaleFactor /
     1381                _mouseCurState.rHotY = _mouseCurState.hotY * _videoMode.scaleFactor /
    14001382                        _cursorTargetScale;
    14011383
    14021384                // The virtual dimensions will be the same as the original.
     
    14111393        int rH1 = rH; // store original to pass to aspect-correction function later
    14121394#endif
    14131395
    1414         if (_adjustAspectRatio && _cursorTargetScale == 1) {
     1396        if (_videoMode.aspectRatio && _cursorTargetScale == 1) {
    14151397                rH = real2Aspect(rH - 1) + 1;
    14161398                _mouseCurState.rHotY = real2Aspect(_mouseCurState.rHotY);
    14171399        }
     
    14461428        // the game. This only works well with the non-blurring scalers so we
    14471429        // actually only use the 1x, 1.5x, 2x and AdvMame scalers.
    14481430
    1449         if (_cursorTargetScale == 1 && (_mode == GFX_DOUBLESIZE || _mode == GFX_TRIPLESIZE))
     1431        if (_cursorTargetScale == 1 && (_videoMode.mode == GFX_DOUBLESIZE || _videoMode.mode == GFX_TRIPLESIZE))
    14501432                scalerProc = _scalerProc;
    14511433        else
    1452                 scalerProc = scalersMagn[_cursorTargetScale - 1][_scaleFactor - 1];
     1434                scalerProc = scalersMagn[_cursorTargetScale - 1][_videoMode.scaleFactor - 1];
    14531435
    14541436        scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2,
    14551437                _mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch,
    14561438                _mouseCurState.w, _mouseCurState.h);
    14571439
    14581440#ifndef DISABLE_SCALERS
    1459         if (_adjustAspectRatio && _cursorTargetScale == 1)
     1441        if (_videoMode.aspectRatio && _cursorTargetScale == 1)
    14601442                cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, rW, rH1, 0, 0, 0);
    14611443#endif
    14621444
     
    14991481
    15001482        // When we switch bigger overlay off mouse jumps. Argh!
    15011483        // This is intended to prevent undrawing offscreen mouse
    1502         if (!_overlayVisible && (x >= _screenWidth || y >= _screenHeight)) {
     1484        if (!_overlayVisible && (x >= _videoMode.screenWidth || y >= _videoMode.screenHeight)) {
    15031485                return;
    15041486        }
    15051487
     
    15221504        dst.y = _mouseCurState.y;
    15231505
    15241506        if (!_overlayVisible) {
    1525                 scale = _scaleFactor;
    1526                 width = _screenWidth;
    1527                 height = _screenHeight;
     1507                scale = _videoMode.scaleFactor;
     1508                width = _videoMode.screenWidth;
     1509                height = _videoMode.screenHeight;
    15281510                dst.w = _mouseCurState.vW;
    15291511                dst.h = _mouseCurState.vH;
    15301512                hotX = _mouseCurState.vHotX;
    15311513                hotY = _mouseCurState.vHotY;
    15321514        } else {
    15331515                scale = 1;
    1534                 width = _overlayWidth;
    1535                 height = _overlayHeight;
     1516                width = _videoMode.overlayWidth;
     1517                height = _videoMode.overlayHeight;
    15361518                dst.w = _mouseCurState.rW;
    15371519                dst.h = _mouseCurState.rH;
    15381520                hotX = _mouseCurState.rHotX;
     
    15541536                dst.y += _currentShakePos;
    15551537        }
    15561538
    1557         if (_adjustAspectRatio && !_overlayVisible)
     1539        if (_videoMode.aspectRatio && !_overlayVisible)
    15581540                dst.y = real2Aspect(dst.y);
    15591541
    15601542        dst.x = scale * dst.x - _mouseCurState.rHotX;
     
    16701652void OSystem_SDL::handleScalerHotkeys(const SDL_KeyboardEvent &key) {
    16711653        // Ctrl-Alt-a toggles aspect ratio correction
    16721654        if (key.keysym.sym == 'a') {
    1673                 setFeatureState(kFeatureAspectRatioCorrection, !_adjustAspectRatio);
     1655                beginGFXTransaction();
     1656                        setFeatureState(kFeatureAspectRatioCorrection, !_videoMode.aspectRatio);
     1657                endGFXTransaction();
    16741658#ifdef USE_OSD
    16751659                char buffer[128];
    1676                 if (_adjustAspectRatio)
     1660                if (_videoMode.aspectRatio)
    16771661                        sprintf(buffer, "Enabled aspect ratio correction\n%d x %d -> %d x %d",
    1678                                 _screenWidth, _screenHeight,
     1662                                _videoMode.screenWidth, _videoMode.screenHeight,
    16791663                                _hwscreen->w, _hwscreen->h
    16801664                                );
    16811665                else
    16821666                        sprintf(buffer, "Disabled aspect ratio correction\n%d x %d -> %d x %d",
    1683                                 _screenWidth, _screenHeight,
     1667                                _videoMode.screenWidth, _videoMode.screenHeight,
    16841668                                _hwscreen->w, _hwscreen->h
    16851669                                );
    16861670                displayMessageOnOSD(buffer);
     
    16901674        }
    16911675
    16921676        int newMode = -1;
    1693         int factor = _scaleFactor - 1;
     1677        int factor = _videoMode.scaleFactor - 1;
    16941678
    16951679        // Increase/decrease the scale factor
    16961680        if (key.keysym.sym == SDLK_EQUALS || key.keysym.sym == SDLK_PLUS || key.keysym.sym == SDLK_MINUS ||
     
    17161700        }
    17171701
    17181702        if (newMode >= 0) {
    1719                 setGraphicsMode(newMode);
     1703                beginGFXTransaction();
     1704                        setGraphicsMode(newMode);
     1705                endGFXTransaction();
    17201706#ifdef USE_OSD
    17211707                if (_osdSurface) {
    17221708                        const char *newScalerName = 0;
    17231709                        const GraphicsMode *g = getSupportedGraphicsModes();
    17241710                        while (g->name) {
    1725                                 if (g->id == _mode) {
     1711                                if (g->id == _videoMode.mode) {
    17261712                                        newScalerName = g->description;
    17271713                                        break;
    17281714                                }
     
    17321718                                char buffer[128];
    17331719                                sprintf(buffer, "Active graphics filter: %s\n%d x %d -> %d x %d",
    17341720                                        newScalerName,
    1735                                         _screenWidth, _screenHeight,
     1721                                        _videoMode.screenWidth, _videoMode.screenHeight,
    17361722                                        _hwscreen->w, _hwscreen->h
    17371723                                        );
    17381724                                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

     
    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
    430426        virtual void hotswapGFXMode(); // overloaded by CE backend
    431427
     
    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();