src/render/software/SDL_blendpoint.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 31 Mar 2013 12:48:50 -0400
changeset 7037 3fedf1f25b94
parent 6885 700f1b25f77f
child 8093 b43765095a6f
permissions -rw-r--r--
Make SDL_SetError and friends unconditionally return -1.

This lets us change things like this...

if (Failed) {
SDL_SetError("We failed");
return -1;
}

...into this...

if (Failed) {
return SDL_SetError("We failed");
}


Fixes Bugzilla #1778.
slouken@2901
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6885
     3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
slouken@2901
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@2901
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@2901
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@2901
    20
*/
slouken@2901
    21
#include "SDL_config.h"
slouken@2901
    22
slouken@5226
    23
#if !SDL_RENDER_DISABLED
slouken@5226
    24
slouken@2901
    25
#include "SDL_draw.h"
slouken@5163
    26
#include "SDL_blendpoint.h"
slouken@5163
    27
slouken@2901
    28
slouken@2901
    29
static int
slouken@4929
    30
SDL_BlendPoint_RGB555(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
    31
                      Uint8 g, Uint8 b, Uint8 a)
slouken@2901
    32
{
slouken@2901
    33
    unsigned inva = 0xff - a;
slouken@2901
    34
slouken@2901
    35
    switch (blendMode) {
slouken@2901
    36
    case SDL_BLENDMODE_BLEND:
slouken@2901
    37
        DRAW_SETPIXELXY_BLEND_RGB555(x, y);
slouken@2901
    38
        break;
slouken@2901
    39
    case SDL_BLENDMODE_ADD:
slouken@2901
    40
        DRAW_SETPIXELXY_ADD_RGB555(x, y);
slouken@2901
    41
        break;
slouken@5184
    42
    case SDL_BLENDMODE_MOD:
slouken@5184
    43
        DRAW_SETPIXELXY_MOD_RGB555(x, y);
slouken@5184
    44
        break;
slouken@2901
    45
    default:
slouken@2901
    46
        DRAW_SETPIXELXY_RGB555(x, y);
slouken@2901
    47
        break;
slouken@2901
    48
    }
slouken@2901
    49
    return 0;
slouken@2901
    50
}
slouken@2901
    51
slouken@2901
    52
static int
slouken@4929
    53
SDL_BlendPoint_RGB565(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
    54
                      Uint8 g, Uint8 b, Uint8 a)
slouken@2901
    55
{
slouken@2901
    56
    unsigned inva = 0xff - a;
slouken@2901
    57
slouken@2901
    58
    switch (blendMode) {
slouken@2901
    59
    case SDL_BLENDMODE_BLEND:
slouken@2901
    60
        DRAW_SETPIXELXY_BLEND_RGB565(x, y);
slouken@2901
    61
        break;
slouken@2901
    62
    case SDL_BLENDMODE_ADD:
slouken@2901
    63
        DRAW_SETPIXELXY_ADD_RGB565(x, y);
slouken@2901
    64
        break;
slouken@5184
    65
    case SDL_BLENDMODE_MOD:
slouken@5184
    66
        DRAW_SETPIXELXY_MOD_RGB565(x, y);
slouken@5184
    67
        break;
slouken@2901
    68
    default:
slouken@2901
    69
        DRAW_SETPIXELXY_RGB565(x, y);
slouken@2901
    70
        break;
slouken@2901
    71
    }
slouken@2901
    72
    return 0;
slouken@2901
    73
}
slouken@2901
    74
slouken@2901
    75
static int
slouken@4929
    76
SDL_BlendPoint_RGB888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
    77
                      Uint8 g, Uint8 b, Uint8 a)
