src/render/software/SDL_blendpoint.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 04 Feb 2011 19:50:56 -0800
changeset 5184 d976b67150c5
parent 5163 d72793305335
child 5226 710d00cb3a6a
permissions -rw-r--r--
Restored SDL_BLENDMODE_MOD for MAME
slouken@2901
     1
/*
slouken@2901
     2
    SDL - Simple DirectMedia Layer
slouken@3697
     3
    Copyright (C) 1997-2010 Sam Lantinga
slouken@2901
     4
slouken@2901
     5
    This library is free software; you can redistribute it and/or
slouken@2901
     6
    modify it under the terms of the GNU Lesser General Public
slouken@2901
     7
    License as published by the Free Software Foundation; either
slouken@2901
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@2901
     9
slouken@2901
    10
    This library is distributed in the hope that it will be useful,
slouken@2901
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@2901
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@2901
    13
    Lesser General Public License for more details.
slouken@2901
    14
slouken@2901
    15
    You should have received a copy of the GNU Lesser General Public
slouken@2901
    16
    License along with this library; if not, write to the Free Software
slouken@2901
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@2901
    18
slouken@2901
    19
    Sam Lantinga
slouken@2901
    20
    slouken@libsdl.org
slouken@2901
    21
*/
slouken@2901
    22
#include "SDL_config.h"
slouken@2901
    23
slouken@2901
    24
#include "SDL_draw.h"
slouken@5163
    25
#include "SDL_blendpoint.h"
slouken@5163
    26
slouken@2901
    27
slouken@2901
    28
static int
slouken@4929
    29
SDL_BlendPoint_RGB555(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
    30
                      Uint8 g, Uint8 b, Uint8 a)
slouken@2901
    31
{
slouken@2901
    32
    unsigned inva = 0xff - a;
slouken@2901
    33
slouken@2901
    34
    switch (blendMode) {
slouken@2901
    35
    case SDL_BLENDMODE_BLEND:
slouken@2901
    36
        DRAW_SETPIXELXY_BLEND_RGB555(x, y);
slouken@2901
    37
        break;
slouken@2901
    38
    case SDL_BLENDMODE_ADD:
slouken@2901
    39
        DRAW_SETPIXELXY_ADD_RGB555(x, y);
slouken@2901
    40
        break;
slouken@5184
    41
    case SDL_BLENDMODE_MOD:
slouken@5184
    42
        DRAW_SETPIXELXY_MOD_RGB555(x, y);
slouken@5184
    43
        break;
slouken@2901
    44
    default:
slouken@2901
    45
        DRAW_SETPIXELXY_RGB555(x, y);
slouken@2901
    46
        break;
slouken@2901
    47
    }
slouken@2901
    48
    return 0;
slouken@2901
    49
}
slouken@2901
    50
slouken@2901
    51
static int
slouken@4929
    52
SDL_BlendPoint_RGB565(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
    53
                      Uint8 g, Uint8 b, Uint8 a)
slouken@2901
    54
{
slouken@2901
    55
    unsigned inva = 0xff - a;
slouken@2901
    56
slouken@2901
    57
    switch (blendMode) {
slouken@2901
    58
    case SDL_BLENDMODE_BLEND:
slouken@2901
    59
        DRAW_SETPIXELXY_BLEND_RGB565(x, y);
slouken@2901
    60
        break;
slouken@2901
    61
    case SDL_BLENDMODE_ADD:
slouken@2901
    62
        DRAW_SETPIXELXY_ADD_RGB565(x, y);
slouken@2901
    63
        break;
slouken@5184
    64
    case SDL_BLENDMODE_MOD:
slouken@5184
    65
        DRAW_SETPIXELXY_MOD_RGB565(x, y);
slouken@5184
    66
        break;
slouken@2901
    67
    default:
slouken@2901
    68
        DRAW_SETPIXELXY_RGB565(x, y);
slouken@2901
    69
        break;
slouken@2901
    70
    }
slouken@2901
    71
    return 0;
slouken@2901
    72
}
slouken@2901
    73
slouken@2901
    74
static int
slouken@4929
    75
SDL_BlendPoint_RGB888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
    76
                      Uint8 g, Uint8 b, Uint8 a)
