cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_blendfillrect.c (9458B)


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