slouken@2901
    78
{
slouken@2901
    79
    unsigned inva = 0xff - a;
slouken@2901
    80
slouken@2901
    81
    switch (blendMode) {
slouken@2901
    82
    case SDL_BLENDMODE_BLEND:
slouken@2901
    83
        DRAW_SETPIXELXY_BLEND_RGB888(x, y);
slouken@2901
    84
        break;
slouken@2901
    85
    case SDL_BLENDMODE_ADD:
slouken@2901
    86
        DRAW_SETPIXELXY_ADD_RGB888(x, y);
slouken@2901
    87
        break;
slouken@5184
    88
    case SDL_BLENDMODE_MOD:
slouken@5184
    89
        DRAW_SETPIXELXY_MOD_RGB888(x, y);
slouken@5184
    90
        break;
slouken@2901
    91
    default:
slouken@2901
    92
        DRAW_SETPIXELXY_RGB888(x, y);
slouken@2901
    93
        break;
slouken@2901
    94
    }
slouken@2901
    95
    return 0;
slouken@2901
    96
}
slouken@2901
    97
slouken@2901
    98
static int
slouken@4929
    99
SDL_BlendPoint_ARGB8888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode,
slouken@2901
   100
                        Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2901
   101
{
slouken@2901
   102
    unsigned inva = 0xff - a;
slouken@2901
   103
slouken@2901
   104
    switch (blendMode) {
slouken@2901
   105
    case SDL_BLENDMODE_BLEND:
slouken@2901
   106
        DRAW_SETPIXELXY_BLEND_ARGB8888(x, y);
slouken@2901
   107
        break;
slouken@2901
   108
    case SDL_BLENDMODE_ADD:
slouken@2901
   109
        DRAW_SETPIXELXY_ADD_ARGB8888(x, y);
slouken@2901
   110
        break;
slouken@5184
   111
    case SDL_BLENDMODE_MOD:
slouken@5184
   112
        DRAW_SETPIXELXY_MOD_ARGB8888(x, y);
slouken@5184
   113
        break;
slouken@2901
   114
    default:
slouken@2901
   115
        DRAW_SETPIXELXY_ARGB8888(x, y);
slouken@2901
   116
        break;
slouken@2901
   117
    }
slouken@2901
   118
    return 0;
slouken@2901
   119
}
slouken@2901
   120
slouken@2901
   121
static int
slouken@4929
   122
SDL_BlendPoint_RGB(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
   123
                   Uint8 g, Uint8 b, Uint8 a)
slouken@2901
   124
{
slouken@2901
   125
    SDL_PixelFormat *fmt = dst->format;
slouken@2901
   126
    unsigned inva = 0xff - a;
slouken@2901
   127
slouken@2901
   128
    switch (fmt->BytesPerPixel) {
slouken@2901
   129
    case 2:
slouken@2901
   130
        switch (blendMode) {
slouken@2901
   131
        case SDL_BLENDMODE_BLEND:
slouken@2901
   132
            DRAW_SETPIXELXY2_BLEND_RGB(x, y);
slouken@2901
   133
            break;
slouken@2901
   134
        case SDL_BLENDMODE_ADD:
slouken@2901
   135
            DRAW_SETPIXELXY2_ADD_RGB(x, y);
slouken@2901
   136
            break;
slouken@5184
   137
        case SDL_BLENDMODE_MOD:
slouken@5184
   138
            DRAW_SETPIXELXY2_MOD_RGB(x, y);
slouken@5184
   139
            break;
slouken@2901
   140
        default:
slouken@2901
   141
            DRAW_SETPIXELXY2_RGB(x, y);
slouken@2901
   142
            break;
slouken@2901
   143
        }
slouken@2901
   144
        return 0;
slouken@2901
   145
    case 4:
slouken@2901
   146
        switch (blendMode) {
slouken@2901
   147
        case SDL_BLENDMODE_BLEND:
slouken@2901
   148
            DRAW_SETPIXELXY4_BLEND_RGB(x, y);
slouken@2901
   149
            break;
slouken@2901
   150
        case SDL_BLENDMODE_ADD:
slouken@2901
   151
            DRAW_SETPIXELXY4_ADD_RGB(x, y);
slouken@2901
   152
            break;
slouken@5184
   153
        case SDL_BLENDMODE_MOD:
slouken@5184
   154
            DRAW_SETPIXELXY4_MOD_RGB(x, y);
slouken@5184
   155
            break;
slouken@2901
   156
        default:
slouken@2901
   157
            DRAW_SETPIXELXY4_RGB(x, y);
slouken@2901
   158
            break;
slouken@2901
   159
        }
slouken@2901
   160
        return 0;
slouken@2901
   161
    default:
icculus@7037
   162
        return SDL_Unsupported();
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:
icculus@7037
   191
        return SDL_Unsupported();
slouken@2901
   192
    }
slouken@2901
   193
}
slouken@2901
   194