slouken@2901
    77
{
slouken@2901
    78
    unsigned inva = 0xff - a;
slouken@2901
    79
slouken@2901
    80
    switch (blendMode) {
slouken@2901
    81
    case SDL_BLENDMODE_BLEND:
slouken@2901
    82
        DRAW_SETPIXELXY_BLEND_RGB888(x, y);
slouken@2901
    83
        break;
slouken@2901
    84
    case SDL_BLENDMODE_ADD:
slouken@2901
    85
        DRAW_SETPIXELXY_ADD_RGB888(x, y);
slouken@2901
    86
        break;
slouken@5184
    87
    case SDL_BLENDMODE_MOD:
slouken@5184
    88
        DRAW_SETPIXELXY_MOD_RGB888(x, y);
slouken@5184
    89
        break;
slouken@2901
    90
    default:
slouken@2901
    91
        DRAW_SETPIXELXY_RGB888(x, y);
slouken@2901
    92
        break;
slouken@2901
    93
    }
slouken@2901
    94
    return 0;
slouken@2901
    95
}
slouken@2901
    96
slouken@2901
    97
static int
slouken@4929
    98
SDL_BlendPoint_ARGB8888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode,
slouken@2901
    99
                        Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2901
   100
{
slouken@2901
   101
    unsigned inva = 0xff - a;
slouken@2901
   102
slouken@2901
   103
    switch (blendMode) {
slouken@2901
   104
    case SDL_BLENDMODE_BLEND:
slouken@2901
   105
        DRAW_SETPIXELXY_BLEND_ARGB8888(x, y);
slouken@2901
   106
        break;
slouken@2901
   107
    case SDL_BLENDMODE_ADD:
slouken@2901
   108
        DRAW_SETPIXELXY_ADD_ARGB8888(x, y);
slouken@2901
   109
        break;
slouken@5184
   110
    case SDL_BLENDMODE_MOD:
slouken@5184
   111
        DRAW_SETPIXELXY_MOD_ARGB8888(x, y);
slouken@5184
   112
        break;
slouken@2901
   113
    default:
slouken@2901
   114
        DRAW_SETPIXELXY_ARGB8888(x, y);
slouken@2901
   115
        break;
slouken@2901
   116
    }
slouken@2901
   117
    return 0;
slouken@2901
   118
}
slouken@2901
   119
slouken@2901
   120
static int
slouken@4929
   121
SDL_BlendPoint_RGB(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
   122
                   Uint8 g, Uint8 b, Uint8 a)
slouken@2901
   123
{
slouken@2901
   124
    SDL_PixelFormat *fmt = dst->format;
slouken@2901
   125
    unsigned inva = 0xff - a;
slouken@2901
   126
slouken@2901
   127
    switch (fmt->BytesPerPixel) {
slouken@2901
   128
    case 2:
slouken@2901
   129
        switch (blendMode) {
slouken@2901
   130
        case SDL_BLENDMODE_BLEND:
slouken@2901
   131
            DRAW_SETPIXELXY2_BLEND_RGB(x, y);
slouken@2901
   132
            break;
slouken@2901
   133
        case SDL_BLENDMODE_ADD:
slouken@2901
   134
            DRAW_SETPIXELXY2_ADD_RGB(x, y);
slouken@2901
   135
            break;
slouken@5184
   136
        case SDL_BLENDMODE_MOD:
slouken@5184
   137
            DRAW_SETPIXELXY2_MOD_RGB(x, y);
slouken@5184
   138
            break;
slouken@2901
   139
        default:
slouken@2901
   140
            DRAW_SETPIXELXY2_RGB(x, y);
slouken@2901
   141
            break;
slouken@2901
   142
        }
slouken@2901
   143
        return 0;
slouken@2901
   144
    case 4:
slouken@2901
   145
        switch (blendMode) {
slouken@2901
   146
        case SDL_BLENDMODE_BLEND:
slouken@2901
   147
            DRAW_SETPIXELXY4_BLEND_RGB(x, y);
slouken@2901
   148
            break;
slouken@2901
   149
        case SDL_BLENDMODE_ADD:
slouken@2901
   150
            DRAW_SETPIXELXY4_ADD_RGB(x, y);
slouken@2901
   151
            break;
slouken@5184
   152
        case SDL_BLENDMODE_MOD:
slouken@5184
   153
            DRAW_SETPIXELXY4_MOD_RGB(x, y);
slouken@5184
   154
            break;
slouken@2901
   155
        default:
slouken@2901
   156
            DRAW_SETPIXELXY4_RGB(x, y);
slouken@2901
   157
            break;
slouken@2901
   158
        }
slouken@2901
   159
        return 0;
slouken@2901
   160
    default:
slouken@2901
   161
        SDL_Unsupported();
slouken@2901
   162
        return -1;
slouken@2901
   163
    }
slouken@2901
   164
}
slouken@2901
   165
slouken@2901
   166
static int
slouken@4929
   167
SDL_BlendPoint_RGBA(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
   168
                    Uint8 g, Uint8 b, Uint8 a)
