Ticket #8250: aspect-modes.diff

File aspect-modes.diff, 26.9 KB (added by eriktorbjorn, 21 years ago)

Patch against a June 24 CVS snapshot

  • scummvm/README

    diff -ur ScummVM-cvs20030624/scummvm/README ScummVM-cvs20030624+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-cvs20030624/scummvm/backends/sdl/sdl-common.cpp ScummVM-cvs20030624+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-cvs20030624/scummvm/backends/sdl/sdl-common.h ScummVM-cvs20030624+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-cvs20030624/scummvm/backends/sdl/sdl.cpp ScummVM-cvs20030624+hack/scummvm/backends/sdl/sdl.cpp
    old new  
    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
     
    134134                break;
    135135        default:
    136136                error("unknown gfx mode %d", _mode);
    137                 _scaleFactor = 1;
    138                 _scaler_proc = NULL;
     137        }
     138
     139        switch (_aspectRatioMode) {
     140        case ASPECT_NONE:
     141                _stretcher_proc = NULL;
     142                break;
     143        case ASPECT_SLOPPY:
     144                _stretcher_proc = stretch200To240Sloppy;
     145                break;
     146        case ASPECT_FAST:
     147                _stretcher_proc = stretch200To240Fast;
     148                break;
     149        case ASPECT_EXACT:
     150                _stretcher_proc = stretch200To240Exact;
     151                break;
     152        default:
     153                error("unknown aspect ratio mode %d", _aspectRatioMode);
    139154        }
    140155
    141156        //
     
    149164        // Create the surface that contains the scaled graphics in 16 bit mode
    150165        //
    151166
    152         _hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor, 16,
     167        _hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor, 16,
    153168                _full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
    154169        );
    155170        if (_hwscreen == NULL)
     
    283298                uint32 srcPitch, dstPitch;
    284299                SDL_Rect *last_rect = _dirty_rect_list + _num_dirty_rects;
    285300
    286                 if (_scaler_proc == Normal1x && !_adjustAspectRatio) {
     301                if (_scaler_proc == Normal1x && _aspectRatioMode == ASPECT_NONE) {
    287302                        SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen;
    288303                        for (r = _dirty_rect_list; r != last_rect; ++r) {
    289304                                dst = *r;
     
    325340
    326341                                        dst_y *= _scaleFactor;
    327342
    328                                         if (_adjustAspectRatio) {
     343                                        if (_aspectRatioMode != ASPECT_NONE) {
    329344                                                orig_dst_y = dst_y;
    330345                                                dst_y = real2Aspect(dst_y);
    331346                                        }
     
    339354                                r->w *= _scaleFactor;
    340355                                r->h = dst_h * _scaleFactor;
    341356
    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);
     357                                if (_stretcher_proc && orig_dst_y / _scaleFactor < _screenHeight)
     358                                        r->h = _stretcher_proc((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
    344359                        }
    345360                        SDL_UnlockSurface(_tmpscreen);
    346361                        SDL_UnlockSurface(_hwscreen);
     
    350365                // This is necessary if shaking is active.
    351366                if (_forceFull) {
    352367                        _dirty_rect_list[0].y = 0;
    353                         _dirty_rect_list[0].h = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor;
     368                        _dirty_rect_list[0].h = ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor;
    354369                }
    355370
    356371                // Finally, blit all our changes to the screen
     
    385400                hotswap_gfx_mode();
    386401
    387402                return 1;
    388         } else if (param == PROP_TOGGLE_ASPECT_RATIO) {
     403        } else if (param == PROP_SET_ASPECT_RATIO_MODE) {
    389404                if (_screenHeight == 200) {
    390                         assert(_hwscreen != 0);
    391                         _adjustAspectRatio ^= true;
     405                        _aspectRatioMode = value->aspect_ratio_mode;
    392406                        hotswap_gfx_mode();
    393407                }
    394408        }
  • scummvm/backends/sdl/sdl_gl.cpp

    diff -ur ScummVM-cvs20030624/scummvm/backends/sdl/sdl_gl.cpp ScummVM-cvs20030624+hack/scummvm/backends/sdl/sdl_gl.cpp
    old new  
    6363        SDL_Surface *_hwscreen;  // hardware screen (=> _usingOpenGL == false)
    6464
    6565        ScalerProc *_scaler_proc;
     66        StretcherProc *_stretcher_proc;
    6667       
    6768        virtual void load_gfx_mode();
    6869        virtual void unload_gfx_mode();
     
    7475}
    7576
    7677OSystem_SDL_OpenGL::OSystem_SDL_OpenGL()
    77   : _hwscreen(0), _scaler_proc(0)
     78  : _hwscreen(0), _scaler_proc(0), _stretcher_proc(0)
    7879{
    7980  _glScreenStart = 0;
    8081  _glBilinearFilter = true;
     
    178179        }
    179180
    180181        if (_mode != GFX_NORMAL)
    181           _usingOpenGL = false;
     182                _usingOpenGL = false;
    182183       
     184        switch (_aspectRatioMode) {
     185        case ASPECT_NONE:
     186                _stretcher_proc = NULL;
     187                break;
     188        case ASPECT_SLOPPY:
     189                _stretcher_proc = stretch200To240Sloppy;
     190                break;
     191        case ASPECT_FAST:
     192                _stretcher_proc = stretch200To240Fast;
     193                break;
     194        case ASPECT_EXACT:
     195                _stretcher_proc = stretch200To240Exact;
     196                break;
     197        default:
     198                error("unknown aspect ratio mode %d", _aspectRatioMode);
     199        }
     200
    183201        //
    184202        // Create the surface that contains the 8 bit game data
    185203        //
     
    203221               
    204222        } else { // SDL backend
    205223         
    206                 _hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor, 16,
     224                _hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor, 16,
    207225                _full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
    208226                );
    209227                if (_hwscreen == NULL)
     
    425443                        fb2gl.display();
    426444                } else { // SDL backend
    427445                       
    428                         if (_scaler_proc == Normal1x && !_adjustAspectRatio) {
     446                        if (_scaler_proc == Normal1x && _aspectRatioMode == ASPECT_NONE) {
    429447                                SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen;
    430448                                for (r = _dirty_rect_list; r != last_rect; ++r) {
    431449                                        dst = *r;
     
    467485                       
    468486                                                        dst_y *= _scaleFactor;
    469487                       
    470                                                         if (_adjustAspectRatio) {
     488                                                        if (_aspectRatioMode != ASPECT_NONE) {
    471489                                                                orig_dst_y = dst_y;
    472490                                                                dst_y = real2Aspect(dst_y);
    473491                                                        }
     
    481499                                        r->w *= _scaleFactor;
    482500                                        r->h = dst_h * _scaleFactor;
    483501
    484                                         if (_adjustAspectRatio && orig_dst_y / _scaleFactor < _screenHeight)
    485                                                 r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
     502                                        if (_stretcher_proc && orig_dst_y / _scaleFactor < _screenHeight)
     503                                                r->h = _stretcher_proc((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
    486504                                }
    487505                       
    488506                                SDL_UnlockSurface(_tmpscreen);
     
    493511                        // This is necessary if shaking is active.
    494512                        if (_forceFull) {
    495513                                _dirty_rect_list[0].y = 0;
    496                                 _dirty_rect_list[0].h = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor;
     514                                _dirty_rect_list[0].h = ((_aspectRatioMode != ASPECT_NONE) ? 240 : _screenHeight) * _scaleFactor;
    497515                        }
    498516                       
    499517                        // Finally, blit all our changes to the screen
     
    555573#endif
    556574
    557575                return 1;
    558         } else if (param == PROP_TOGGLE_ASPECT_RATIO) {
    559 
    560                 _adjustAspectRatio ^= true;
     576        } else if (param == PROP_SET_ASPECT_RATIO_MODE) {
    561577                if (_usingOpenGL) {
    562                         if (_adjustAspectRatio) {
     578                        // OpenGL has only two aspect ratio correction modes.
     579                        if (value->aspect_ratio_mode == ASPECT_MIN)
     580                                _aspectRatioMode = ASPECT_MIN;
     581                        else
     582                                _aspectRatioMode = ASPECT_MAX;
     583                        if (_aspectRatioMode != ASPECT_NONE) {
    563584                                // Don't use the whole screen (black borders)
    564585                                fb2gl.init(0, 0, 0, 15, _glFlags);
    565586                                _glScreenStart = 20;
     
    576597                        fb2gl.display();
    577598                } else {
    578599                        if (_screenHeight == 200) {
    579                                 assert(_hwscreen != 0);
     600                                _aspectRatioMode = value->aspect_ratio_mode;
    580601                                hotswap_gfx_mode();
    581602                        }
    582603                }
  • scummvm/common/gameDetector.cpp

    diff -ur ScummVM-cvs20030624/scummvm/common/gameDetector.cpp ScummVM-cvs20030624+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-cvs20030624/scummvm/common/gameDetector.h ScummVM-cvs20030624+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-cvs20030624/scummvm/common/scaler.cpp ScummVM-cvs20030624+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-cvs20030624/scummvm/common/scaler.h ScummVM-cvs20030624+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-cvs20030624/scummvm/common/system.h ScummVM-cvs20030624+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-cvs20030624/scummvm/scumm/scummvm.cpp ScummVM-cvs20030624+hack/scummvm/scumm/scummvm.cpp
    old new  
    590590        _sound->_sound_volume_sfx = detector->_sfx_volume;
    591591        _sound->_sound_volume_music = detector->_music_volume;
    592592
     593        /* Initialize backend */
     594
     595        syst->init_size(_screenWidth, _screenHeight);
     596        prop.cd_num = detector->_cdrom;
     597        if (prop.cd_num >= 0 && (_features & GF_AUDIOTRACKS))
     598                syst->property(OSystem::PROP_OPEN_CD, &prop);
     599
    593600        // Override global scaler with any game-specific define
    594601        if (g_config->get("gfx_mode")) {
    595602                prop.gfx_mode = detector->parseGraphicsMode(g_config->get("gfx_mode"));
    596603                syst->property(OSystem::PROP_SET_GFX_MODE, &prop);
    597604        }
    598605
    599         /* Initialize backend */
    600         syst->init_size(_screenWidth, _screenHeight);
    601         prop.cd_num = detector->_cdrom;
    602         if (prop.cd_num >= 0 && (_features & GF_AUDIOTRACKS))
    603                 syst->property(OSystem::PROP_OPEN_CD, &prop);
     606        // Override global aspect ratio correction with any game-specific define
     607        if (g_config->get("aspect_ratio")) {
     608                prop.aspect_ratio_mode = detector->parseAspectRatioMode(g_config->get("aspect_ratio"));
     609                syst->property(OSystem::PROP_SET_ASPECT_RATIO_MODE, &prop);
     610        }
    604611
    605612        // Override global fullscreen setting with any game-specific define
    606613        if (g_config->getBool("fullscreen", false)) {