slouken@2901
   195
int
slouken@4929
   196
SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
slouken@2901
   197
               Uint8 g, Uint8 b, Uint8 a)
slouken@2901
   198
{
slouken@3536
   199
    if (!dst) {
icculus@7037
   200
        return SDL_SetError("Passed NULL destination surface");
slouken@3536
   201
    }
slouken@2901
   202
slouken@2901
   203
    /* This function doesn't work on surfaces < 8 bpp */
slouken@2901
   204
    if (dst->format->BitsPerPixel < 8) {
icculus@7037
   205
        return SDL_SetError("SDL_BlendPoint(): Unsupported surface format");
slouken@2901
   206
    }
slouken@2901
   207
slouken@2901
   208
    /* Perform clipping */
slouken@2901
   209
    if (x < dst->clip_rect.x || y < dst->clip_rect.y ||
slouken@2901
   210
        x >= (dst->clip_rect.x + dst->clip_rect.w) ||
slouken@2901
   211
        y >= (dst->clip_rect.y + dst->clip_rect.h)) {
slouken@2901
   212
        return 0;
slouken@2901
   213
    }
slouken@2901
   214
slouken@3536
   215
    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
slouken@2901
   216
        r = DRAW_MUL(r, a);
slouken@2901
   217
        g = DRAW_MUL(g, a);
slouken@2901
   218
        b = DRAW_MUL(b, a);
slouken@2901
   219
    }
slouken@2901
   220
slouken@3536
   221
    switch (dst->format->BitsPerPixel) {
slouken@2901
   222
    case 15:
slouken@3536
   223
        switch (dst->format->Rmask) {
slouken@2901
   224
        case 0x7C00:
slouken@2901
   225
            return SDL_BlendPoint_RGB555(dst, x, y, blendMode, r, g, b, a);
slouken@2901
   226
        }
slouken@2901
   227
        break;
slouken@2901
   228
    case 16:
slouken@3536
   229
        switch (dst->format->Rmask) {
slouken@2901
   230
        case 0xF800:
slouken@2901
   231
            return SDL_BlendPoint_RGB565(dst, x, y, blendMode, r, g, b, a);
slouken@2901
   232
        }
slouken@2901
   233
        break;
slouken@2901
   234
    case 32:
slouken@3536
   235
        switch (dst->format->Rmask) {
slouken@2901
   236
        case 0x00FF0000:
slouken@3536
   237
            if (!dst->format->Amask) {
slouken@2901
   238
                return SDL_BlendPoint_RGB888(dst, x, y, blendMode, r, g, b,
slouken@2901
   239
                                             a);
slouken@2901
   240
            } else {
slouken@2901
   241
                return SDL_BlendPoint_ARGB8888(dst, x, y, blendMode, r, g, b,
slouken@2901
   242
                                               a);
slouken@2901
   243
            }
slouken@2901
   244
            break;
slouken@2901
   245
        }
slouken@3536
   246
        break;
slouken@2901
   247
    default:
slouken@2901
   248
        break;
slouken@2901
   249
    }
slouken@2901
   250
slouken@3536
   251
    if (!dst->format->Amask) {
slouken@2901
   252
        return SDL_BlendPoint_RGB(dst, x, y, blendMode, r, g, b, a);
slouken@2901
   253
    } else {
slouken@2901
   254
        return SDL_BlendPoint_RGBA(dst, x, y, blendMode, r, g, b, a);
slouken@2901
   255
    }
slouken@2901
   256
}
slouken@2901
   257
slouken@3536
   258
int
slouken@3536
   259
SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count,
slouken@4929
   260
                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@3536
   261
{
slouken@3536
   262
    int minx, miny;
slouken@3536
   263
    int maxx, maxy;
slouken@3536
   264
    int i;
slouken@3536
   265
    int x, y;
slouken@3536
   266
    int (*func)(SDL_Surface * dst, int x, int y,
slouken@4929
   267
                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
slouken@3536
   268
    int status = 0;
slouken@3536
   269
slouken@3536
   270
    if (!dst) {
icculus@7037
   271
        return SDL_SetError("Passed NULL destination surface");
slouken@3536
   272
    }
slouken@3536
   273
slouken@3536
   274
    /* This function doesn't work on surfaces < 8 bpp */
slouken@3536
   275
    if (dst->format->BitsPerPixel < 8) {
icculus@7037
   276
        return SDL_SetError("SDL_BlendPoints(): Unsupported surface format");
slouken@3536
   277
    }
slouken@3536
   278
slouken@3536
   279
    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
slouken@3536
   280
        r = DRAW_MUL(r, a);
slouken@3536
   281
        g = DRAW_MUL(g, a);
slouken@3536
   282
        b = DRAW_MUL(b, a);
slouken@3536
   283
    }
slouken@3536
   284
slouken@3536
   285
    /* FIXME: Does this function pointer slow things down significantly? */
slouken@3536
   286
    switch (dst->format->BitsPerPixel) {
slouken@3536
   287
    case 15:
slouken@3536
   288
        switch (dst->format->Rmask) {
slouken@3536
   289
        case 0x7C00:
slouken@3536
   290
            func = SDL_BlendPoint_RGB555;
slouken@3536
   291
            break;
slouken@3536
   292
        }
slouken@3536
   293
        break;
slouken@3536
   294
    case 16:
slouken@3536
   295
        switch (dst->format->Rmask) {
slouken@3536
   296
        case 0xF800:
slouken@3536
   297
            func = SDL_BlendPoint_RGB565;
slouken@3536
   298
            break;
slouken@3536
   299
        }
slouken@3536
   300
        break;
slouken@3536
   301
    case 32:
slouken@3536
   302
        switch (dst->format->Rmask) {
slouken@3536
   303
        case 0x00FF0000:
slouken@3536
   304
            if (!dst->format->Amask) {
slouken@3536
   305
                func = SDL_BlendPoint_RGB888;
slouken@3536
   306
            } else {
slouken@3536
   307
                func = SDL_BlendPoint_ARGB8888;
slouken@3536
   308
            }
slouken@3536
   309
            break;
slouken@3536
   310
        }
slouken@3536
   311
        break;
slouken@3536
   312
    default:
slouken@3536
   313
        break;
slouken@3536
   314
    }
slouken@3536
   315
slouken@3536
   316
    if (!func) {
slouken@3536
   317
        if (!dst->format->Amask) {
slouken@3536
   318
            func = SDL_BlendPoint_RGB;
slouken@3536
   319
        } else {
slouken@3536
   320
            func = SDL_BlendPoint_RGBA;
slouken@3536
   321
        }
slouken@3536
   322
    }
slouken@3536
   323
slouken@3536
   324
    minx = dst->clip_rect.x;
slouken@3536
   325
    maxx = dst->clip_rect.x + dst->clip_rect.w - 1;
slouken@3536
   326
    miny = dst->clip_rect.y;
slouken@3536
   327
    maxy = dst->clip_rect.y + dst->clip_rect.h - 1;
slouken@3536
   328
slouken@3536
   329
    for (i = 0; i < count; ++i) {
slouken@3536
   330
        x = points[i].x;
slouken@3536
   331
        y = points[i].y;
slouken@3536
   332
slouken@3536
   333
        if (x < minx || x > maxx || y < miny || y > maxy) {
slouken@3536
   334
            continue;
slouken@3536
   335
        }
slouken@3536
   336
        status = func(dst, x, y, blendMode, r, g, b, a);
slouken@3536
   337
    }
slouken@3536
   338
    return status;
slouken@3536
   339
}
slouken@3536
   340
slouken@5226
   341
#endif /* !SDL_RENDER_DISABLED */
slouken@5226
   342
slouken@2901
   343
/* vi: set ts=4 sw=4 expandtab: */