slouken@2901
   169
{
slouken@2901
   170
    SDL_PixelFormat *fmt = dst->format;
slouken@2901
   171
    unsigned inva = 0xff - a;
slouken@2901
   172
slouken@2901
   173
    switch (fmt->BytesPerPixel) {
slouken@2901
   174
    case 4:
slouken@2901
   175
        switch (blendMode) {
slouken@2901
   176
        case SDL_BLENDMODE_BLEND:
slouken@2901
   177
            DRAW_SETPIXELXY4_BLEND_RGBA(x, y);
slouken@2901
   178
            break;
slouken@2901
   179
        case SDL_BLENDMODE_ADD:
slouken@2901
   180
            DRAW_SETPIXELXY4_ADD_RGBA(x, y);
slouken@2901
   181
            break;
slouken@5184
   182
        case SDL_BLENDMODE_MOD:
slouken@5184
   183
            DRAW_SETPIXELXY4_MOD_RGBA(x, y);
slouken@5184
   184
            break;
slouken@2901
   185
        default:
slouken@2901
   186
            DRAW_SETPIXELXY4_RGBA(x, y);
slouken@2901
   187
            break;
slouken@2901
   188
        }
slouken@2901
   189
        return 0;
slouken@2901
   190
    default:
slouken@2901
   191
        SDL_Unsupported();
slouken@2901
   192
        return -1;
slouken@2901
   193
    }
slouken@2901
   194
}
slouken@2901
   195
slouken@2901
   196
int
slouken@4929
   197
SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
   198
               Uint8 g, Uint8 b, Uint8 a)
slouken@2901
   199
{
slouken@3536
   200
    if (!dst) {
slouken@3536
   201
        SDL_SetError("Passed NULL destination surface");
slouken@3536
   202
        return -1;
slouken@3536
   203
    }
slouken@2901
   204
slouken@2901
   205
    /* This function doesn't work on surfaces < 8 bpp */
slouken@2901
   206
    if (dst->format->BitsPerPixel < 8) {
slouken@2901
   207
        SDL_SetError("SDL_BlendPoint(): Unsupported surface format");
slouken@3536
   208
        return -1;
slouken@2901
   209
    }
slouken@2901
   210
slouken@2901
   211
    /* Perform clipping */
slouken@2901
   212
    if (x < dst->clip_rect.x || y < dst->clip_rect.y ||
slouken@2901
   213
        x >= (dst->clip_rect.x + dst->clip_rect.w) ||
slouken@2901
   214
        y >= (dst->clip_rect.y + dst->clip_rect.h)) {
slouken@2901
   215
        return 0;
slouken@2901
   216
    }
slouken@2901
   217
slouken@3536
   218
    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
slouken@2901
   219
        r = DRAW_MUL(r, a);
slouken@2901
   220
        g = DRAW_MUL(g, a);
slouken@2901
   221
        b = DRAW_MUL(b, a);
slouken@2901
   222
    }
slouken@2901
   223
slouken@3536
   224
    switch (dst->format->BitsPerPixel) {
slouken@2901
   225
    case 15:
slouken@3536
   226
        switch (dst->format->Rmask) {
slouken@2901
   227
        case 0x7C00:
slouken@2901
   228
            return SDL_BlendPoint_RGB555(dst, x, y, blendMode, r, g, b, a);
slouken@2901
   229
        }
slouken@2901
   230
        break;
slouken@2901
   231
    case 16:
slouken@3536
   232
        switch (dst->format->Rmask) {
slouken@2901
   233
        case 0xF800:
slouken@2901
   234
            return SDL_BlendPoint_RGB565(dst, x, y, blendMode, r, g, b, a);
slouken@2901
   235
        }
slouken@2901
   236
        break;
slouken@2901
   237
    case 32:
slouken@3536
   238
        switch (dst->format->Rmask) {
slouken@2901
   239
        case 0x00FF0000:
slouken@3536
   240
            if (!dst->format->Amask) {
slouken@2901
   241
                return SDL_BlendPoint_RGB888(dst, x, y, blendMode, r, g, b,
slouken@2901
   242
                                             a);
slouken@2901
   243
            } else {
slouken@2901
   244
                return SDL_BlendPoint_ARGB8888(dst, x, y, blendMode, r, g, b,
slouken@2901
   245
                                               a);
slouken@2901
   246
            }
slouken@2901
   247
            break;
slouken@2901
   248
        }
slouken@3536
   249
        break;
slouken@2901
   250
    default:
slouken@2901
   251
        break;
slouken@2901
   252
    }
slouken@2901
   253
