src/render/software/SDL_blendfillrect.c
author Alex Szpakowski <slime73@gmail.com>
Tue, 15 Jul 2014 02:01:43 -0300
branchiOS-improvements
changeset 9489 6cd0275146b3
parent 8149 681eb46b8ac4
child 9619 b94b6d0bff0f
permissions -rw-r--r--
iOS now respects SDL_HINT_ACCELEROMETER_AS_JOYSTICK.
slouken@5163
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@8149
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@5163
     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@5163
     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@5163
    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@5163
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@5163
    22
slouken@5226
    23
#if !SDL_RENDER_DISABLED
slouken@5226
    24
slouken@5163
    25
#include "SDL_draw.h"
slouken@5163
    26
#include "SDL_blendfillrect.h"
slouken@5163
    27
slouken@5163
    28
slouken@5163
    29
static int
slouken@5163
    30
SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
    31
                         SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
    32
{
slouken@5163
    33
    unsigned inva = 0xff - a;
slouken@5163
    34
slouken@5163
    35
    switch (blendMode) {
slouken@5163
    36
    case SDL_BLENDMODE_BLEND:
slouken@5163
    37
        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
slouken@5163
    38
        break;
slouken@5163
    39
    case SDL_BLENDMODE_ADD:
slouken@5163
    40
        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
slouken@5163
    41
        break;
slouken@5184
    42
    case SDL_BLENDMODE_MOD:
slouken@5184
    43
        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
slouken@5184
    44
        break;
slouken@5163
    45
    default:
slouken@5163
    46
        FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
slouken@5163
    47
        break;
slouken@5163
    48
    }
slouken@5163
    49
    return 0;
slouken@5163
    50
}
slouken@5163
    51
slouken@5163
    52
static int
slouken@5163
    53
SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
    54
                         SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
    55
{
slouken@5163
    56
    unsigned inva = 0xff - a;
slouken@5163
    57
slouken@5163
    58
    switch (blendMode) {
slouken@5163
    59
    case SDL_BLENDMODE_BLEND:
slouken@5163
    60
        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
slouken@5163
    61
        break;
slouken@5163
    62
    case SDL_BLENDMODE_ADD:
slouken@5163
    63
        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
slouken@5163
    64
        break;
slouken@5184
    65
    case SDL_BLENDMODE_MOD:
slouken@5184
    66
        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
slouken@5184
    67
        break;
slouken@5163
    68
    default:
slouken@5163
    69
        FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
slouken@5163
    70
        break;
slouken@5163
    71
    }
slouken@5163
    72
    return 0;
slouken@5163
    73
}
slouken@5163
    74
slouken@5163
    75
static int
slouken@5163
    76
SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
    77
                         SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
    78
{
slouken@5163
    79
    unsigned inva = 0xff - a;
slouken@5163
    80
slouken@5163
    81
    switch (blendMode) {
slouken@5163
    82
    case SDL_BLENDMODE_BLEND:
slouken@5163
    83
        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888);
slouken@5163
    84
        break;
slouken@5163
    85
    case SDL_BLENDMODE_ADD:
slouken@5163
    86
        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888);
slouken@5163
    87
        break;
slouken@5184
    88
    case SDL_BLENDMODE_MOD:
slouken@5184
    89
        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
slouken@5184
    90
        break;
slouken@5163
    91
    default:
slouken@5163
    92
        FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
slouken@5163
    93
        break;
slouken@5163
    94
    }
slouken@5163
    95
    return 0;
slouken@5163
    96
}
slouken@5163
    97
slouken@5163
    98
static int
slouken@5163
    99
SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   100
                           SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   101
{
slouken@5163
   102
    unsigned inva = 0xff - a;
slouken@5163
   103
slouken@5163
   104
    switch (blendMode) {
slouken@5163
   105
    case SDL_BLENDMODE_BLEND:
slouken@5163
   106
        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
slouken@5163
   107
        break;
slouken@5163
   108
    case SDL_BLENDMODE_ADD:
slouken@5163
   109
        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
slouken@5163
   110
        break;
slouken@5184
   111
    case SDL_BLENDMODE_MOD:
slouken@5184
   112
        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
slouken@5184
   113
        break;
slouken@5163
   114
    default:
slouken@5163
   115
        FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
slouken@5163
   116
        break;
slouken@5163
   117
    }
slouken@5163
   118
    return 0;
slouken@5163
   119
}
slouken@5163
   120
slouken@5163
   121
static int
slouken@5163
   122
SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   123
                      SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   124
{
slouken@5163
   125
    SDL_PixelFormat *fmt = dst->format;
slouken@5163
   126
    unsigned inva = 0xff - a;
slouken@5163
   127
slouken@5163
   128
    switch (fmt->BytesPerPixel) {
slouken@5163
   129
    case 2:
slouken@5163
   130
        switch (blendMode) {
slouken@5163
   131
        case SDL_BLENDMODE_BLEND:
slouken@5163
   132
            FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
slouken@5163
   133
            break;
slouken@5163
   134
        case SDL_BLENDMODE_ADD:
slouken@5163
   135
            FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
slouken@5163
   136
            break;
slouken@5184
   137
        case SDL_BLENDMODE_MOD:
slouken@5184
   138
            FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
slouken@5184
   139
            break;
slouken@5163
   140
        default:
slouken@5163
   141
            FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
slouken@5163
   142
            break;
slouken@5163
   143
        }
slouken@5163
   144
        return 0;
slouken@5163
   145
    case 4:
slouken@5163
   146
        switch (blendMode) {
slouken@5163
   147
        case SDL_BLENDMODE_BLEND:
slouken@5163
   148
            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
slouken@5163
   149
            break;
slouken@5163
   150
        case SDL_BLENDMODE_ADD:
slouken@5163
   151
            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
slouken@5163
   152
            break;
slouken@5184
   153
        case SDL_BLENDMODE_MOD:
slouken@5184
   154
            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
slouken@5184
   155
            break;
slouken@5163
   156
        default:
slouken@5163
   157
            FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
slouken@5163
   158
            break;
slouken@5163
   159
        }
slouken@5163
   160
        return 0;
slouken@5163
   161
    default:
icculus@7037
   162
        return SDL_Unsupported();
slouken@5163
   163
    }
slouken@5163
   164
}
slouken@5163
   165
slouken@5163
   166
static int
slouken@5163
   167
SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   168
                       SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   169
{
slouken@5163
   170
    SDL_PixelFormat *fmt = dst->format;
slouken@5163
   171
    unsigned inva = 0xff - a;
slouken@5163
   172
slouken@5163
   173
    switch (fmt->BytesPerPixel) {
slouken@5163
   174
    case 4:
slouken@5163
   175
        switch (blendMode) {
slouken@5163
   176
        case SDL_BLENDMODE_BLEND:
slouken@5163
   177
            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
slouken@5163
   178
            break;
slouken@5163
   179
        case SDL_BLENDMODE_ADD:
slouken@5163
   180
            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
slouken@5163
   181
            break;
slouken@5184
   182
        case SDL_BLENDMODE_MOD:
slouken@5184
   183
            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
slouken@5184
   184
            break;
slouken@5163
   185
        default:
slouken@5163
   186
            FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
slouken@5163
   187
            break;
slouken@5163
   188
        }
slouken@5163
   189
        return 0;
slouken@5163
   190
    default:
icculus@7037
   191
        return SDL_Unsupported();
slouken@5163
   192
    }
slouken@5163
   193
}
slouken@5163
   194
slouken@5163
   195
int
slouken@5163
   196
SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   197
                  SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   198
{
slouken@5163
   199
    SDL_Rect clipped;
slouken@5163
   200
slouken@5163
   201
    if (!dst) {
icculus@7037
   202
        return SDL_SetError("Passed NULL destination surface");
slouken@5163
   203
    }
slouken@5163
   204
slouken@5163
   205
    /* This function doesn't work on surfaces < 8 bpp */
slouken@5163
   206
    if (dst->format->BitsPerPixel < 8) {
icculus@7037
   207
        return SDL_SetError("SDL_BlendFillRect(): Unsupported surface format");
slouken@5163
   208
    }
slouken@5163
   209
slouken@5163
   210
    /* If 'rect' == NULL, then fill the whole surface */
slouken@5163
   211
    if (rect) {
slouken@5163
   212
        /* Perform clipping */
slouken@5163
   213
        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
slouken@5163
   214
            return 0;
slouken@5163
   215
        }
slouken@5163
   216
        rect = &clipped;
slouken@5163
   217
    } else {
slouken@5163
   218
        rect = &dst->clip_rect;
slouken@5163
   219
    }
slouken@5163
   220
slouken@5163
   221
    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
slouken@5163
   222
        r = DRAW_MUL(r, a);
slouken@5163
   223
        g = DRAW_MUL(g, a);
slouken@5163
   224
        b = DRAW_MUL(b, a);
slouken@5163
   225
    }
slouken@5163
   226
slouken@5163
   227
    switch (dst->format->BitsPerPixel) {
slouken@5163
   228
    case 15:
slouken@5163
   229
        switch (dst->format->Rmask) {
slouken@5163
   230
        case 0x7C00:
slouken@5163
   231
            return SDL_BlendFillRect_RGB555(dst, rect, blendMode, r, g, b, a);
slouken@5163
   232
        }
slouken@5163
   233
        break;
slouken@5163
   234
    case 16:
slouken@5163
   235
        switch (dst->format->Rmask) {
slouken@5163
   236
        case 0xF800:
slouken@5163
   237
            return SDL_BlendFillRect_RGB565(dst, rect, blendMode, r, g, b, a);
slouken@5163
   238
        }
slouken@5163
   239
        break;
slouken@5163
   240
    case 32:
slouken@5163
   241
        switch (dst->format->Rmask) {
slouken@5163
   242
        case 0x00FF0000:
slouken@5163
   243
            if (!dst->format->Amask) {
slouken@5163
   244
                return SDL_BlendFillRect_RGB888(dst, rect, blendMode, r, g, b, a);
slouken@5163
   245
            } else {
slouken@5163
   246
                return SDL_BlendFillRect_ARGB8888(dst, rect, blendMode, r, g, b, a);
slouken@5163
   247
            }
slouken@5163
   248
            break;
slouken@5163
   249
        }
slouken@5163
   250
        break;
slouken@5163
   251
    default:
slouken@5163
   252
        break;
slouken@5163
   253
    }
