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