test/testoverlay2.c
author Alex Baines <alex@abaines.me.uk>
Tue, 19 Aug 2014 23:31:50 +0100
changeset 9097 56d712662a82
parent 9046 c3ec7c3e6c24
child 9278 8900afb78a19
permissions -rw-r--r--
Add a SDL_IM_INTERNAL_EDITING event to make IMs like iBus render editing text in its own UI instead of sending TEXTEDITING events.
This is useful for applications that handle TEXTINPUT events but not TEXTEDITING events.
     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 
    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 void
   210 ConvertRGBtoNV12(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 
   232 static void
   233 PrintUsage(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 
   249 int
   250 main(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: */