Ticket #8250: aspect-modes2.diff

File aspect-modes2.diff, 28.3 KB (added by eriktorbjorn, 21 years ago)

Patch against a June 30 CVS snapshot

  • scummvm/README

    diff -ur ScummVM+orig/scummvm/README ScummVM+hack/scummvm/README
    old new  
    346346        -x[<num>]      - Save game slot to load (default: autosave)
    347347        -f             - Full-screen mode.
    348348        -g<mode>       - Select graphics scaler. See below.
     349        -r<mode>       - Select aspect ratio correction mode. See below.
    349350        -e<mode>       - Select sound engine. See below.
    350351        -a             - Enable amiga pal conversion, for playing Amiga
    351352                         versions
     
    367368                         current directory
    368369        --multi-midi   - enable combination Adlib and native MIDI
    369370        --native-mt32  - true Roland MT-32 (disable GM emulation)
    370         --aspect-ratio - enable aspect ratio correction
    371371
    372372
    373373
     
    383383        Ctrl-Alt 0-9           - Switch between graphics filters
    384384        Ctrl-Alt b             - Switch beetwen bilinear and non-linear
    385385                                 filtering [OpenGL backend]
    386         Ctrl-Alt a             - Toggle aspect-ratio correction on/off.
    387                                  Most of the games use a 320x200 pixel
    388                                  resolution, which may look squashed on
    389                                  modern monitors. Aspect-ratio correction
    390                                  stretches the image to use 320x240 pixels
    391                                  instead, or a multiple thereof.
     386        Ctrl-Alt a             - Cycle between aspect ratio correction modes.
    392387
    393388    Scumm:
    394389        Ctrl 0-9 and Alt 0-9   - load and save game state
     
    458453
    459454    scummvm -g advmame2x monkey2
    460455
     456In addition ScummVM offers a few different methods for aspect ratio correction
     457to stretch a 320x200 image to 320x240. This provides the correct aspect ratio
     458on modern displays, and can be combined with any of the scalers listed above
     459(except for opengl, which handles aspect ratio correction differently) to
     460produce 640x480 or 960x720 resolutions.
     461
     462They are:
     463        none   - No aspect ratio correction. (default)
     464        sloppy - Every fifth screen line is doubled. This is fast, but will
     465                 look ugly in some cases.
     466        fast   - Approximated bilinear filtering. This is a little slower, but
     467                 looks better than sloppy mode.
     468        exact  - Exact bilinear filtering. This is much slower, but may look a
     469                 little better than fast mode.
     470
     471To select an aspect ratio correction mode, pass its name via the '-r' option
     472to scummvm, for example:
     473
     474    scummvm -g avdmame2x -r fast monkey2
     475
    461476Note #1: Not all backends support all or any filters. The ones listed above
    462477are for the default SDL backend.
    463478
     
    468483Note #3: The FmTowns version of Zak (zak256 target) uses an original resolution
    469484of 320x240 - hence for this game scalers will scale to 640x480 or 960x720.
    470485
     486Note #4: The Curse of Monkey Island uses an original resolution of 640x480 -
     487hence for this game scalers will scale to 1280x960 or 1920x1440. However, the
     488anti-aliasing filters are unlikely to improve the graphics much since they are
     489already anti-aliased to begin with.
    471490
    472491Autosaves:
    473492----------
  • scummvm/backends/sdl/sdl-common.cpp

    diff -ur ScummVM+orig/scummvm/backends/sdl/sdl-common.cpp ScummVM+hack/scummvm/backends/sdl/sdl-common.cpp
    old new  
    4141#define JOY_BUT_SPACE 4
    4242#define JOY_BUT_F5 5
    4343
    44 OSystem *OSystem_SDL_create(int gfx_mode, bool full_screen, bool aspect_ratio) {
    45         return OSystem_SDL_Common::create(gfx_mode, full_screen, aspect_ratio);
     44OSystem *OSystem_SDL_create(int gfx_mode, bool full_screen, int aspect_ratio_mode) {
     45        return OSystem_SDL_Common::create(gfx_mode, full_screen, aspect_ratio_mode);
    4646}
    4747
    48 OSystem *OSystem_SDL_Common::create(int gfx_mode, bool full_screen, bool aspect_ratio) {
     48OSystem *OSystem_SDL_Common::create(int gfx_mode, bool full_screen, int aspect_ratio_mode) {
    4949        OSystem_SDL_Common *syst = OSystem_SDL_Common::create_intern();
    5050
    51         syst->init_intern(gfx_mode, full_screen, aspect_ratio);
     51        syst->init_intern(gfx_mode, full_screen, aspect_ratio_mode);
    5252
    5353        return syst;
    5454}
    5555
    56 void OSystem_SDL_Common::init_intern(int gfx_mode, bool full_screen, bool aspect_ratio) {
     56void OSystem_SDL_Common::init_intern(int gfx_mode, bool full_screen, int aspect_ratio_mode) {
    5757
    5858        _mode = gfx_mode;
    5959        _full_screen = full_screen;
    60         _adjustAspectRatio = aspect_ratio;
     60        _aspectRatioMode = aspect_ratio_mode;
    6161
    6262        if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK) ==-1) {
    6363                error("Could not initialize SDL: %s.\n", SDL_GetError());
     
    132132        _screenHeight = h;
    133133
    134134        if (h != 200)
    135                 _adjustAspectRatio = false;
     135                _aspectRatioMode = ASPECT_NONE;
    136136
    137137        CKSUM_NUM = (_screenWidth * _screenHeight / (8 * 8));
    138138        if (_dirty_checksums)
     
    287287                        h = _screenHeight - y;
    288288                }
    289289
    290                 if (_adjustAspectRatio)
     290                if (_aspectRatioMode > ASPECT_SLOPPY)
    291291                        makeRectStretchable(x, y, w, h);
    292292       
    293293                r->x = x;
     
    586586
    587587                        // Ctr-Alt-a will change aspect ratio
    588588                        if (b == (KBD_CTRL|KBD_ALT) && ev.key.keysym.sym=='a') {
    589                                 property(PROP_TOGGLE_ASPECT_RATIO, NULL);
     589                                Property prop;
     590
     591                                if (_aspectRatioMode >= ASPECT_MAX)
     592                                        prop.aspect_ratio_mode = ASPECT_MIN;
     593                                else
     594                                        prop.aspect_ratio_mode = _aspectRatioMode + 1;
     595                                property(PROP_SET_ASPECT_RATIO_MODE, &prop);
    590596                                break;
    591597                        }
    592598
     
    704710                        event->mouse.x /= _scaleFactor;
    705711                        event->mouse.y /= _scaleFactor;
    706712
    707                         if (_adjustAspectRatio)
     713                        if (_aspectRatioMode != ASPECT_NONE)
    708714                                event->mouse.y = aspect2Real(event->mouse.y);
    709715                        return true;
    710716
     
    726732                        event->mouse.x /= _scaleFactor;
    727733                        event->mouse.y /= _scaleFactor;
    728734
    729                         if (_adjustAspectRatio)
     735                        if (_aspectRatioMode != ASPECT_NONE)
    730736                                event->mouse.y = aspect2Real(event->mouse.y);
    731737
    732738                        return true;
     
    743749                        event->mouse.x /= _scaleFactor;
    744750                        event->mouse.y /= _scaleFactor;
    745751
    746                         if (_adjustAspectRatio)
     752                        if (_aspectRatioMode != ASPECT_NONE)
    747753                                event->mouse.y = aspect2Real(event->mouse.y);
    748754
    749755                        return true;
     
    851857                        event->mouse.x /= _scaleFactor;
    852858                        event->mouse.y /= _scaleFactor;
    853859
    854                         if (_adjustAspectRatio)
     860                        if (_aspectRatioMode != ASPECT_NONE)
    855861                                event->mouse.y = aspect2Real(event->mouse.y);
    856862
    857863                        return true;
  • scummvm/backends/sdl/sdl-common.h

    diff -ur ScummVM+orig/scummvm/backends/sdl/sdl-common.h ScummVM+hack/scummvm/backends/sdl/sdl-common.h
    old new  
    2525#include "stdafx.h"
    2626#include "scummsys.h"
    2727#include "system.h"
     28#include "common/scaler.h"
    2829
    2930#include <SDL.h>
    3031#include <SDL_thread.h>
     
    123124        virtual int16 RGBToColor(uint8 r, uint8 g, uint8 b);
    124125        virtual void colorToRGB(int16 color, uint8 &r, uint8 &g, uint8 &b);
    125126
    126         static OSystem *create(int gfx_mode, bool full_screenm, bool aspect_ratio);
     127        static OSystem *create(int gfx_mode, bool full_screenm, int aspect_ratio_mode);
    127128
    128129protected:
    129130        OSystem_SDL_Common();
     
    131132
    132133        static OSystem_SDL_Common *create_intern();
    133134
    134         void init_intern(int gfx_mode, bool full_screen, bool aspect_ratio);
     135        void init_intern(int gfx_mode, bool full_screen, int aspect_ratio_mode);
    135136
    136137        // unseen game screen
    137138        SDL_Surface *_screen;
     
    142143        int _tmpScreenWidth;
    143144        bool _overlayVisible;
    144145
    145         bool _adjustAspectRatio;
     146        int _aspectRatioMode;
    146147
    147148        // CD Audio
    148149        SDL_CD *_cdrom;
  • scummvm/backends/sdl/sdl.cpp

    diff -ur ScummVM+orig/scummvm/backends/sdl/sdl.cpp ScummVM+hack/scummvm/backends/sdl/sdl.cpp
    old new  
    1616 * along with this program; if not, write to the Free Software
    1717 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    1818 *
    19  * $Header: /cvsroot/scummvm/scummvm/backends/sdl/sdl.cpp,v 1.37 2003/06/22 14:18:33 kirben Exp $
     19 * $Header: /cvsroot/scummvm/scummvm/backends/sdl/sdl.cpp,v 1.38 2003/06/30 14:31:09 eriktorbjorn Exp $
    2020 *
    2121 */
    2222
    2323#include "sdl-common.h"
    24 #include "common/scaler.h"
    2524#include "common/util.h"
    2625#include "common/engine.h"      // Only #included for error() and warning()
    2726
     
    4241        SDL_Surface *_hwscreen;    // hardware screen
    4342
    4443        ScalerProc *_scaler_proc;
     44        StretcherProc *_stretcher_proc;
    4545
    4646        virtual void load_gfx_mode();
    4747        virtual void unload_gfx_mode();
     
    5353}
    5454
    5555OSystem_SDL::OSystem_SDL()
    56          : _hwscreen(0), _scaler_proc(0)
     56         : _hwscreen(0), _scaler_proc(0), _stretcher_proc(0)
    5757{
    5858}
    5959
     
    119119                break;
    120120
    121121        case GFX_TRIPLESIZE:
    122                 if (_full_screen) {
    123                         warning("full screen in useless in triplesize mode, reverting to normal mode");
    124                         goto normal_mode;
    125                 }
    126122                _scaleFactor = 3;
    127123                _scaler_proc = Normal3x;
    128124                break;
    129125
    130126        case GFX_NORMAL:
    131 normal_mode:;
    132127                _scaleFactor = 1;
    133128                _scaler_proc = Normal1x;
    134129                break;
    135130        default:
    136131                error("unknown gfx mode %d", _mode);
    137                 _scaleFactor = 1;
    138                 _scaler_proc = NULL;
     132        }
     133
     134        switch (_aspectRatioMode) {
     135        case ASPECT_NONE:
     136                _stretcher_proc = NULL;
     137                break;
     138        case ASPECT_SLOPPY:
     139                _stretcher_proc = stretch200To240Sloppy;
     140                break;
     141        case ASPECT_FAST:
     142                _stretcher_proc = stretch200To240Fast;
     143                break;
     144        case ASPECT_EXACT:
     145                _stretcher_proc = stretch200To240Exact;
     146                break;
     147        default:
     148                error("unknown aspect ratio mode %d", _aspectRatioMode);
    139149        }
    140150
    141151        //
     
    149159        // Create the surface that contains the scaled graphics in 16 bit mode
    150160        //
    151161
    152         _hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor, 16,
     162        _hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor, 16,
    153163                _full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
    154164        );
    155165        if (_hwscreen == NULL)
     
    283293                uint32 srcPitch, dstPitch;
    284294                SDL_Rect *last_rect = _dirty_rect_list + _num_dirty_rects;
    285295
    286                 if (_scaler_proc == Normal1x && !_adjustAspectRatio) {
     296                if (_scaler_proc == Normal1x && _aspectRatioMode == ASPECT_NONE) {
    287297                        SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen;
    288298                        for (r = _dirty_rect_list; r != last_rect; ++r) {
    289299                                dst = *r;
     
    325335
    326336                                        dst_y *= _scaleFactor;
    327337
    328                                         if (_adjustAspectRatio) {
     338                                        if (_aspectRatioMode != ASPECT_NONE) {
    329339                                                orig_dst_y = dst_y;
    330340                                                dst_y = real2Aspect(dst_y);
    331341                                        }
     
    339349                                r->w *= _scaleFactor;
    340350                                r->h = dst_h * _scaleFactor;
    341351
    342                                 if (_adjustAspectRatio && orig_dst_y / _scaleFactor < _screenHeight)
    343                                         r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
     352                                if (_stretcher_proc && orig_dst_y / _scaleFactor < _screenHeight)
     353                                        r->h = _stretcher_proc((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
    344354                        }
    345355                        SDL_UnlockSurface(_tmpscreen);
    346356                        SDL_UnlockSurface(_hwscreen);
     
    350360                // This is necessary if shaking is active.
    351361                if (_forceFull) {
    352362                        _dirty_rect_list[0].y = 0;
    353                         _dirty_rect_list[0].h = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor;
     363                        _dirty_rect_list[0].h = ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor;
    354364                }
    355365
    356366                // Finally, blit all our changes to the screen
     
    385395                hotswap_gfx_mode();
    386396
    387397                return 1;
    388         } else if (param == PROP_TOGGLE_ASPECT_RATIO) {
     398        } else if (param == PROP_SET_ASPECT_RATIO_MODE) {
    389399                if (_screenHeight == 200) {
    390                         assert(_hwscreen != 0);
    391                         _adjustAspectRatio ^= true;
     400                        _aspectRatioMode = value->aspect_ratio_mode;
    392401                        hotswap_gfx_mode();
    393402                }
    394403        }
  • scummvm/backends/sdl/sdl_gl.cpp

    diff -ur ScummVM+orig/scummvm/backends/sdl/sdl_gl.cpp ScummVM+hack/scummvm/backends/sdl/sdl_gl.cpp
    old new  
    1616 * along with this program; if not, write to the Free Software
    1717 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    1818 *
    19  * $Header: /cvsroot/scummvm/scummvm/backends/sdl/sdl_gl.cpp,v 1.42 2003/06/30 02:38:56 kirben Exp $
     19 * $Header: /cvsroot/scummvm/scummvm/backends/sdl/sdl_gl.cpp,v 1.43 2003/06/30 14:31:09 eriktorbjorn Exp $
    2020 *
    2121 */
    2222
     
    6464        SDL_Surface *_hwscreen;  // hardware screen (=> _usingOpenGL == false)
    6565
    6666        ScalerProc *_scaler_proc;
     67        StretcherProc *_stretcher_proc;
    6768       
    6869        virtual void load_gfx_mode();
    6970        virtual void unload_gfx_mode();
     
    7576}
    7677
    7778OSystem_SDL_OpenGL::OSystem_SDL_OpenGL()
    78   : _hwscreen(0), _scaler_proc(0)
     79  : _hwscreen(0), _scaler_proc(0), _stretcher_proc(0)
    7980{
    8081  _glScreenStart = 0;
    8182  _glBilinearFilter = false;
     
    159160                break;
    160161
    161162        case GFX_TRIPLESIZE:
    162                 if (_full_screen) {
    163                         warning("full screen in useless in triplesize mode, reverting to normal mode");
    164                         goto normal_mode;
    165                 }
    166163                _scaleFactor = 3;
    167164                _scaler_proc = Normal3x;
    168165                break;
    169166
    170167        case GFX_NORMAL:
    171 normal_mode:;
    172168                _scaleFactor = 1; //_usingOpenGL ? 2 : 1;
    173169                _scaler_proc = Normal1x;
    174170                break;
     
    180176        }
    181177
    182178        if (_mode != GFX_NORMAL) {
    183           _usingOpenGL = false;
     179                _usingOpenGL = false;
    184180        }
    185  
     181
     182        switch (_aspectRatioMode) {
     183        case ASPECT_NONE:
     184                _stretcher_proc = NULL;
     185                break;
     186        case ASPECT_SLOPPY:
     187                _stretcher_proc = stretch200To240Sloppy;
     188                break;
     189        case ASPECT_FAST:
     190                _stretcher_proc = stretch200To240Fast;
     191                break;
     192        case ASPECT_EXACT:
     193                _stretcher_proc = stretch200To240Exact;
     194                break;
     195        default:
     196                error("unknown aspect ratio mode %d", _aspectRatioMode);
     197        }
     198
    186199        //
    187200        // Create the surface that contains the 8 bit game data
    188201        //
     
    218231               
    219232        } else { // SDL backend
    220233         
    221                 _hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor, 16,
     234                _hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor, 16,
    222235                _full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
    223236                );
    224237                if (_hwscreen == NULL)
     
    432445
    433446                        // Bottom black border height
    434447                        tmpBlackRect.h = _glBottomOfTexture - _glBottomOfGameScreen;
    435                         if (_adjustAspectRatio && tmpBlackRect.h > 0) {
     448                        if (_aspectRatioMode != ASPECT_NONE && tmpBlackRect.h > 0) {
    436449                                SDL_FillRect(tmpSurface, &tmpBlackRect, 0);
    437450                                fb2gl.blit16(tmpSurface, 1, &tmpBlackRect, 0,
    438451                                  _glBottomOfGameScreen);
     
    441454                        fb2gl.display();
    442455                } else { // SDL backend
    443456                       
    444                         if (_scaler_proc == Normal1x && !_adjustAspectRatio) {
     457                        if (_scaler_proc == Normal1x && _aspectRatioMode == ASPECT_NONE) {
    445458                                SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen;
    446459                                for (r = _dirty_rect_list; r != last_rect; ++r) {
    447460                                        dst = *r;
     
    483496                       
    484497                                                        dst_y *= _scaleFactor;
    485498                       
    486                                                         if (_adjustAspectRatio) {
     499                                                        if (_aspectRatioMode != ASPECT_NONE) {
    487500                                                                orig_dst_y = dst_y;
    488501                                                                dst_y = real2Aspect(dst_y);
    489502                                                        }
     
    497510                                        r->w *= _scaleFactor;
    498511                                        r->h = dst_h * _scaleFactor;
    499512
    500                                         if (_adjustAspectRatio && orig_dst_y / _scaleFactor < _screenHeight)
    501                                                 r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
     513                                        if (_stretcher_proc && orig_dst_y / _scaleFactor < _screenHeight)
     514                                                r->h = _stretcher_proc((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
    502515                                }
    503516                       
    504517                                SDL_UnlockSurface(_tmpscreen);
     
    509522                        // This is necessary if shaking is active.
    510523                        if (_forceFull) {
    511524                                _dirty_rect_list[0].y = 0;
    512                                 _dirty_rect_list[0].h = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor;
     525                                _dirty_rect_list[0].h = ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor;
    513526                        }
    514527                       
    515528                        // Finally, blit all our changes to the screen
     
    571584#endif
    572585
    573586                return 1;
    574         } else if (param == PROP_TOGGLE_ASPECT_RATIO) {
    575 
    576                 _adjustAspectRatio ^= true;
     587        } else if (param == PROP_SET_ASPECT_RATIO_MODE) {
    577588                if (_usingOpenGL) {
    578                         if (_adjustAspectRatio) {
     589                        // OpenGL has only two aspect ratio correction modes.
     590                        if (value->aspect_ratio_mode == ASPECT_MIN)
     591                                _aspectRatioMode = ASPECT_MIN;
     592                        else
     593                                _aspectRatioMode = ASPECT_MAX;
     594                        if (_aspectRatioMode != ASPECT_NONE) {
    579595                                // Don't use the whole screen (black borders)
    580596                                fb2gl.init(0, 0, 0, 15, _glFlags);
    581597                                _glScreenStart = _glBorderHeight;
     
    611627                        fb2gl.display();
    612628                } else {
    613629                        if (_screenHeight == 200) {
    614                                 assert(_hwscreen != 0);
     630                                _aspectRatioMode = value->aspect_ratio_mode;
    615631                                hotswap_gfx_mode();
    616632                        }
    617633                }
  • scummvm/common/gameDetector.cpp

    diff -ur ScummVM+orig/scummvm/common/gameDetector.cpp ScummVM+hack/scummvm/common/gameDetector.cpp
    old new  
    2525#include "engine.h"
    2626#include "gameDetector.h"
    2727#include "config-file.h"
    28 #include "scaler.h"     // Only for gfx_modes
     28#include "scaler.h"     // Only for gfx_modes and aspect ratio
    2929
    3030#if defined(HAVE_CONFIG_H)
    3131#include "config.h"
     
    5454        "\t-x[<num>]      - load this savegame (default: 0 - autosave)\n"
    5555        "\t-f             - fullscreen mode\n"
    5656        "\t-g<mode>       - graphics mode (normal,2x,3x,2xsai,super2xsai,supereagle,advmame2x,advmame3x,tv2x,dotmatrix)\n"
     57        "\t-r<mode>       - aspect ratio correction (none,sloppy,fast,exact)\n"
    5758        "\t-e<mode>       - set music engine (see README for details)\n"
    5859        "\t-a             - specify game is amiga version\n"
    5960        "\t-q<lang>       - specify language (en,de,fr,it,pt,es,jp,zh,kr,hb)\n"
     
    8283        "\n"
    8384        "\t--multi-midi   - enable combination Adlib and native MIDI\n"
    8485        "\t--native-mt32  - true Roland MT-32 (disable GM emulation)\n"
    85         "\t--aspect-ratio - enable aspect ratio correction\n"
    8686;
    8787#endif
    8888// This contains a pointer to a list of all supported games.
     
    110110        {0, 0, 0}
    111111};
    112112
     113static const struct AspectRatioMode aspect_ratio_modes[] = {
     114        {"none", "No correction", ASPECT_NONE},
     115        {"sloppy", "Pixel doubling", ASPECT_SLOPPY},
     116        {"fast", "Approximate bilinear filtering", ASPECT_FAST},
     117        {"exact", "Exact bilinear filtering", ASPECT_EXACT},
     118        {0, 0, 0}
     119};
     120
    113121static const struct Language languages[] = {
    114122        {"en", "English", EN_USA},
    115123        {"de", "German", DE_DEU},
     
    150158
    151159GameDetector::GameDetector() {
    152160        _fullScreen = false;
    153         _aspectRatio = false;
     161        _aspectRatioMode = ASPECT_NONE;
    154162
    155163        _use_adlib = false;
    156164
     
    248256                }
    249257
    250258        _fullScreen = g_config->getBool("fullscreen", _fullScreen);
    251         _aspectRatio = g_config->getBool("aspect_ratio", _aspectRatio);
     259
     260        if ((val = g_config->get("aspect_ratio")))
     261                if ((_aspectRatioMode = parseAspectRatioMode(val)) == -1) {
     262                        printf("Error in the config file: invalid aspect_ratio.\n");
     263                        printf(USAGE_STRING);
     264                        exit(-1);
     265                }
    252266
    253267        if ((val = g_config->get("gfx_mode")))
    254268                if ((_gfx_mode = parseGraphicsMode(val)) == -1) {
     
    404418                                break;
    405419                        case 'r':
    406420                                HANDLE_OPTION();
    407                                 // Ignore -r for now, to ensure backward compatibility.
     421                                _aspectRatioMode = parseAspectRatioMode(option);
     422                                if (_aspectRatioMode == -1)
     423                                        goto ShowHelpAndExit;
     424                                g_config->set("aspect_ratio", option, "scummvm");
    408425                                break;
    409426                        case 's':
    410427                                HANDLE_OPTION();
     
    457474                                } else if (!strcmp (s, "native-mt32")) {
    458475                                        _native_mt32 = true;
    459476                                        g_config->setBool ("native_mt32", true);
    460                                 } else if (!strcmp (s, "aspect-ratio")) {
    461                                         _aspectRatio = true;
    462                                         g_config->setBool ("aspect_ratio", true);
    463477                                } else {
    464478                                        goto ShowHelpAndExit;
    465479                                }
     
    520534        return -1;
    521535}
    522536
     537int GameDetector::parseAspectRatioMode(const char *s) {
     538        const AspectRatioMode *arm = aspect_ratio_modes;
     539        while(arm->name) {
     540                if (!scumm_stricmp(arm->name, s))
     541                        return arm->id;
     542                arm++;
     543        }
     544
     545        return -1;
     546}
     547
    523548int GameDetector::parseLanguage(const char *s) {
    524549        const Language *l = languages;
    525550        while(l->name) {
     
    680705        return OSystem_PALMOS_create(_gfx_mode);
    681706#else
    682707        /* SDL is the default driver for now */
    683         return OSystem_SDL_create(_gfx_mode, _fullScreen, _aspectRatio);
     708        return OSystem_SDL_create(_gfx_mode, _fullScreen, _aspectRatioMode);
    684709#endif
    685710}
    686711
  • scummvm/common/gameDetector.h

    diff -ur ScummVM+orig/scummvm/common/gameDetector.h ScummVM+hack/scummvm/common/gameDetector.h
    old new  
    8585        int id;
    8686};
    8787
     88struct AspectRatioMode {
     89        const char *name;
     90        const char *description;
     91        int id;
     92};
     93
    8894struct Language {
    8995        const char *name;
    9096        const char *description;
     
    110116        const String& getGameName(void);
    111117       
    112118        bool _fullScreen;
    113         bool _aspectRatio;
     119        int _aspectRatioMode;
    114120
    115121        bool _use_adlib;
    116122
     
    151157        int getMidiDriverType();
    152158
    153159        int parseGraphicsMode(const char *s);
     160        int parseAspectRatioMode(const char *s);
    154161        void updateconfig();
    155162
    156163protected:
  • scummvm/common/scaler.cpp

    diff -ur ScummVM+orig/scummvm/common/scaler.cpp ScummVM+hack/scummvm/common/scaler.cpp
    old new  
    658658        return (uint16)((r & redMask) | (g & greenMask) | (b & blueMask));
    659659}
    660660
    661 static inline void interpolate5Line(uint16 *dst, const uint16 *srcA, const uint16 *srcB, int scale, int width) {
    662 #if 1
    663         // Accurate but slightly slower code
    664         while (width--) {
    665                 *dst++ = interpolate5(*srcA++, *srcB++, scale);
    666         }
    667 #else
     661static inline void interpolate5LineFast(uint16 *dst, const uint16 *srcA, const uint16 *srcB, int scale, int width) {
    668662        // Not fully accurate, but a bit faster
    669663       
    670664        if (width & 1) {
     
    693687                        *d++ = INTERPOLATE(*sA++, *sB++);
    694688                }
    695689        }
    696 #endif
     690}
     691
     692static inline void interpolate5Line(uint16 *dst, const uint16 *srcA, const uint16 *srcB, int scale, int width) {
     693        // Accurate but slightly slower code
     694        while (width--) {
     695                *dst++ = interpolate5(*srcA++, *srcB++, scale);
     696        }
    697697}
    698698
    699699void makeRectStretchable(int &x, int &y, int &w, int &h) {
     
    710710
    711711/**
    712712 * Stretch a 16bpp image vertically by factor 1.2. Used to correct the
    713  * aspect-ratio in games using 320x200 pixel graphics with non-qudratic
     713 * aspect ratio in games using 320x200 pixel graphics with non-qudratic
    714714 * pixels. Applying this method effectively turns that into 320x240, which
    715  * provides the correct aspect-ratio on modern displays.
     715 * provides the correct aspect ratio on modern displays.
    716716 *
    717717 * The image would normally have occupied y coordinates origSrcY through
    718718 * origSrcY + height - 1.
     
    724724 * srcY + height - 1, and it should be stretched to Y coordinates srcY
    725725 * through real2Aspect(srcY + height - 1).
    726726 */
    727 int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) {
     727int stretch200To240Sloppy(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) {
    728728        int maxDstY = real2Aspect(origSrcY + height - 1);
    729729        int off = srcY - origSrcY;
    730730        int y;
     
    734734        for (y = maxDstY; y >= srcY; y--) {
    735735                uint8 *srcPtr = buf + srcX * 2 + (aspect2Real(y) + off) * pitch;
    736736
    737 #if 0
    738                 // Don't use bilinear filtering, rather just duplicate pixel lines:
    739                 // a little bit faster, but looks ugly
     737                // Don't use bilinear filtering, rather just duplicate pixel
     738                // lines: a little bit faster, but looks ugly
    740739                if (srcPtr == dstPtr)
    741740                        break;
    742741               
    743742                memcpy(dstPtr, srcPtr, width * 2);
    744 #else
     743                dstPtr -= pitch;
     744        }
     745
     746        return 1 + maxDstY - srcY;
     747}
     748
     749int stretch200To240Fast(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) {
     750        int maxDstY = real2Aspect(origSrcY + height - 1);
     751        int off = srcY - origSrcY;
     752        int y;
     753
     754        uint8 *dstPtr = buf + srcX * 2 + maxDstY * pitch;
     755
     756        for (y = maxDstY; y >= srcY; y--) {
     757                uint8 *srcPtr = buf + srcX * 2 + (aspect2Real(y) + off) * pitch;
     758
     759                // Bilinear filter
     760                switch (y % 6) {
     761                case 0:
     762                case 5:
     763                        if (srcPtr != dstPtr)
     764                                memcpy(dstPtr, srcPtr, width * 2);
     765                        break;
     766                case 1:
     767                case 4:
     768                        interpolate5LineFast((uint16 *)dstPtr, (uint16 *)(srcPtr - pitch), (uint16 *)srcPtr, 1, width);
     769                        break;
     770                case 2:
     771                case 3:
     772                        interpolate5LineFast((uint16 *)dstPtr, (uint16 *)(srcPtr - pitch), (uint16 *)srcPtr, 2, width);
     773                        break;
     774                }
     775                dstPtr -= pitch;
     776        }
     777
     778        return 1 + maxDstY - srcY;
     779}
     780
     781int stretch200To240Exact(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) {
     782        int maxDstY = real2Aspect(origSrcY + height - 1);
     783        int off = srcY - origSrcY;
     784        int y;
     785
     786        uint8 *dstPtr = buf + srcX * 2 + maxDstY * pitch;
     787
     788        for (y = maxDstY; y >= srcY; y--) {
     789                uint8 *srcPtr = buf + srcX * 2 + (aspect2Real(y) + off) * pitch;
     790
    745791                // Bilinear filter
    746792                switch (y % 6) {
    747793                case 0:
     
    758804                        interpolate5Line((uint16 *)dstPtr, (uint16 *)(srcPtr - pitch), (uint16 *)srcPtr, 2, width);
    759805                        break;
    760806                }
    761 #endif
    762807                dstPtr -= pitch;
    763808        }
    764809
  • scummvm/common/scaler.h

    diff -ur ScummVM+orig/scummvm/common/scaler.h ScummVM+hack/scummvm/common/scaler.h
    old new  
    5151
    5252extern void makeRectStretchable(int &x, int &y, int &w, int &h);
    5353
    54 extern int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY);
     54typedef int StretcherProc(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY);
     55
     56#define DECLARE_STRETCHER(x)    \
     57        extern int x(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY)
     58
     59DECLARE_STRETCHER(stretch200To240Sloppy);
     60DECLARE_STRETCHER(stretch200To240Fast);
     61DECLARE_STRETCHER(stretch200To240Exact);
    5562
    5663enum {
    5764        GFX_NORMAL = 0,
     
    7380       
    7481};
    7582
     83enum {
     84        ASPECT_MIN = 0,
     85
     86        ASPECT_NONE = 0,
     87        ASPECT_SLOPPY = 1,
     88        ASPECT_FAST = 2,
     89        ASPECT_EXACT = 3,
     90
     91        ASPECT_MAX = 3
     92};
    7693
    7794#endif
  • scummvm/common/system.h

    diff -ur ScummVM+orig/scummvm/common/system.h ScummVM+hack/scummvm/common/system.h
    old new  
    9595                PROP_GET_FULLSCREEN = 7,
    9696                PROP_GET_FMOPL_ENV_BITS = 8,
    9797                PROP_GET_FMOPL_EG_ENT = 9,
    98                 PROP_TOGGLE_ASPECT_RATIO = 10
     98                PROP_SET_ASPECT_RATIO_MODE = 10
    9999        };
    100100        union Property {
    101101                const char *caption;
    102102                int cd_num;
    103103                int gfx_mode;
     104                int aspect_ratio_mode;
    104105                bool show_cursor;
    105106        };
    106107       
     
    364365/* Factory functions. This means we don't have to include the headers for
    365366 * all backends.
    366367 */
    367 extern OSystem *OSystem_SDL_create(int gfx_driver, bool full_screen, bool aspect_ratio);
     368extern OSystem *OSystem_SDL_create(int gfx_driver, bool full_screen, int aspect_ratio_mode);
    368369extern OSystem *OSystem_NULL_create();
    369370extern OSystem *OSystem_MorphOS_create(int game_id, int gfx_driver, bool full_screen);
    370371extern OSystem *OSystem_Dreamcast_create();
  • scummvm/scumm/scummvm.cpp

    diff -ur ScummVM+orig/scummvm/scumm/scummvm.cpp ScummVM+hack/scummvm/scumm/scummvm.cpp
    old new  
    586586        _sound->_sound_volume_sfx = detector->_sfx_volume;
    587587        _sound->_sound_volume_music = detector->_music_volume;
    588588
     589        /* Initialize backend */
     590
     591        syst->init_size(_screenWidth, _screenHeight);
     592        prop.cd_num = detector->_cdrom;
     593        if (prop.cd_num >= 0 && (_features & GF_AUDIOTRACKS))
     594                syst->property(OSystem::PROP_OPEN_CD, &prop);
     595
    589596        // Override global scaler with any game-specific define
    590597        if (g_config->get("gfx_mode")) {
    591598                prop.gfx_mode = detector->parseGraphicsMode(g_config->get("gfx_mode"));
    592599                syst->property(OSystem::PROP_SET_GFX_MODE, &prop);
    593600        }
    594601
    595         /* Initialize backend */
    596         syst->init_size(_screenWidth, _screenHeight);
    597         prop.cd_num = detector->_cdrom;
    598         if (prop.cd_num >= 0 && (_features & GF_AUDIOTRACKS))
    599                 syst->property(OSystem::PROP_OPEN_CD, &prop);
     602        // Override global aspect ratio correction with any game-specific define
     603        if (g_config->get("aspect_ratio")) {
     604                prop.aspect_ratio_mode = detector->parseAspectRatioMode(g_config->get("aspect_ratio"));
     605                syst->property(OSystem::PROP_SET_ASPECT_RATIO_MODE, &prop);
     606        }
    600607
    601608        // Override global fullscreen setting with any game-specific define
    602609        if (g_config->getBool("fullscreen", false)) {