Ticket #8567: scummvm-advmame4x.patch

File scummvm-advmame4x.patch, 14.4 KB (added by SF/mbandsmer, 14 years ago)

Patch against current SVN

  • backends/platform/sdl/graphics.cpp

     
    3232        {"1x", "Normal (no scaling)", GFX_NORMAL},
    3333        {"2x", "2x", GFX_DOUBLESIZE},
    3434        {"3x", "3x", GFX_TRIPLESIZE},
     35        {"4x", "4x", GFX_QUADSIZE},
    3536        {"2xsai", "2xSAI", GFX_2XSAI},
    3637        {"super2xsai", "Super2xSAI", GFX_SUPER2XSAI},
    3738        {"supereagle", "SuperEagle", GFX_SUPEREAGLE},
    3839        {"advmame2x", "AdvMAME2x", GFX_ADVMAME2X},
    3940        {"advmame3x", "AdvMAME3x", GFX_ADVMAME3X},
     41        {"advmame4x", "AdvMAME4x", GFX_ADVMAME4X},
    4042#ifndef DISABLE_HQ_SCALERS
    4143        {"hq2x", "HQ2x", GFX_HQ2X},
    4244        {"hq3x", "HQ3x", GFX_HQ3X},
     
    4850
    4951// Table of relative scalers magnitudes
    5052// [definedScale - 1][_scaleFactor - 1]
    51 static ScalerProc *scalersMagn[3][3] = {
     53static ScalerProc *scalersMagn[4][4] = {
    5254#ifndef DISABLE_SCALERS
    53         { Normal1x, AdvMame2x, AdvMame3x },
    54         { Normal1x, Normal1x, Normal1o5x },
    55         { Normal1x, Normal1x, Normal1x }
     55        { Normal1x, AdvMame2x, AdvMame3x, AdvMame4x },
     56        { Normal1x, Normal1x, Normal1o5x, AdvMame2x },
     57        { Normal1x, Normal1x, Normal1x, Normal1x }, // We'll likely never need a 4/3 scale ratio, so use 1x for now
     58        { Normal1x, Normal1x, Normal1x, Normal1x }
    5659#else // remove dependencies on other scalers
    57         { Normal1x, Normal1x, Normal1x },
    58         { Normal1x, Normal1x, Normal1x },
    59         { Normal1x, Normal1x, Normal1x }
     60        { Normal1x, Normal1x, Normal1x, Normal1x },
     61        { Normal1x, Normal1x, Normal1x, Normal1x },
     62        { Normal1x, Normal1x, Normal1x, Normal1x },
     63        { Normal1x, Normal1x, Normal1x, Normal1x }
    6064#endif
    6165};
    6266
    63 static const int s_gfxModeSwitchTable[][4] = {
    64                 { GFX_NORMAL, GFX_DOUBLESIZE, GFX_TRIPLESIZE, -1 },
    65                 { GFX_NORMAL, GFX_ADVMAME2X, GFX_ADVMAME3X, -1 },
    66                 { GFX_NORMAL, GFX_HQ2X, GFX_HQ3X, -1 },
    67                 { GFX_NORMAL, GFX_2XSAI, -1, -1 },
    68                 { GFX_NORMAL, GFX_SUPER2XSAI, -1, -1 },
    69                 { GFX_NORMAL, GFX_SUPEREAGLE, -1, -1 },
    70                 { GFX_NORMAL, GFX_TV2X, -1, -1 },
    71                 { GFX_NORMAL, GFX_DOTMATRIX, -1, -1 }
     67static const int s_gfxModeSwitchTable[][5] = {
     68                { GFX_NORMAL, GFX_DOUBLESIZE, GFX_TRIPLESIZE, GFX_QUADSIZE, -1 },
     69                { GFX_NORMAL, GFX_ADVMAME2X, GFX_ADVMAME3X, GFX_ADVMAME4X, -1 },
     70                { GFX_NORMAL, GFX_HQ2X, GFX_HQ3X, -1, -1 },
     71                { GFX_NORMAL, GFX_2XSAI, -1, -1, -1 },
     72                { GFX_NORMAL, GFX_SUPER2XSAI, -1, -1, -1 },
     73                { GFX_NORMAL, GFX_SUPEREAGLE, -1, -1, -1 },
     74                { GFX_NORMAL, GFX_TV2X, -1, -1, -1 },
     75                { GFX_NORMAL, GFX_DOTMATRIX, -1, -1, -1 },
    7276        };
    7377
    7478#ifndef DISABLE_SCALERS
     
    162166                newScaleFactor = 3;
    163167                newScalerProc = Normal3x;
    164168                break;
     169        case GFX_QUADSIZE:
     170                newScaleFactor = 4;
     171                newScalerProc = Normal4x;
     172                break;
    165173
    166174        case GFX_2XSAI:
    167175                newScaleFactor = 2;
     
    183191                newScaleFactor = 3;
    184192                newScalerProc = AdvMame3x;
    185193                break;
     194        case GFX_ADVMAME4X:
     195                newScaleFactor = 4;
     196                newScalerProc = AdvMame4x;
     197                break;
    186198#ifndef DISABLE_HQ_SCALERS
    187199        case GFX_HQ2X:
    188200                newScaleFactor = 2;
     
    375387                InitScalers(565);
    376388
    377389        // Need some extra bytes around when using 2xSaI
    378         _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth + 3, _screenHeight + 3,
     390        _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE,
     391                                                _screenWidth + 2 * MAX_SCALER_REACH,
     392                                                _screenHeight + 2 * MAX_SCALER_REACH,
    379393                                                16,
    380394                                                _hwscreen->format->Rmask,
    381395                                                _hwscreen->format->Gmask,
     
    395409        if (_overlayscreen == NULL)
    396410                error("allocating _overlayscreen failed");
    397411
    398         _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth + 3, _overlayHeight + 3,
     412        _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE,
     413                                                _overlayWidth + 2 * MAX_SCALER_REACH,
     414                                                _overlayHeight + 2 * MAX_SCALER_REACH,
    399415                                                16,
    400416                                                _hwscreen->format->Rmask,
    401417                                                _hwscreen->format->Gmask,
     
    615631                } else {
    616632                        for (r = _dirtyRectList; r != lastRect; ++r) {
    617633                                dst = *r;
    618                                 dst.x++;        // Shift rect by one since 2xSai needs to acces the data around
    619                                 dst.y++;        // any pixel to scale it, and we want to avoid mem access crashes.
     634                                dst.x += MAX_SCALER_REACH;      // Shift rect since scalers need to acces the data around
     635                                dst.y += MAX_SCALER_REACH;      // any pixel to scale it, and we want to avoid mem access crashes.
    620636
    621637                                if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0)
    622638                                        error("SDL_BlitSurface failed: %s", SDL_GetError());
     
    646662                                                dst_y = real2Aspect(dst_y);
    647663
    648664                                        assert(scalerProc != NULL);
    649                                         scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
     665                                        scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2 * MAX_SCALER_REACH) + (r->y + MAX_SCALER_REACH) * srcPitch, srcPitch,
    650666                                                           (byte *)_hwscreen->pixels + rx1 * 2 + dst_y * dstPitch, dstPitch, r->w, dst_h);
    651667                                }
    652668
     
    11541170        // Clear the overlay by making the game screen "look through" everywhere.
    11551171        SDL_Rect src, dst;
    11561172        src.x = src.y = 0;
    1157         dst.x = dst.y = 1;
     1173        dst.x = dst.y = MAX_SCALER_REACH;
    11581174        src.w = dst.w = _screenWidth;
    11591175        src.h = dst.h = _screenHeight;
    11601176        if (SDL_BlitSurface(_screen, &src, _tmpscreen, &dst) != 0)
     
    11621178
    11631179        SDL_LockSurface(_tmpscreen);
    11641180        SDL_LockSurface(_overlayscreen);
    1165         _scalerProc((byte *)(_tmpscreen->pixels) + _tmpscreen->pitch + 2, _tmpscreen->pitch,
     1181        _scalerProc((byte *)(_tmpscreen->pixels) + (_tmpscreen->pitch + 2) * MAX_SCALER_REACH, _tmpscreen->pitch,
    11661182        (byte *)_overlayscreen->pixels, _overlayscreen->pitch, _screenWidth, _screenHeight);
    11671183
    11681184#ifndef DISABLE_SCALERS
     
    13131329                if (_mouseOrigSurface)
    13141330                        SDL_FreeSurface(_mouseOrigSurface);
    13151331
    1316                 // Allocate bigger surface because AdvMame2x adds black pixel at [0,0]
     1332                // Allocate bigger surface for scalers to access
    13171333                _mouseOrigSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
    1318                                                 _mouseCurState.w + 2,
    1319                                                 _mouseCurState.h + 2,
     1334                                                _mouseCurState.w + 2 * MAX_SCALER_REACH,
     1335                                                _mouseCurState.h + 2 * MAX_SCALER_REACH,
    13201336                                                16,
    13211337                                                _hwscreen->format->Rmask,
    13221338                                                _hwscreen->format->Gmask,
     
    13501366        SDL_LockSurface(_mouseOrigSurface);
    13511367
    13521368        // Make whole surface transparent
    1353         for (i = 0; i < h + 2; i++) {
     1369        for (i = 0; i < h + 2 * MAX_SCALER_REACH; i++) {
    13541370                dstPtr = (byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch * i;
    1355                 for (j = 0; j < w + 2; j++) {
     1371                for (j = 0; j < w + 2 * MAX_SCALER_REACH; j++) {
    13561372                        *(uint16 *)dstPtr = kMouseColorKey;
    13571373                        dstPtr += 2;
    13581374                }
    13591375        }
    13601376
    1361         // Draw from [1,1] since AdvMame2x adds artefact at 0,0
    1362         dstPtr = (byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2;
     1377        // Draw the cursor in the center of the surface
     1378        dstPtr = (byte *)_mouseOrigSurface->pixels + (_mouseOrigSurface->pitch + 2) * MAX_SCALER_REACH;
    13631379
    13641380        SDL_Color *palette;
    13651381
     
    14581474        // the game. This only works well with the non-blurring scalers so we
    14591475        // actually only use the 1x, 1.5x, 2x and AdvMame scalers.
    14601476
    1461         if (_cursorTargetScale == 1 && (_mode == GFX_DOUBLESIZE || _mode == GFX_TRIPLESIZE))
     1477        if (_cursorTargetScale == 1 && (_mode == GFX_DOUBLESIZE || _mode == GFX_TRIPLESIZE || _mode == GFX_QUADSIZE))
    14621478                scalerProc = _scalerProc;
    14631479        else
    14641480                scalerProc = scalersMagn[_cursorTargetScale - 1][_scaleFactor - 1];
    14651481
    1466         scalerProc((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2,
     1482        scalerProc((byte *)_mouseOrigSurface->pixels + (_mouseOrigSurface->pitch + 2) * MAX_SCALER_REACH,
    14671483                _mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch,
    14681484                _mouseCurState.w, _mouseCurState.h);
    14691485
  • backends/platform/sdl/sdl-common.h

     
    4343        GFX_NORMAL = 0,
    4444        GFX_DOUBLESIZE = 1,
    4545        GFX_TRIPLESIZE = 2,
    46         GFX_2XSAI = 3,
    47         GFX_SUPER2XSAI = 4,
    48         GFX_SUPEREAGLE = 5,
    49         GFX_ADVMAME2X = 6,
    50         GFX_ADVMAME3X = 7,
    51         GFX_HQ2X = 8,
    52         GFX_HQ3X = 9,
    53         GFX_TV2X = 10,
    54         GFX_DOTMATRIX = 11
     46        GFX_QUADSIZE = 3,
     47        GFX_2XSAI = 4,
     48        GFX_SUPER2XSAI = 5,
     49        GFX_SUPEREAGLE = 6,
     50        GFX_ADVMAME2X = 7,
     51        GFX_ADVMAME3X = 8,
     52        GFX_ADVMAME4X = 9,
     53        GFX_HQ2X = 10,
     54        GFX_HQ3X = 11,
     55        GFX_TV2X = 12,
     56        GFX_DOTMATRIX = 13
    5557};
    5658
    5759
     
    277279
    278280                MAX_MOUSE_W = 80,
    279281                MAX_MOUSE_H = 80,
    280                 MAX_SCALING = 3
     282                MAX_SCALING = 4
    281283        };
    282284
    283285        // Dirty rect management
  • base/commandLine.cpp

     
    8080        "  -x, --save-slot[=NUM]    Save game slot to load (default: autosave)\n"
    8181        "  -f, --fullscreen         Force full-screen mode\n"
    8282        "  -F, --no-fullscreen      Force windowed mode\n"
    83         "  -g, --gfx-mode=MODE      Select graphics scaler (normal,2x,3x,2xsai,\n"
    84         "                           super2xsai,supereagle,advmame2x,advmame3x,hq2x,\n"
    85         "                           hq3x,tv2x,dotmatrix)\n"
     83        "  -g, --gfx-mode=MODE      Select graphics scaler (normal,2x,3x,4x,2xsai,\n"
     84        "                           super2xsai,supereagle,advmame2x,advmame3x,advmame4x,\n"
     85        "                           hq2x,hq3x,tv2x,dotmatrix)\n"
    8686        "  --gui-theme=THEME        Select GUI theme (default, modern, classic)\n"
    8787        "  --themepath=PATH         Path to where GUI themes are stored\n"
    8888        "  -e, --music-driver=MODE  Select music driver (see README for details)\n"
  • graphics/scaler.cpp

     
    178178        }
    179179}
    180180
     181/**
     182 * Trivial nearest-neighbour 4x scaler.
     183 */
     184void Normal4x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
     185                                                        int width, int height) {
     186        uint8 *r;
     187        const uint32 dstPitch2 = dstPitch * 2;
     188        const uint32 dstPitch3 = dstPitch * 3;
     189        const uint32 dstPitch4 = dstPitch * 4;
     190
     191        assert(((long)dstPtr & 1) == 0);
     192        while (height--) {
     193                r = dstPtr;
     194                for (int i = 0; i < width; ++i, r += 8) {
     195                        uint16 color = *(((const uint16 *)srcPtr) + i);
     196
     197                        *(uint16 *)(r + 0) = color;
     198                        *(uint16 *)(r + 2) = color;
     199                        *(uint16 *)(r + 4) = color;
     200                        *(uint16 *)(r + 6) = color;
     201                        *(uint16 *)(r + 0 + dstPitch) = color;
     202                        *(uint16 *)(r + 2 + dstPitch) = color;
     203                        *(uint16 *)(r + 4 + dstPitch) = color;
     204                        *(uint16 *)(r + 6 + dstPitch) = color;
     205                        *(uint16 *)(r + 0 + dstPitch2) = color;
     206                        *(uint16 *)(r + 2 + dstPitch2) = color;
     207                        *(uint16 *)(r + 4 + dstPitch2) = color;
     208                        *(uint16 *)(r + 6 + dstPitch2) = color;
     209                        *(uint16 *)(r + 0 + dstPitch3) = color;
     210                        *(uint16 *)(r + 2 + dstPitch3) = color;
     211                        *(uint16 *)(r + 4 + dstPitch3) = color;
     212                        *(uint16 *)(r + 6 + dstPitch3) = color;
     213                }
     214                srcPtr += srcPitch;
     215                dstPtr += dstPitch4;
     216        }
     217}
     218
    181219#define interpolate32_1_1               interpolate32_1_1<bitFormat>
    182220#define interpolate32_1_1_1_1   interpolate32_1_1_1_1<bitFormat>
    183221
     
    236274        scale(3, dstPtr, dstPitch, srcPtr - srcPitch, srcPitch, 2, width, height);
    237275}
    238276
     277/**
     278 * The Scale4x filter, also known as AdvMame4x.
     279 * See also http://scale2x.sourceforge.net
     280 */
     281void AdvMame4x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
     282                                                         int width, int height) {
     283        scale(4, dstPtr, dstPitch, srcPtr - 2 * srcPitch, srcPitch, 2, width, height);
     284}
     285
    239286template<int bitFormat>
    240287void TV2xTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
    241288                                        int width, int height) {
  • graphics/scaler.h

     
    4040DECLARE_SCALER(SuperEagle);
    4141DECLARE_SCALER(AdvMame2x);
    4242DECLARE_SCALER(AdvMame3x);
     43DECLARE_SCALER(AdvMame4x);
    4344DECLARE_SCALER(Normal1x);
    4445DECLARE_SCALER(Normal2x);
    4546DECLARE_SCALER(Normal3x);
     47DECLARE_SCALER(Normal4x);
    4648DECLARE_SCALER(Normal1o5x);
    4749DECLARE_SCALER(TV2x);
    4850DECLARE_SCALER(DotMatrix);
     
    5254DECLARE_SCALER(HQ3x);
    5355#endif
    5456
     57// Define MAX_SCALER_REACH as the largest "reach" of all supported scalers.
     58// This determines how much extra border we need to allocate for surfaces that
     59// get scaled.
     60//
     61// A scaler's "reach" is the distance of the furthest source pixel that
     62// the scaler examines in determining the color of a destination pixel.  E.g:
     63// * Normalxx scalers have a reach of 0, because each destination pixel is
     64//             based on only one corresponding source pixel.
     65// * AdvMame2x examines the source pixel and adjacent pixels, but no further,
     66//             and therefore has a reach of 1.
     67// * AdvMame4x examines all pixels within a 2-pixel radius of the source pixel,
     68//             and therefore has a reach of 2.
     69#define MAX_SCALER_REACH 2
     70
    5571FORCEINLINE int real2Aspect(int y) {
    5672        return y + (y + 1) / 5;
    5773}
  • graphics/scaler/scalebit.cpp

     
    193193        unsigned count;
    194194        unsigned char* mid[6];
    195195
    196         assert(height >= 4);
    197 
    198196        count = height;
    199197
    200198        /* set the 6 buffer pointers */
     
    205203        mid[4] = mid[3] + mid_slice;
    206204        mid[5] = mid[4] + mid_slice;
    207205
     206        /* initialize the temporary buffer */
     207        stage_scale2x(SCMID(0), SCMID(1), SCSRC(0) - pixel, SCSRC(1) - pixel, SCSRC(2) - pixel, pixel, width + 2);
     208        stage_scale2x(SCMID(2), SCMID(3), SCSRC(1) - pixel, SCSRC(2) - pixel, SCSRC(3) - pixel, pixel, width + 2);
     209
    208210        while (count) {
    209211                unsigned char* tmp;
    210212
    211                 stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(4), pixel, width);
    212                 stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
     213                stage_scale2x(SCMID(4), SCMID(5), SCSRC(2) - pixel, SCSRC(3) - pixel, SCSRC(4) - pixel, pixel, width + 2);
     214                stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1) + 2 * pixel, SCMID(2) + 2 * pixel, SCMID(3) + 2 * pixel, SCMID(4) + 2 * pixel, pixel, width);
    213215
    214216                dst = SCDST(4);
    215217                src = SCSRC(1);
     
    252254        unsigned mid_slice;
    253255        void* mid;
    254256
    255         mid_slice = 2 * pixel * width; /* required space for 1 row buffer */
     257        mid_slice = 2 * pixel * (width + 2); /* required space for 1 row buffer */
    256258
    257259        mid_slice = (mid_slice + 0x7) & ~0x7; /* align to 8 bytes */
    258260
  • gui/themes/modern.ini

     
    166166fontfile_fixed_normal="courr12-l1.bdf"
    167167cursor_hotspot_x=0
    168168cursor_hotspot_y=0
    169 cursor_targetScale=3
     169cursor_targetScale=4
    170170
    171171[XxY]
    172172skipFor=320xY,256x240