slouken@3536
   254
    if (!dst->format->Amask) {
slouken@2901
   255
        return SDL_BlendPoint_RGB(dst, x, y, blendMode, r, g, b, a);
slouken@2901
   256
    } else {
slouken@2901
   257
        return SDL_BlendPoint_RGBA(dst, x, y, blendMode, r, g, b, a);
slouken@2901
   258
    }
slouken@2901
   259
}
slouken@2901
   260
slouken@3536
   261
int
slouken@3536
   262
SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count,
slouken@4929
   263
                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@3536
   264
{
slouken@3536
   265
    int minx, miny;
slouken@3536
   266
    int maxx, maxy;
slouken@3536
   267
    int i;
slouken@3536
   268
    int x, y;
slouken@3536
   269
    int (*func)(SDL_Surface * dst, int x, int y,
slouken@4929
   270
                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
slouken@3536
   271
    int status = 0;
slouken@3536
   272
slouken@3536
   273
    if (!dst) {
slouken@3536
   274
        SDL_SetError("Passed NULL destination surface");
slouken@3536
   275
        return -1;
slouken@3536
   276
    }
slouken@3536
   277
slouken@3536
   278
    /* This function doesn't work on surfaces < 8 bpp */
slouken@3536
   279
    if (dst->format->BitsPerPixel < 8) {
slouken@3536
   280
        SDL_SetError("SDL_BlendPoints(): Unsupported surface format");
slouken@3536
   281
        return (-1);
slouken@3536
   282
    }
slouken@3536
   283
slouken@3536
   284
    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
slouken@3536
   285
        r = DRAW_MUL(r, a);
slouken@3536
   286
        g = DRAW_MUL(g, a);
slouken@3536
   287
        b = DRAW_MUL(b, a);
slouken@3536
   288
    }
slouken@3536
   289
slouken@3536
   290
    /* FIXME: Does this function pointer slow things down significantly? */
slouken@3536
   291
    switch (dst->format->BitsPerPixel) {
slouken@3536
   292
    case 15:
slouken@3536
   293
        switch (dst->format->Rmask) {
slouken@3536
   294
        case 0x7C00:
slouken@3536
   295
            func = SDL_BlendPoint_RGB555;
slouken@3536
   296
            break;
slouken@3536
   297
        }
slouken@3536
   298
        break;
slouken@3536
   299
    case 16:
slouken@3536
   300
        switch (dst->format->Rmask) {
slouken@3536
   301
        case 0xF800:
slouken@3536
   302
            func = SDL_BlendPoint_RGB565;
slouken@3536
   303
            break;
slouken@3536
   304
        }
slouken@3536
   305
        break;
slouken@3536
   306
    case 32:
slouken@3536
   307
        switch (dst->format->Rmask) {
slouken@3536
   308
        case 0x00FF0000:
slouken@3536
   309
            if (!dst->format->Amask) {
slouken@3536
   310
                func = SDL_BlendPoint_RGB888;
slouken@3536
   311
            } else {
slouken@3536
   312
                func = SDL_BlendPoint_ARGB8888;
slouken@3536
   313
            }
slouken@3536
   314
            break;
slouken@3536
   315
        }
slouken@3536
   316
        break;
slouken@3536
   317
    default:
slouken@3536
   318
        break;
slouken@3536
   319
    }
slouken@3536
   320
slouken@3536
   321
    if (!func) {
slouken@3536
   322
        if (!dst->format->Amask) {
slouken@3536
   323
            func = SDL_BlendPoint_RGB;
slouken@3536
   324
        } else {
slouken@3536
   325
            func = SDL_BlendPoint_RGBA;
slouken@3536
   326
        }
slouken@3536
   327
    }
slouken@3536
   328
slouken@3536
   329
    minx = dst->clip_rect.x;
slouken@3536
   330
    maxx = dst->clip_rect.x + dst->clip_rect.w - 1;
slouken@3536
   331
    miny = dst->clip_rect.y;
slouken@3536
   332
    maxy = dst->clip_rect.y + dst->clip_rect.h - 1;
slouken@3536
   333
slouken@3536
   334
    for (i = 0; i < count; ++i) {
slouken@3536
   335
        x = points[i].x;
slouken@3536
   336
        y = points[i].y;
slouken@3536
   337
slouken@3536
   338
        if (x < minx || x > maxx || y < miny || y > maxy) {
slouken@3536
   339
            continue;
slouken@3536
   340
        }
slouken@3536
   341
        status = func(dst, x, y, blendMode, r, g, b, a);
slouken@3536
   342
    }
slouken@3536
   343
    return status;
slouken@3536
   344
}
slouken@3536
   345
slouken@2901
   346
/* vi: set ts=4 sw=4 expandtab: */