cscg22-gearboy

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

testoverlay2.c (14066B)


      1/*
      2  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      3
      4  This software is provided 'as-is', without any express or implied
      5  warranty.  In no event will the authors be held liable for any damages
      6  arising from the use of this software.
      7
      8  Permission is granted to anyone to use this software for any purpose,
      9  including commercial applications, and to alter it and redistribute it
     10  freely.
     11*/
     12/********************************************************************************
     13 *                                                                              *
     14 * Test of the overlay used for moved pictures, test more closed to real life.  *
     15 * Running trojan moose :) Coded by Mike Gorchak.                               *
     16 *                                                                              *
     17 ********************************************************************************/
     18
     19#include <stdlib.h>
     20#include <stdio.h>
     21#include <string.h>
     22
     23#include "SDL.h"
     24
     25#define MOOSEPIC_W 64
     26#define MOOSEPIC_H 88
     27
     28#define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H)
     29#define MOOSEFRAMES_COUNT 10
     30
     31SDL_Color MooseColors[84] = {
     32    {49, 49, 49}
     33    , {66, 24, 0}
     34    , {66, 33, 0}
     35    , {66, 66, 66}
     36    ,
     37    {66, 115, 49}
     38    , {74, 33, 0}
     39    , {74, 41, 16}
     40    , {82, 33, 8}
     41    ,
     42    {82, 41, 8}
     43    , {82, 49, 16}
     44    , {82, 82, 82}
     45    , {90, 41, 8}
     46    ,
     47    {90, 41, 16}
     48    , {90, 57, 24}
     49    , {99, 49, 16}
     50    , {99, 66, 24}
     51    ,
     52    {99, 66, 33}
     53    , {99, 74, 33}
     54    , {107, 57, 24}
     55    , {107, 82, 41}
     56    ,
     57    {115, 57, 33}
     58    , {115, 66, 33}
     59    , {115, 66, 41}
     60    , {115, 74, 0}
     61    ,
     62    {115, 90, 49}
     63    , {115, 115, 115}
     64    , {123, 82, 0}
     65    , {123, 99, 57}
     66    ,
     67    {132, 66, 41}
     68    , {132, 74, 41}
     69    , {132, 90, 8}
     70    , {132, 99, 33}
     71    ,
     72    {132, 99, 66}
     73    , {132, 107, 66}
     74    , {140, 74, 49}
     75    , {140, 99, 16}
     76    ,
     77    {140, 107, 74}
     78    , {140, 115, 74}
     79    , {148, 107, 24}
     80    , {148, 115, 82}
     81    ,
     82    {148, 123, 74}
     83    , {148, 123, 90}
     84    , {156, 115, 33}
     85    , {156, 115, 90}
     86    ,
     87    {156, 123, 82}
     88    , {156, 132, 82}
     89    , {156, 132, 99}
     90    , {156, 156, 156}
     91    ,
     92    {165, 123, 49}
     93    , {165, 123, 90}
     94    , {165, 132, 82}
     95    , {165, 132, 90}
     96    ,
     97    {165, 132, 99}
     98    , {165, 140, 90}
     99    , {173, 132, 57}
    100    , {173, 132, 99}
    101    ,
    102    {173, 140, 107}
    103    , {173, 140, 115}
    104    , {173, 148, 99}
    105    , {173, 173, 173}
    106    ,
    107    {181, 140, 74}
    108    , {181, 148, 115}
    109    , {181, 148, 123}
    110    , {181, 156, 107}
    111    ,
    112    {189, 148, 123}
    113    , {189, 156, 82}
    114    , {189, 156, 123}
    115    , {189, 156, 132}
    116    ,
    117    {189, 189, 189}
    118    , {198, 156, 123}
    119    , {198, 165, 132}
    120    , {206, 165, 99}
    121    ,
    122    {206, 165, 132}
    123    , {206, 173, 140}
    124    , {206, 206, 206}
    125    , {214, 173, 115}
    126    ,
    127    {214, 173, 140}
    128    , {222, 181, 148}
    129    , {222, 189, 132}
    130    , {222, 189, 156}
    131    ,
    132    {222, 222, 222}
    133    , {231, 198, 165}
    134    , {231, 231, 231}
    135    , {239, 206, 173}
    136};
    137
    138
    139/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    140static void
    141quit(int rc)
    142{
    143    SDL_Quit();
    144    exit(rc);
    145}
    146
    147/* All RGB2YUV conversion code and some other parts of code has been taken from testoverlay.c */
    148
    149/* NOTE: These RGB conversion functions are not intended for speed,
    150         only as examples.
    151*/
    152
    153void
    154RGBtoYUV(Uint8 * rgb, int *yuv, int monochrome, int luminance)
    155{
    156    if (monochrome) {
    157#if 1                           /* these are the two formulas that I found on the FourCC site... */
    158        yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
    159        yuv[1] = 128;
    160        yuv[2] = 128;
    161#else
    162        yuv[0] = (int)(0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
    163        yuv[1] = 128;
    164        yuv[2] = 128;
    165#endif
    166    } else {
    167#if 1                           /* these are the two formulas that I found on the FourCC site... */
    168        yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
    169        yuv[1] = (int)((rgb[2] - yuv[0]) * 0.565 + 128);
    170        yuv[2] = (int)((rgb[0] - yuv[0]) * 0.713 + 128);
    171#else
    172        yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
    173        yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]);
    174        yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
    175#endif
    176    }
    177
    178    if (luminance != 100) {
    179        yuv[0] = yuv[0] * luminance / 100;
    180        if (yuv[0] > 255)
    181            yuv[0] = 255;
    182    }
    183}
    184
    185void
    186ConvertRGBtoYV12(Uint8 *rgb, Uint8 *out, int w, int h,
    187                 int monochrome, int luminance)
    188{
    189    int x, y;
    190    int yuv[3];
    191    Uint8 *op[3];
    192
    193    op[0] = out;
    194    op[1] = op[0] + w*h;
    195    op[2] = op[1] + w*h/4;
    196    for (y = 0; y < h; ++y) {
    197        for (x = 0; x < w; ++x) {
    198            RGBtoYUV(rgb, yuv, monochrome, luminance);
    199            *(op[0]++) = yuv[0];
    200            if (x % 2 == 0 && y % 2 == 0) {
    201                *(op[1]++) = yuv[2];
    202                *(op[2]++) = yuv[1];
    203            }
    204            rgb += 3;
    205        }
    206    }
    207}
    208
    209void
    210ConvertRGBtoNV12(Uint8 *rgb, Uint8 *out, int w, int h,
    211                 int monochrome, int luminance)
    212{
    213    int x, y;
    214    int yuv[3];
    215    Uint8 *op[2];
    216
    217    op[0] = out;
    218    op[1] = op[0] + w*h;
    219    for (y = 0; y < h; ++y) {
    220        for (x = 0; x < w; ++x) {
    221            RGBtoYUV(rgb, yuv, monochrome, luminance);
    222            *(op[0]++) = yuv[0];
    223            if (x % 2 == 0 && y % 2 == 0) {
    224                *(op[1]++) = yuv[1];
    225                *(op[1]++) = yuv[2];
    226            }
    227            rgb += 3;
    228        }
    229    }
    230}
    231
    232static void
    233PrintUsage(char *argv0)
    234{
    235    SDL_Log("Usage: %s [arg] [arg] [arg] ...\n", argv0);
    236    SDL_Log("\n");
    237    SDL_Log("Where 'arg' is any of the following options:\n");
    238    SDL_Log("\n");
    239    SDL_Log("    -fps <frames per second>\n");
    240    SDL_Log("    -nodelay\n");
    241    SDL_Log("    -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n");
    242    SDL_Log("    -scale <scale factor> (initial scale of the overlay)\n");
    243    SDL_Log("    -help (shows this help)\n");
    244    SDL_Log("\n");
    245    SDL_Log("Press ESC to exit, or SPACE to freeze the movie while application running.\n");
    246    SDL_Log("\n");
    247}
    248
    249int
    250main(int argc, char **argv)
    251{
    252    Uint8 *RawMooseData;
    253    SDL_RWops *handle;
    254    int window_w;
    255    int window_h;
    256    SDL_Window *window;
    257    SDL_Renderer *renderer;
    258    Uint8 MooseFrame[MOOSEFRAMES_COUNT][MOOSEFRAME_SIZE*2];
    259    SDL_Texture *MooseTexture;
    260    SDL_Rect displayrect;
    261    SDL_Event event;
    262    int paused = 0;
    263    int i, j;
    264    int fps = 12;
    265    int fpsdelay;
    266    int nodelay = 0;
    267#ifdef TEST_NV12
    268    Uint32 pixel_format = SDL_PIXELFORMAT_NV12;
    269#else
    270    Uint32 pixel_format = SDL_PIXELFORMAT_YV12;
    271#endif
    272    int scale = 5;
    273    SDL_bool done = SDL_FALSE;
    274
    275    /* Enable standard application logging */
    276    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    277
    278    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    279        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
    280        return 3;
    281    }
    282
    283    while (argc > 1) {
    284        if (strcmp(argv[1], "-fps") == 0) {
    285            if (argv[2]) {
    286                fps = atoi(argv[2]);
    287                if (fps == 0) {
    288                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    289                            "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
    290                    quit(10);
    291                }
    292                if ((fps < 0) || (fps > 1000)) {
    293                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    294                            "The -fps option must be in range from 1 to 1000, default is 12.\n");
    295                    quit(10);
    296                }
    297                argv += 2;
    298                argc -= 2;
    299            } else {
    300                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    301                        "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
    302                quit(10);
    303            }
    304        } else if (strcmp(argv[1], "-nodelay") == 0) {
    305            nodelay = 1;
    306            argv += 1;
    307            argc -= 1;
    308        } else if (strcmp(argv[1], "-scale") == 0) {
    309            if (argv[2]) {
    310                scale = atoi(argv[2]);
    311                if (scale == 0) {
    312                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    313                            "The -scale option requires an argument [from 1 to 50], default is 5.\n");
    314                    quit(10);
    315                }
    316                if ((scale < 0) || (scale > 50)) {
    317                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    318                            "The -scale option must be in range from 1 to 50, default is 5.\n");
    319                    quit(10);
    320                }
    321                argv += 2;
    322                argc -= 2;
    323            } else {
    324                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    325                        "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
    326                quit(10);
    327            }
    328        } else if ((strcmp(argv[1], "-help") == 0)
    329                   || (strcmp(argv[1], "-h") == 0)) {
    330            PrintUsage(argv[0]);
    331            quit(0);
    332        } else {
    333            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unrecognized option: %s.\n", argv[1]);
    334            quit(10);
    335        }
    336        break;
    337    }
    338
    339    RawMooseData = (Uint8 *) malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT);
    340    if (RawMooseData == NULL) {
    341        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't allocate memory for movie !\n");
    342        free(RawMooseData);
    343        quit(1);
    344    }
    345
    346    /* load the trojan moose images */
    347    handle = SDL_RWFromFile("moose.dat", "rb");
    348    if (handle == NULL) {
    349        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n");
    350        free(RawMooseData);
    351        quit(2);
    352    }
    353
    354    SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT);
    355
    356    SDL_RWclose(handle);
    357
    358    /* Create the window and renderer */
    359    window_w = MOOSEPIC_W * scale;
    360    window_h = MOOSEPIC_H * scale;
    361    window = SDL_CreateWindow("Happy Moose",
    362                              SDL_WINDOWPOS_UNDEFINED,
    363                              SDL_WINDOWPOS_UNDEFINED,
    364                              window_w, window_h,
    365                              SDL_WINDOW_RESIZABLE);
    366    if (!window) {
    367        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create window: %s\n", SDL_GetError());
    368        free(RawMooseData);
    369        quit(4);
    370    }
    371
    372    renderer = SDL_CreateRenderer(window, -1, 0);
    373    if (!renderer) {
    374        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create renderer: %s\n", SDL_GetError());
    375        free(RawMooseData);
    376        quit(4);
    377    }
    378
    379    MooseTexture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
    380    if (!MooseTexture) {
    381        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError());
    382        free(RawMooseData);
    383        quit(5);
    384    }
    385    /* Uncomment this to check vertex color with a YUV texture */
    386    /* SDL_SetTextureColorMod(MooseTexture, 0xff, 0x80, 0x80); */
    387
    388    for (i = 0; i < MOOSEFRAMES_COUNT; i++) {
    389        Uint8 MooseFrameRGB[MOOSEFRAME_SIZE*3];
    390        Uint8 *rgb;
    391        Uint8 *frame;
    392
    393        rgb = MooseFrameRGB;
    394        frame = RawMooseData + i * MOOSEFRAME_SIZE;
    395        for (j = 0; j < MOOSEFRAME_SIZE; ++j) {
    396            rgb[0] = MooseColors[frame[j]].r;
    397            rgb[1] = MooseColors[frame[j]].g;
    398            rgb[2] = MooseColors[frame[j]].b;
    399            rgb += 3;
    400        }
    401        switch (pixel_format) {
    402        case SDL_PIXELFORMAT_YV12:
    403            ConvertRGBtoYV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100);
    404            break;
    405        case SDL_PIXELFORMAT_NV12:
    406            ConvertRGBtoNV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100);
    407            break;
    408        default:
    409            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unsupported pixel format\n");
    410            break;
    411        }
    412    }
    413
    414    free(RawMooseData);
    415
    416    /* set the start frame */
    417    i = 0;
    418    if (nodelay) {
    419        fpsdelay = 0;
    420    } else {
    421        fpsdelay = 1000 / fps;
    422    }
    423
    424    displayrect.x = 0;
    425    displayrect.y = 0;
    426    displayrect.w = window_w;
    427    displayrect.h = window_h;
    428
    429    /* Ignore key up events, they don't even get filtered */
    430    SDL_EventState(SDL_KEYUP, SDL_IGNORE);
    431
    432    /* Loop, waiting for QUIT or RESIZE */
    433    while (!done) {
    434        while (SDL_PollEvent(&event)) {
    435            switch (event.type) {
    436            case SDL_WINDOWEVENT:
    437                if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
    438                    SDL_RenderSetViewport(renderer, NULL);
    439                    displayrect.w = window_w = event.window.data1;
    440                    displayrect.h = window_h = event.window.data2;
    441                }
    442                break;
    443            case SDL_MOUSEBUTTONDOWN:
    444                displayrect.x = event.button.x - window_w / 2;
    445                displayrect.y = event.button.y - window_h / 2;
    446                break;
    447            case SDL_MOUSEMOTION:
    448                if (event.motion.state) {
    449                    displayrect.x = event.motion.x - window_w / 2;
    450                    displayrect.y = event.motion.y - window_h / 2;
    451                }
    452                break;
    453            case SDL_KEYDOWN:
    454                if (event.key.keysym.sym == SDLK_SPACE) {
    455                    paused = !paused;
    456                    break;
    457                }
    458                if (event.key.keysym.sym != SDLK_ESCAPE) {
    459                    break;
    460                }
    461            case SDL_QUIT:
    462                done = SDL_TRUE;
    463                break;
    464            }
    465        }
    466        SDL_Delay(fpsdelay);
    467
    468        if (!paused) {
    469            i = (i + 1) % MOOSEFRAMES_COUNT;
    470
    471            SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*SDL_BYTESPERPIXEL(pixel_format));
    472        }
    473        SDL_RenderClear(renderer);
    474        SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect);
    475        SDL_RenderPresent(renderer);
    476    }
    477    SDL_DestroyRenderer(renderer);
    478    quit(0);
    479    return 0;
    480}
    481
    482/* vi: set ts=4 sw=4 expandtab: */