slouken@5163
   254
slouken@5163
   255
    if (!dst->format->Amask) {
slouken@5163
   256
        return SDL_BlendFillRect_RGB(dst, rect, blendMode, r, g, b, a);
slouken@5163
   257
    } else {
slouken@5163
   258
        return SDL_BlendFillRect_RGBA(dst, rect, blendMode, r, g, b, a);
slouken@5163
   259
    }
slouken@5163
   260
}
slouken@5163
   261
slouken@5163
   262
int
slouken@5297
   263
SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
slouken@5163
   264
                   SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   265
{
slouken@5297
   266
    SDL_Rect rect;
slouken@5163
   267
    int i;
slouken@5163
   268
    int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   269
                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
slouken@5163
   270
    int status = 0;
slouken@5163
   271
slouken@5163
   272
    if (!dst) {
icculus@7037
   273
        return SDL_SetError("Passed NULL destination surface");
slouken@5163
   274
    }
slouken@5163
   275
slouken@5163
   276
    /* This function doesn't work on surfaces < 8 bpp */
slouken@5163
   277
    if (dst->format->BitsPerPixel < 8) {
icculus@7037
   278
        return SDL_SetError("SDL_BlendFillRects(): Unsupported surface format");
slouken@5163
   279
    }
slouken@5163
   280
slouken@5163
   281
    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
slouken@5163
   282
        r = DRAW_MUL(r, a);
slouken@5163
   283
        g = DRAW_MUL(g, a);
slouken@5163
   284
        b = DRAW_MUL(b, a);
slouken@5163
   285
    }
slouken@5163
   286
slouken@5163
   287
    /* FIXME: Does this function pointer slow things down significantly? */
slouken@5163
   288
    switch (dst->format->BitsPerPixel) {
slouken@5163
   289
    case 15:
slouken@5163
   290
        switch (dst->format->Rmask) {
slouken@5163
   291
        case 0x7C00:
slouken@5163
   292
            func = SDL_BlendFillRect_RGB555;
slouken@5163
   293
        }
slouken@5163
   294
        break;
slouken@5163
   295
    case 16:
slouken@5163
   296
        switch (dst->format->Rmask) {
slouken@5163
   297
        case 0xF800:
slouken@5163
   298
            func = SDL_BlendFillRect_RGB565;
slouken@5163
   299
        }
slouken@5163
   300
        break;
slouken@5163
   301
    case 32:
slouken@5163
   302
        switch (dst->format->Rmask) {
slouken@5163
   303
        case 0x00FF0000:
slouken@5163
   304
            if (!dst->format->Amask) {
slouken@5163
   305
                func = SDL_BlendFillRect_RGB888;
slouken@5163
   306
            } else {
slouken@5163
   307
                func = SDL_BlendFillRect_ARGB8888;
slouken@5163
   308
            }
slouken@5163
   309
            break;
slouken@5163
   310
        }
slouken@5163
   311
        break;
slouken@5163
   312
    default:
slouken@5163
   313
        break;
slouken@5163
   314
    }
slouken@5163
   315
slouken@5163
   316
    if (!func) {
slouken@5163
   317
        if (!dst->format->Amask) {
slouken@5163
   318
            func = SDL_BlendFillRect_RGB;
slouken@5163
   319
        } else {
slouken@5163
   320
            func = SDL_BlendFillRect_RGBA;
slouken@5163
   321
        }
slouken@5163
   322
    }
slouken@5163
   323
slouken@5163
   324
    for (i = 0; i < count; ++i) {
slouken@5297
   325
        /* Perform clipping */
slouken@5297
   326
        if (!SDL_IntersectRect(&rects[i], &dst->clip_rect, &rect)) {
slouken@5297
   327
            continue;
slouken@5163
   328
        }
slouken@5297
   329
        status = func(dst, &rect, blendMode, r, g, b, a);
slouken@5163
   330
    }
slouken@5163
   331
    return status;
slouken@5163
   332
}
slouken@5163
   333
slouken@5226
   334
#endif /* !SDL_RENDER_DISABLED */
slouken@5226
   335
slouken@5163
   336
/* vi: set ts=4 sw=4 expandtab: */