cscg22-gearboy

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

SDL_blendpoint.c (9278B)


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