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