Home | History | Annotate | Download | only in test
      1 /*
      2   Copyright (C) 1997-2014 Sam Lantinga <slouken (at) 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 
     31 SDL_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. */
    140 static void
    141 quit(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 
    153 void
    154 RGBtoYUV(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 
    185 void
    186 ConvertRGBtoYV12(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 
    209 static void
    210 PrintUsage(char *argv0)
    211 {
    212     SDL_Log("Usage: %s [arg] [arg] [arg] ...\n", argv0);
    213     SDL_Log("\n");
    214     SDL_Log("Where 'arg' is any of the following options:\n");
    215     SDL_Log("\n");
    216     SDL_Log("    -fps <frames per second>\n");
    217     SDL_Log("    -nodelay\n");
    218     SDL_Log("    -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n");
    219     SDL_Log("    -scale <scale factor> (initial scale of the overlay)\n");
    220     SDL_Log("    -help (shows this help)\n");
    221     SDL_Log("\n");
    222     SDL_Log("Press ESC to exit, or SPACE to freeze the movie while application running.\n");
    223     SDL_Log("\n");
    224 }
    225 
    226 int
    227 main(int argc, char **argv)
    228 {
    229     Uint8 *RawMooseData;
    230     SDL_RWops *handle;
    231     int window_w;
    232     int window_h;
    233     SDL_Window *window;
    234     SDL_Renderer *renderer;
    235     Uint8 MooseFrame[MOOSEFRAMES_COUNT][MOOSEFRAME_SIZE*2];
    236     SDL_Texture *MooseTexture;
    237     SDL_Rect displayrect;
    238     SDL_Event event;
    239     int paused = 0;
    240     int i, j;
    241     int fps = 12;
    242     int fpsdelay;
    243     int nodelay = 0;
    244     Uint32 pixel_format = SDL_PIXELFORMAT_YV12;
    245     int scale = 5;
    246     SDL_bool done = SDL_FALSE;
    247 
    248     /* Enable standard application logging */
    249     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    250 
    251     if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    252         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
    253         return 3;
    254     }
    255 
    256     while (argc > 1) {
    257         if (strcmp(argv[1], "-fps") == 0) {
    258             if (argv[2]) {
    259                 fps = atoi(argv[2]);
    260                 if (fps == 0) {
    261                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    262                             "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
    263                     quit(10);
    264                 }
    265                 if ((fps < 0) || (fps > 1000)) {
    266                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    267                             "The -fps option must be in range from 1 to 1000, default is 12.\n");
    268                     quit(10);
    269                 }
    270                 argv += 2;
    271                 argc -= 2;
    272             } else {
    273                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    274                         "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
    275                 quit(10);
    276             }
    277         } else if (strcmp(argv[1], "-nodelay") == 0) {
    278             nodelay = 1;
    279             argv += 1;
    280             argc -= 1;
    281         } else if (strcmp(argv[1], "-scale") == 0) {
    282             if (argv[2]) {
    283                 scale = atoi(argv[2]);
    284                 if (scale == 0) {
    285                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    286                             "The -scale option requires an argument [from 1 to 50], default is 5.\n");
    287                     quit(10);
    288                 }
    289                 if ((scale < 0) || (scale > 50)) {
    290                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    291                             "The -scale option must be in range from 1 to 50, default is 5.\n");
    292                     quit(10);
    293                 }
    294                 argv += 2;
    295                 argc -= 2;
    296             } else {
    297                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
    298                         "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
    299                 quit(10);
    300             }
    301         } else if ((strcmp(argv[1], "-help") == 0)
    302                    || (strcmp(argv[1], "-h") == 0)) {
    303             PrintUsage(argv[0]);
    304             quit(0);
    305         } else {
    306             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unrecognized option: %s.\n", argv[1]);
    307             quit(10);
    308         }
    309         break;
    310     }
    311 
    312     RawMooseData = (Uint8 *) malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT);
    313     if (RawMooseData == NULL) {
    314         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't allocate memory for movie !\n");
    315         free(RawMooseData);
    316         quit(1);
    317     }
    318 
    319     /* load the trojan moose images */
    320     handle = SDL_RWFromFile("moose.dat", "rb");
    321     if (handle == NULL) {
    322         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n");
    323         free(RawMooseData);
    324         quit(2);
    325     }
    326 
    327     SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT);
    328 
    329     SDL_RWclose(handle);
    330 
    331     /* Create the window and renderer */
    332     window_w = MOOSEPIC_W * scale;
    333     window_h = MOOSEPIC_H * scale;
    334     window = SDL_CreateWindow("Happy Moose",
    335                               SDL_WINDOWPOS_UNDEFINED,
    336                               SDL_WINDOWPOS_UNDEFINED,
    337                               window_w, window_h,
    338                               SDL_WINDOW_RESIZABLE);
    339     if (!window) {
    340         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create window: %s\n", SDL_GetError());
    341         free(RawMooseData);
    342         quit(4);
    343     }
    344 
    345     renderer = SDL_CreateRenderer(window, -1, 0);
    346     if (!renderer) {
    347         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create renderer: %s\n", SDL_GetError());
    348         free(RawMooseData);
    349         quit(4);
    350     }
    351 
    352     MooseTexture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
    353     if (!MooseTexture) {
    354         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError());
    355         free(RawMooseData);
    356         quit(5);
    357     }
    358     /* Uncomment this to check vertex color with a YUV texture */
    359     /* SDL_SetTextureColorMod(MooseTexture, 0xff, 0x80, 0x80); */
    360 
    361     for (i = 0; i < MOOSEFRAMES_COUNT; i++) {
    362         Uint8 MooseFrameRGB[MOOSEFRAME_SIZE*3];
    363         Uint8 *rgb;
    364         Uint8 *frame;
    365 
    366         rgb = MooseFrameRGB;
    367         frame = RawMooseData + i * MOOSEFRAME_SIZE;
    368         for (j = 0; j < MOOSEFRAME_SIZE; ++j) {
    369             rgb[0] = MooseColors[frame[j]].r;
    370             rgb[1] = MooseColors[frame[j]].g;
    371             rgb[2] = MooseColors[frame[j]].b;
    372             rgb += 3;
    373         }
    374         ConvertRGBtoYV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100);
    375     }
    376 
    377     free(RawMooseData);
    378 
    379     /* set the start frame */
    380     i = 0;
    381     if (nodelay) {
    382         fpsdelay = 0;
    383     } else {
    384         fpsdelay = 1000 / fps;
    385     }
    386 
    387     displayrect.x = 0;
    388     displayrect.y = 0;
    389     displayrect.w = window_w;
    390     displayrect.h = window_h;
    391 
    392     /* Ignore key up events, they don't even get filtered */
    393     SDL_EventState(SDL_KEYUP, SDL_IGNORE);
    394 
    395     /* Loop, waiting for QUIT or RESIZE */
    396     while (!done) {
    397         while (SDL_PollEvent(&event)) {
    398             switch (event.type) {
    399             case SDL_WINDOWEVENT:
    400                 if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
    401                     SDL_RenderSetViewport(renderer, NULL);
    402                     displayrect.w = window_w = event.window.data1;
    403                     displayrect.h = window_h = event.window.data2;
    404                 }
    405                 break;
    406             case SDL_MOUSEBUTTONDOWN:
    407                 displayrect.x = event.button.x - window_w / 2;
    408                 displayrect.y = event.button.y - window_h / 2;
    409                 break;
    410             case SDL_MOUSEMOTION:
    411                 if (event.motion.state) {
    412                     displayrect.x = event.motion.x - window_w / 2;
    413                     displayrect.y = event.motion.y - window_h / 2;
    414                 }
    415                 break;
    416             case SDL_KEYDOWN:
    417                 if (event.key.keysym.sym == SDLK_SPACE) {
    418                     paused = !paused;
    419                     break;
    420                 }
    421                 if (event.key.keysym.sym != SDLK_ESCAPE) {
    422                     break;
    423                 }
    424             case SDL_QUIT:
    425                 done = SDL_TRUE;
    426                 break;
    427             }
    428         }
    429         SDL_Delay(fpsdelay);
    430 
    431         if (!paused) {
    432             i = (i + 1) % MOOSEFRAMES_COUNT;
    433 
    434             SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*SDL_BYTESPERPIXEL(pixel_format));
    435         }
    436         SDL_RenderClear(renderer);
    437         SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect);
    438         SDL_RenderPresent(renderer);
    439     }
    440     SDL_DestroyRenderer(renderer);
    441     quit(0);
    442     return 0;
    443 }
    444 
    445 /* vi: set ts=4 sw=4 expandtab: */
    446