cscg22-gearboy

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

SDL_blit_1.c (12710B)


      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#include "SDL_video.h"
     24#include "SDL_blit.h"
     25#include "SDL_sysvideo.h"
     26#include "SDL_endian.h"
     27
     28/* Functions to blit from 8-bit surfaces to other surfaces */
     29
     30static void
     31Blit1to1(SDL_BlitInfo * info)
     32{
     33#ifndef USE_DUFFS_LOOP
     34    int c;
     35#endif
     36    int width, height;
     37    Uint8 *src, *map, *dst;
     38    int srcskip, dstskip;
     39
     40    /* Set up some basic variables */
     41    width = info->dst_w;
     42    height = info->dst_h;
     43    src = info->src;
     44    srcskip = info->src_skip;
     45    dst = info->dst;
     46    dstskip = info->dst_skip;
     47    map = info->table;
     48
     49    while (height--) {
     50#ifdef USE_DUFFS_LOOP
     51        /* *INDENT-OFF* */
     52		DUFFS_LOOP(
     53			{
     54			  *dst = map[*src];
     55			}
     56			dst++;
     57			src++;
     58		, width);
     59        /* *INDENT-ON* */
     60#else
     61        for (c = width; c; --c) {
     62            *dst = map[*src];
     63            dst++;
     64            src++;
     65        }
     66#endif
     67        src += srcskip;
     68        dst += dstskip;
     69    }
     70}
     71
     72/* This is now endian dependent */
     73#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN )
     74#define HI	1
     75#define LO	0
     76#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */
     77#define HI	0
     78#define LO	1
     79#endif
     80static void
     81Blit1to2(SDL_BlitInfo * info)
     82{
     83#ifndef USE_DUFFS_LOOP
     84    int c;
     85#endif
     86    int width, height;
     87    Uint8 *src, *dst;
     88    Uint16 *map;
     89    int srcskip, dstskip;
     90
     91    /* Set up some basic variables */
     92    width = info->dst_w;
     93    height = info->dst_h;
     94    src = info->src;
     95    srcskip = info->src_skip;
     96    dst = info->dst;
     97    dstskip = info->dst_skip;
     98    map = (Uint16 *) info->table;
     99
    100#ifdef USE_DUFFS_LOOP
    101    while (height--) {
    102		/* *INDENT-OFF* */
    103		DUFFS_LOOP(
    104		{
    105			*(Uint16 *)dst = map[*src++];
    106			dst += 2;
    107		},
    108		width);
    109		/* *INDENT-ON* */
    110        src += srcskip;
    111        dst += dstskip;
    112    }
    113#else
    114    /* Memory align at 4-byte boundary, if necessary */
    115    if ((long) dst & 0x03) {
    116        /* Don't do anything if width is 0 */
    117        if (width == 0) {
    118            return;
    119        }
    120        --width;
    121
    122        while (height--) {
    123            /* Perform copy alignment */
    124            *(Uint16 *) dst = map[*src++];
    125            dst += 2;
    126
    127            /* Copy in 4 pixel chunks */
    128            for (c = width / 4; c; --c) {
    129                *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
    130                src += 2;
    131                dst += 4;
    132                *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
    133                src += 2;
    134                dst += 4;
    135            }
    136            /* Get any leftovers */
    137            switch (width & 3) {
    138            case 3:
    139                *(Uint16 *) dst = map[*src++];
    140                dst += 2;
    141            case 2:
    142                *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
    143                src += 2;
    144                dst += 4;
    145                break;
    146            case 1:
    147                *(Uint16 *) dst = map[*src++];
    148                dst += 2;
    149                break;
    150            }
    151            src += srcskip;
    152            dst += dstskip;
    153        }
    154    } else {
    155        while (height--) {
    156            /* Copy in 4 pixel chunks */
    157            for (c = width / 4; c; --c) {
    158                *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
    159                src += 2;
    160                dst += 4;
    161                *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
    162                src += 2;
    163                dst += 4;
    164            }
    165            /* Get any leftovers */
    166            switch (width & 3) {
    167            case 3:
    168                *(Uint16 *) dst = map[*src++];
    169                dst += 2;
    170            case 2:
    171                *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]);
    172                src += 2;
    173                dst += 4;
    174                break;
    175            case 1:
    176                *(Uint16 *) dst = map[*src++];
    177                dst += 2;
    178                break;
    179            }
    180            src += srcskip;
    181            dst += dstskip;
    182        }
    183    }
    184#endif /* USE_DUFFS_LOOP */
    185}
    186
    187static void
    188Blit1to3(SDL_BlitInfo * info)
    189{
    190#ifndef USE_DUFFS_LOOP
    191    int c;
    192#endif
    193    int o;
    194    int width, height;
    195    Uint8 *src, *map, *dst;
    196    int srcskip, dstskip;
    197
    198    /* Set up some basic variables */
    199    width = info->dst_w;
    200    height = info->dst_h;
    201    src = info->src;
    202    srcskip = info->src_skip;
    203    dst = info->dst;
    204    dstskip = info->dst_skip;
    205    map = info->table;
    206
    207    while (height--) {
    208#ifdef USE_DUFFS_LOOP
    209		/* *INDENT-OFF* */
    210		DUFFS_LOOP(
    211			{
    212				o = *src * 4;
    213				dst[0] = map[o++];
    214				dst[1] = map[o++];
    215				dst[2] = map[o++];
    216			}
    217			src++;
    218			dst += 3;
    219		, width);
    220		/* *INDENT-ON* */
    221#else
    222        for (c = width; c; --c) {
    223            o = *src * 4;
    224            dst[0] = map[o++];
    225            dst[1] = map[o++];
    226            dst[2] = map[o++];
    227            src++;
    228            dst += 3;
    229        }
    230#endif /* USE_DUFFS_LOOP */
    231        src += srcskip;
    232        dst += dstskip;
    233    }
    234}
    235
    236static void
    237Blit1to4(SDL_BlitInfo * info)
    238{
    239#ifndef USE_DUFFS_LOOP
    240    int c;
    241#endif
    242    int width, height;
    243    Uint8 *src;
    244    Uint32 *map, *dst;
    245    int srcskip, dstskip;
    246
    247    /* Set up some basic variables */
    248    width = info->dst_w;
    249    height = info->dst_h;
    250    src = info->src;
    251    srcskip = info->src_skip;
    252    dst = (Uint32 *) info->dst;
    253    dstskip = info->dst_skip / 4;
    254    map = (Uint32 *) info->table;
    255
    256    while (height--) {
    257#ifdef USE_DUFFS_LOOP
    258		/* *INDENT-OFF* */
    259		DUFFS_LOOP(
    260			*dst++ = map[*src++];
    261		, width);
    262		/* *INDENT-ON* */
    263#else
    264        for (c = width / 4; c; --c) {
    265            *dst++ = map[*src++];
    266            *dst++ = map[*src++];
    267            *dst++ = map[*src++];
    268            *dst++ = map[*src++];
    269        }
    270        switch (width & 3) {
    271        case 3:
    272            *dst++ = map[*src++];
    273        case 2:
    274            *dst++ = map[*src++];
    275        case 1:
    276            *dst++ = map[*src++];
    277        }
    278#endif /* USE_DUFFS_LOOP */
    279        src += srcskip;
    280        dst += dstskip;
    281    }
    282}
    283
    284static void
    285Blit1to1Key(SDL_BlitInfo * info)
    286{
    287    int width = info->dst_w;
    288    int height = info->dst_h;
    289    Uint8 *src = info->src;
    290    int srcskip = info->src_skip;
    291    Uint8 *dst = info->dst;
    292    int dstskip = info->dst_skip;
    293    Uint8 *palmap = info->table;
    294    Uint32 ckey = info->colorkey;
    295
    296    if (palmap) {
    297        while (height--) {
    298			/* *INDENT-OFF* */
    299			DUFFS_LOOP(
    300			{
    301				if ( *src != ckey ) {
    302				  *dst = palmap[*src];
    303				}
    304				dst++;
    305				src++;
    306			},
    307			width);
    308			/* *INDENT-ON* */
    309            src += srcskip;
    310            dst += dstskip;
    311        }
    312    } else {
    313        while (height--) {
    314			/* *INDENT-OFF* */
    315			DUFFS_LOOP(
    316			{
    317				if ( *src != ckey ) {
    318				  *dst = *src;
    319				}
    320				dst++;
    321				src++;
    322			},
    323			width);
    324			/* *INDENT-ON* */
    325            src += srcskip;
    326            dst += dstskip;
    327        }
    328    }
    329}
    330
    331static void
    332Blit1to2Key(SDL_BlitInfo * info)
    333{
    334    int width = info->dst_w;
    335    int height = info->dst_h;
    336    Uint8 *src = info->src;
    337    int srcskip = info->src_skip;
    338    Uint16 *dstp = (Uint16 *) info->dst;
    339    int dstskip = info->dst_skip;
    340    Uint16 *palmap = (Uint16 *) info->table;
    341    Uint32 ckey = info->colorkey;
    342
    343    /* Set up some basic variables */
    344    dstskip /= 2;
    345
    346    while (height--) {
    347		/* *INDENT-OFF* */
    348		DUFFS_LOOP(
    349		{
    350			if ( *src != ckey ) {
    351				*dstp=palmap[*src];
    352			}
    353			src++;
    354			dstp++;
    355		},
    356		width);
    357		/* *INDENT-ON* */
    358        src += srcskip;
    359        dstp += dstskip;
    360    }
    361}
    362
    363static void
    364Blit1to3Key(SDL_BlitInfo * info)
    365{
    366    int width = info->dst_w;
    367    int height = info->dst_h;
    368    Uint8 *src = info->src;
    369    int srcskip = info->src_skip;
    370    Uint8 *dst = info->dst;
    371    int dstskip = info->dst_skip;
    372    Uint8 *palmap = info->table;
    373    Uint32 ckey = info->colorkey;
    374    int o;
    375
    376    while (height--) {
    377		/* *INDENT-OFF* */
    378		DUFFS_LOOP(
    379		{
    380			if ( *src != ckey ) {
    381				o = *src * 4;
    382				dst[0] = palmap[o++];
    383				dst[1] = palmap[o++];
    384				dst[2] = palmap[o++];
    385			}
    386			src++;
    387			dst += 3;
    388		},
    389		width);
    390		/* *INDENT-ON* */
    391        src += srcskip;
    392        dst += dstskip;
    393    }
    394}
    395
    396static void
    397Blit1to4Key(SDL_BlitInfo * info)
    398{
    399    int width = info->dst_w;
    400    int height = info->dst_h;
    401    Uint8 *src = info->src;
    402    int srcskip = info->src_skip;
    403    Uint32 *dstp = (Uint32 *) info->dst;
    404    int dstskip = info->dst_skip;
    405    Uint32 *palmap = (Uint32 *) info->table;
    406    Uint32 ckey = info->colorkey;
    407
    408    /* Set up some basic variables */
    409    dstskip /= 4;
    410
    411    while (height--) {
    412		/* *INDENT-OFF* */
    413		DUFFS_LOOP(
    414		{
    415			if ( *src != ckey ) {
    416				*dstp = palmap[*src];
    417			}
    418			src++;
    419			dstp++;
    420		},
    421		width);
    422		/* *INDENT-ON* */
    423        src += srcskip;
    424        dstp += dstskip;
    425    }
    426}
    427
    428static void
    429Blit1toNAlpha(SDL_BlitInfo * info)
    430{
    431    int width = info->dst_w;
    432    int height = info->dst_h;
    433    Uint8 *src = info->src;
    434    int srcskip = info->src_skip;
    435    Uint8 *dst = info->dst;
    436    int dstskip = info->dst_skip;
    437    SDL_PixelFormat *dstfmt = info->dst_fmt;
    438    const SDL_Color *srcpal = info->src_fmt->palette->colors;
    439    int dstbpp;
    440    Uint32 pixel;
    441    unsigned sR, sG, sB;
    442    unsigned dR, dG, dB, dA;
    443    const unsigned A = info->a;
    444
    445    /* Set up some basic variables */
    446    dstbpp = dstfmt->BytesPerPixel;
    447
    448    while (height--) {
    449        /* *INDENT-OFF* */
    450        DUFFS_LOOP4(
    451        {
    452            sR = srcpal[*src].r;
    453            sG = srcpal[*src].g;
    454            sB = srcpal[*src].b;
    455            DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
    456            ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
    457            ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
    458            src++;
    459            dst += dstbpp;
    460        },
    461        width);
    462        /* *INDENT-ON* */
    463        src += srcskip;
    464        dst += dstskip;
    465    }
    466}
    467
    468static void
    469Blit1toNAlphaKey(SDL_BlitInfo * info)
    470{
    471    int width = info->dst_w;
    472    int height = info->dst_h;
    473    Uint8 *src = info->src;
    474    int srcskip = info->src_skip;
    475    Uint8 *dst = info->dst;
    476    int dstskip = info->dst_skip;
    477    SDL_PixelFormat *dstfmt = info->dst_fmt;
    478    const SDL_Color *srcpal = info->src_fmt->palette->colors;
    479    Uint32 ckey = info->colorkey;
    480    int dstbpp;
    481    Uint32 pixel;
    482    unsigned sR, sG, sB;
    483    unsigned dR, dG, dB, dA;
    484    const unsigned A = info->a;
    485
    486    /* Set up some basic variables */
    487    dstbpp = dstfmt->BytesPerPixel;
    488
    489    while (height--) {
    490		/* *INDENT-OFF* */
    491		DUFFS_LOOP(
    492		{
    493			if ( *src != ckey ) {
    494				sR = srcpal[*src].r;
    495				sG = srcpal[*src].g;
    496				sB = srcpal[*src].b;
    497				DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA);
    498				ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA);
    499			  	ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
    500			}
    501			src++;
    502			dst += dstbpp;
    503		},
    504		width);
    505		/* *INDENT-ON* */
    506        src += srcskip;
    507        dst += dstskip;
    508    }
    509}
    510
    511static const SDL_BlitFunc one_blit[] = {
    512    (SDL_BlitFunc) NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4
    513};
    514
    515static const SDL_BlitFunc one_blitkey[] = {
    516    (SDL_BlitFunc) NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key
    517};
    518
    519SDL_BlitFunc
    520SDL_CalculateBlit1(SDL_Surface * surface)
    521{
    522    int which;
    523    SDL_PixelFormat *dstfmt;
    524
    525    dstfmt = surface->map->dst->format;
    526    if (dstfmt->BitsPerPixel < 8) {
    527        which = 0;
    528    } else {
    529        which = dstfmt->BytesPerPixel;
    530    }
    531    switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
    532    case 0:
    533        return one_blit[which];
    534
    535    case SDL_COPY_COLORKEY:
    536        return one_blitkey[which];
    537
    538    case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
    539        /* Supporting 8bpp->8bpp alpha is doable but requires lots of
    540           tables which consume space and takes time to precompute,
    541           so is better left to the user */
    542        return which >= 2 ? Blit1toNAlpha : (SDL_BlitFunc) NULL;
    543
    544    case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND:
    545        return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc) NULL;
    546    }
    547    return (SDL_BlitFunc) NULL;
    548}
    549
    550/* vi: set ts=4 sw=4 expandtab: */