test/testoverlay2.c
author Jørgen P. Tjernø <jorgen@valvesoftware.com>
Wed, 05 Jun 2013 12:48:44 -0700
changeset 7277 1290cd7f34af
parent 6256 1d905b13b102
child 7478 0d02f6a323f5
permissions -rw-r--r--
Mac: Fix invalid PS3 controller mapping.

PS3 controller had swapped D-Pad down & left buttons, as well as X & Y buttons.
Thanks to Alex Szpakowski for the bug report and fix.

Fixes http://bugzilla.libsdl.org/show_bug.cgi?id=1891
     1 /*
     2   Copyright (C) 1997-2011 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 #if 1 /* FIXME: Rework this using the 2.0 API */
    20 #include <stdio.h>
    21 
    22 int main(int argc, char *argv[])
    23 {
    24     printf("FIXME\n");
    25     return 0;
    26 }
    27 #else
    28 #include <stdlib.h>
    29 #include <stdio.h>
    30 #include <string.h>
    31 
    32 #include "SDL.h"
    33 
    34 #define MOOSEPIC_W 64
    35 #define MOOSEPIC_H 88
    36 
    37 #define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H)
    38 #define MOOSEFRAMES_COUNT 10
    39 
    40 SDL_Color MooseColors[84] = {
    41     {49, 49, 49}
    42     , {66, 24, 0}
    43     , {66, 33, 0}
    44     , {66, 66, 66}
    45     ,
    46     {66, 115, 49}
    47     , {74, 33, 0}
    48     , {74, 41, 16}
    49     , {82, 33, 8}
    50     ,
    51     {82, 41, 8}
    52     , {82, 49, 16}
    53     , {82, 82, 82}
    54     , {90, 41, 8}
    55     ,
    56     {90, 41, 16}
    57     , {90, 57, 24}
    58     , {99, 49, 16}
    59     , {99, 66, 24}
    60     ,
    61     {99, 66, 33}
    62     , {99, 74, 33}
    63     , {107, 57, 24}
    64     , {107, 82, 41}
    65     ,
    66     {115, 57, 33}
    67     , {115, 66, 33}
    68     , {115, 66, 41}
    69     , {115, 74, 0}
    70     ,
    71     {115, 90, 49}
    72     , {115, 115, 115}
    73     , {123, 82, 0}
    74     , {123, 99, 57}
    75     ,
    76     {132, 66, 41}
    77     , {132, 74, 41}
    78     , {132, 90, 8}
    79     , {132, 99, 33}
    80     ,
    81     {132, 99, 66}
    82     , {132, 107, 66}
    83     , {140, 74, 49}
    84     , {140, 99, 16}
    85     ,
    86     {140, 107, 74}
    87     , {140, 115, 74}
    88     , {148, 107, 24}
    89     , {148, 115, 82}
    90     ,
    91     {148, 123, 74}
    92     , {148, 123, 90}
    93     , {156, 115, 33}
    94     , {156, 115, 90}
    95     ,
    96     {156, 123, 82}
    97     , {156, 132, 82}
    98     , {156, 132, 99}
    99     , {156, 156, 156}
   100     ,
   101     {165, 123, 49}
   102     , {165, 123, 90}
   103     , {165, 132, 82}
   104     , {165, 132, 90}
   105     ,
   106     {165, 132, 99}
   107     , {165, 140, 90}
   108     , {173, 132, 57}
   109     , {173, 132, 99}
   110     ,
   111     {173, 140, 107}
   112     , {173, 140, 115}
   113     , {173, 148, 99}
   114     , {173, 173, 173}
   115     ,
   116     {181, 140, 74}
   117     , {181, 148, 115}
   118     , {181, 148, 123}
   119     , {181, 156, 107}
   120     ,
   121     {189, 148, 123}
   122     , {189, 156, 82}
   123     , {189, 156, 123}
   124     , {189, 156, 132}
   125     ,
   126     {189, 189, 189}
   127     , {198, 156, 123}
   128     , {198, 165, 132}
   129     , {206, 165, 99}
   130     ,
   131     {206, 165, 132}
   132     , {206, 173, 140}
   133     , {206, 206, 206}
   134     , {214, 173, 115}
   135     ,
   136     {214, 173, 140}
   137     , {222, 181, 148}
   138     , {222, 189, 132}
   139     , {222, 189, 156}
   140     ,
   141     {222, 222, 222}
   142     , {231, 198, 165}
   143     , {231, 231, 231}
   144     , {239, 206, 173}
   145 };
   146 
   147 
   148 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
   149 static void
   150 quit(int rc)
   151 {
   152     SDL_Quit();
   153     exit(rc);
   154 }
   155 
   156 /* All RGB2YUV conversion code and some other parts of code has been taken from testoverlay.c */
   157 
   158 /* NOTE: These RGB conversion functions are not intended for speed,
   159          only as examples.
   160 */
   161 
   162 void
   163 RGBtoYUV(Uint8 * rgb, int *yuv, int monochrome, int luminance)
   164 {
   165     if (monochrome) {
   166 #if 1                           /* these are the two formulas that I found on the FourCC site... */
   167         yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
   168         yuv[1] = 128;
   169         yuv[2] = 128;
   170 #else
   171         yuv[0] = (int)(0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
   172         yuv[1] = 128;
   173         yuv[2] = 128;
   174 #endif
   175     } else {
   176 #if 1                           /* these are the two formulas that I found on the FourCC site... */
   177         yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
   178         yuv[1] = (int)((rgb[2] - yuv[0]) * 0.565 + 128);
   179         yuv[2] = (int)((rgb[0] - yuv[0]) * 0.713 + 128);
   180 #else
   181         yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
   182         yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]);
   183         yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
   184 #endif
   185     }
   186 
   187     if (luminance != 100) {
   188         yuv[0] = yuv[0] * luminance / 100;
   189         if (yuv[0] > 255)
   190             yuv[0] = 255;
   191     }
   192 }
   193 
   194 void
   195 ConvertRGBtoYV12(Uint8 *rgb, Uint8 *out, int w, int h,
   196                  int monochrome, int luminance)
   197 {
   198     int x, y;
   199     int yuv[3];
   200     Uint8 *op[3];
   201 
   202     op[0] = out;
   203     op[1] = op[0] + w*h;
   204     op[2] = op[1] + w*h/4;
   205     for (y = 0; y < h; ++y) {
   206         for (x = 0; x < w; ++x) {
   207             RGBtoYUV(rgb, yuv, monochrome, luminance);
   208             *(op[0]++) = yuv[0];
   209             if (x % 2 == 0 && y % 2 == 0) {
   210                 *(op[1]++) = yuv[2];
   211                 *(op[2]++) = yuv[1];
   212             }
   213             rgb += 3;
   214         }
   215     }
   216 }
   217 
   218 void
   219 ConvertRGBtoIYUV(SDL_Surface * s, SDL_Overlay * o, int monochrome,
   220                  int luminance)
   221 {
   222     int x, y;
   223     int yuv[3];
   224     Uint8 *p, *op[3];
   225 
   226     SDL_LockSurface(s);
   227     SDL_LockYUVOverlay(o);
   228 
   229     /* Convert */
   230     for (y = 0; y < s->h && y < o->h; y++) {
   231         p = ((Uint8 *) s->pixels) + s->pitch * y;
   232         op[0] = o->pixels[0] + o->pitches[0] * y;
   233         op[1] = o->pixels[1] + o->pitches[1] * (y / 2);
   234         op[2] = o->pixels[2] + o->pitches[2] * (y / 2);
   235         for (x = 0; x < s->w && x < o->w; x++) {
   236             RGBtoYUV(p, yuv, monochrome, luminance);
   237             *(op[0]++) = yuv[0];
   238             if (x % 2 == 0 && y % 2 == 0) {
   239                 *(op[1]++) = yuv[1];
   240                 *(op[2]++) = yuv[2];
   241             }
   242             p += s->format->BytesPerPixel;
   243         }
   244     }
   245 
   246     SDL_UnlockYUVOverlay(o);
   247     SDL_UnlockSurface(s);
   248 }
   249 
   250 void
   251 ConvertRGBtoUYVY(SDL_Surface * s, SDL_Overlay * o, int monochrome,
   252                  int luminance)
   253 {
   254     int x, y;
   255     int yuv[3];
   256     Uint8 *p, *op;
   257 
   258     SDL_LockSurface(s);
   259     SDL_LockYUVOverlay(o);
   260 
   261     for (y = 0; y < s->h && y < o->h; y++) {
   262         p = ((Uint8 *) s->pixels) + s->pitch * y;
   263         op = o->pixels[0] + o->pitches[0] * y;
   264         for (x = 0; x < s->w && x < o->w; x++) {
   265             RGBtoYUV(p, yuv, monochrome, luminance);
   266             if (x % 2 == 0) {
   267                 *(op++) = yuv[1];
   268                 *(op++) = yuv[0];
   269                 *(op++) = yuv[2];
   270             } else
   271                 *(op++) = yuv[0];
   272 
   273             p += s->format->BytesPerPixel;
   274         }
   275     }
   276 
   277     SDL_UnlockYUVOverlay(o);
   278     SDL_UnlockSurface(s);
   279 }
   280 
   281 void
   282 ConvertRGBtoYVYU(SDL_Surface * s, SDL_Overlay * o, int monochrome,
   283                  int luminance)
   284 {
   285     int x, y;
   286     int yuv[3];
   287     Uint8 *p, *op;
   288 
   289     SDL_LockSurface(s);
   290     SDL_LockYUVOverlay(o);
   291 
   292     for (y = 0; y < s->h && y < o->h; y++) {
   293         p = ((Uint8 *) s->pixels) + s->pitch * y;
   294         op = o->pixels[0] + o->pitches[0] * y;
   295         for (x = 0; x < s->w && x < o->w; x++) {
   296             RGBtoYUV(p, yuv, monochrome, luminance);
   297             if (x % 2 == 0) {
   298                 *(op++) = yuv[0];
   299                 *(op++) = yuv[2];
   300                 op[1] = yuv[1];
   301             } else {
   302                 *op = yuv[0];
   303                 op += 2;
   304             }
   305 
   306             p += s->format->BytesPerPixel;
   307         }
   308     }
   309 
   310     SDL_UnlockYUVOverlay(o);
   311     SDL_UnlockSurface(s);
   312 }
   313 
   314 void
   315 ConvertRGBtoYUY2(SDL_Surface * s, SDL_Overlay * o, int monochrome,
   316                  int luminance)
   317 {
   318     int x, y;
   319     int yuv[3];
   320     Uint8 *p, *op;
   321 
   322     SDL_LockSurface(s);
   323     SDL_LockYUVOverlay(o);
   324 
   325     for (y = 0; y < s->h && y < o->h; y++) {
   326         p = ((Uint8 *) s->pixels) + s->pitch * y;
   327         op = o->pixels[0] + o->pitches[0] * y;
   328         for (x = 0; x < s->w && x < o->w; x++) {
   329             RGBtoYUV(p, yuv, monochrome, luminance);
   330             if (x % 2 == 0) {
   331                 *(op++) = yuv[0];
   332                 *(op++) = yuv[1];
   333                 op[1] = yuv[2];
   334             } else {
   335                 *op = yuv[0];
   336                 op += 2;
   337             }
   338 
   339             p += s->format->BytesPerPixel;
   340         }
   341     }
   342 
   343     SDL_UnlockYUVOverlay(o);
   344     SDL_UnlockSurface(s);
   345 }
   346 
   347 static void
   348 PrintUsage(char *argv0)
   349 {
   350     fprintf(stderr, "Usage: %s [arg] [arg] [arg] ...\n", argv0);
   351     fprintf(stderr, "\n");
   352     fprintf(stderr, "Where 'arg' is any of the following options:\n");
   353     fprintf(stderr, "\n");
   354     fprintf(stderr, "    -fps <frames per second>\n");
   355     fprintf(stderr, "    -nodelay\n");
   356     fprintf(stderr, "    -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n");
   357     fprintf(stderr, "    -scale <scale factor> (initial scale of the overlay)\n");
   358     fprintf(stderr, "    -help (shows this help)\n");
   359     fprintf(stderr, "\n");
   360     fprintf(stderr,
   361             "Press ESC to exit, or SPACE to freeze the movie while application running.\n");
   362     fprintf(stderr, "\n");
   363 }
   364 
   365 int
   366 main(int argc, char **argv)
   367 {
   368     Uint8 *RawMooseData;
   369     SDL_RWops *handle;
   370     int window_w;
   371     int window_h;
   372     SDL_Window *window;
   373     SDL_Renderer *renderer;
   374     Uint8 MooseFrame[MOOSEFRAMES_COUNT][MOOSEFRAME_SIZE*2];
   375     SDL_Texture *MooseTexture;
   376     SDL_Rect displayrect;
   377     SDL_Event event;
   378     int paused = 0;
   379     int i, j;
   380     int fps = 12;
   381     int fpsdelay;
   382     int nodelay = 0;
   383     Uint32 pixel_format = SDL_PIXELFORMAT_YV12;
   384     int scale = 5;
   385     SDL_bool done = SDL_FALSE;
   386 
   387     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
   388         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
   389         return 3;
   390     }
   391 
   392     while (argc > 1) {
   393         if (strcmp(argv[1], "-fps") == 0) {
   394             if (argv[2]) {
   395                 fps = atoi(argv[2]);
   396                 if (fps == 0) {
   397                     fprintf(stderr,
   398                             "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
   399                     quit(10);
   400                 }
   401                 if ((fps < 0) || (fps > 1000)) {
   402                     fprintf(stderr,
   403                             "The -fps option must be in range from 1 to 1000, default is 12.\n");
   404                     quit(10);
   405                 }
   406                 argv += 2;
   407                 argc -= 2;
   408             } else {
   409                 fprintf(stderr,
   410                         "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
   411                 quit(10);
   412             }
   413         } else if (strcmp(argv[1], "-nodelay") == 0) {
   414             nodelay = 1;
   415             argv += 1;
   416             argc -= 1;
   417         } else if (strcmp(argv[1], "-format") == 0) {
   418             if (argv[2]) {
   419                 if (!strcmp(argv[2], "YV12"))
   420                     pixel_format = SDL_PIXELFORMAT_YV12;
   421                 else if (!strcmp(argv[2], "IYUV"))
   422                     pixel_format = SDL_PIXELFORMAT_IYUV;
   423                 else if (!strcmp(argv[2], "YUY2"))
   424                     pixel_format = SDL_PIXELFORMAT_YUY2;
   425                 else if (!strcmp(argv[2], "UYVY"))
   426                     pixel_format = SDL_PIXELFORMAT_UYVY;
   427                 else if (!strcmp(argv[2], "YVYU"))
   428                     pixel_format = SDL_PIXELFORMAT_YVYU;
   429                 else {
   430                     fprintf(stderr,
   431                             "The -format option %s is not recognized, see help for info.\n",
   432                             argv[2]);
   433                     quit(10);
   434                 }
   435                 argv += 2;
   436                 argc -= 2;
   437             } else {
   438                 fprintf(stderr,
   439                         "The -format option requires an argument, default is YUY2.\n");
   440                 quit(10);
   441             }
   442         } else if (strcmp(argv[1], "-scale") == 0) {
   443             if (argv[2]) {
   444                 scale = atoi(argv[2]);
   445                 if (scale == 0) {
   446                     fprintf(stderr,
   447                             "The -scale option requires an argument [from 1 to 50], default is 5.\n");
   448                     quit(10);
   449                 }
   450                 if ((scale < 0) || (scale > 50)) {
   451                     fprintf(stderr,
   452                             "The -scale option must be in range from 1 to 50, default is 5.\n");
   453                     quit(10);
   454                 }
   455                 argv += 2;
   456                 argc -= 2;
   457             } else {
   458                 fprintf(stderr,
   459                         "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
   460                 quit(10);
   461             }
   462         } else if ((strcmp(argv[1], "-help") == 0)
   463                    || (strcmp(argv[1], "-h") == 0)) {
   464             PrintUsage(argv[0]);
   465             quit(0);
   466         } else {
   467             fprintf(stderr, "Unrecognized option: %s.\n", argv[1]);
   468             quit(10);
   469         }
   470         break;
   471     }
   472 
   473     RawMooseData = (Uint8 *) malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT);
   474     if (RawMooseData == NULL) {
   475         fprintf(stderr, "Can't allocate memory for movie !\n");
   476         free(RawMooseData);
   477         quit(1);
   478     }
   479 
   480     /* load the trojan moose images */
   481     handle = SDL_RWFromFile("moose.dat", "rb");
   482     if (handle == NULL) {
   483         fprintf(stderr, "Can't find the file moose.dat !\n");
   484         free(RawMooseData);
   485         quit(2);
   486     }
   487 
   488     SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT);
   489 
   490     SDL_RWclose(handle);
   491 
   492     /* Create the window and renderer */
   493     window_w = MOOSEPIC_W * scale;
   494     window_h = MOOSEPIC_H * scale;
   495     window = SDL_CreateWindow("Happy Moose",
   496                               SDL_WINDOWPOS_UNDEFINED,
   497                               SDL_WINDOWPOS_UNDEFINED,
   498                               window_w, window_h,
   499                               SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);
   500     if (!window) {
   501         fprintf(stderr, "Couldn't set create window: %s\n", SDL_GetError());
   502         free(RawMooseData);
   503         quit(4);
   504     }
   505 
   506     renderer = SDL_CreateRenderer(window, -1, 0);
   507     if (!renderer) {
   508         fprintf(stderr, "Couldn't set create renderer: %s\n", SDL_GetError());
   509         free(RawMooseData);
   510         quit(4);
   511     }
   512 
   513     MooseTexture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
   514     if (!MooseTexture) {
   515         fprintf(stderr, "Couldn't set create texture: %s\n", SDL_GetError());
   516         free(RawMooseData);
   517         quit(5);
   518     }
   519 
   520     for (i = 0; i < MOOSEFRAMES_COUNT; i++) {
   521         Uint8 MooseFrameRGB[MOOSEFRAME_SIZE*3];
   522         Uint8 *rgb;
   523         Uint8 *frame;
   524 
   525         rgb = MooseFrameRGB;
   526         frame = RawMooseData + i * MOOSEFRAME_SIZE;
   527         for (j = 0; j < MOOSEFRAME_SIZE; ++j) {
   528             rgb[0] = MooseColors[frame[j]].r;
   529             rgb[1] = MooseColors[frame[j]].g;
   530             rgb[2] = MooseColors[frame[j]].b;
   531             rgb += 3;
   532         }
   533         ConvertRGBtoYV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100);
   534     }
   535 
   536     free(RawMooseData);
   537 
   538     /* set the start frame */
   539     i = 0;
   540     if (nodelay) {
   541         fpsdelay = 0;
   542     } else {
   543         fpsdelay = 1000 / fps;
   544     }
   545 
   546     displayrect.x = 0;
   547     displayrect.y = 0;
   548     displayrect.w = window_w;
   549     displayrect.h = window_h;
   550 
   551     /* Ignore key up events, they don't even get filtered */
   552     SDL_EventState(SDL_KEYUP, SDL_IGNORE);
   553 
   554     /* Loop, waiting for QUIT or RESIZE */
   555     while (!done) {
   556         while (SDL_PollEvent(&event)) {
   557             switch (event.type) {
   558             case SDL_WINDOWEVENT:
   559                 if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
   560                     SDL_RenderSetViewport(renderer, NULL);
   561                     displayrect.w = window_w = event.window.data1;
   562                     displayrect.h = window_h = event.window.data2;
   563                 }
   564                 break;
   565             case SDL_MOUSEBUTTONDOWN:
   566                 displayrect.x = event.button.x - window_w / 2;
   567                 displayrect.y = event.button.y - window_h / 2;
   568                 break;
   569             case SDL_MOUSEMOTION:
   570                 if (event.motion.state) {
   571                     displayrect.x = event.motion.x - window_w / 2;
   572                     displayrect.y = event.motion.y - window_h / 2;
   573                 }
   574                 break;
   575             case SDL_KEYDOWN:
   576                 if (event.key.keysym.sym == SDLK_SPACE) {
   577                     paused = !paused;
   578                     break;
   579                 }
   580                 if (event.key.keysym.sym != SDLK_ESCAPE) {
   581                     break;
   582                 }
   583             case SDL_QUIT:
   584                 done = SDL_TRUE;
   585                 break;
   586             }
   587         }
   588         SDL_Delay(fpsdelay);
   589 
   590         if (!paused) {
   591             i = (i + 1) % MOOSEFRAMES_COUNT;
   592 
   593             SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*SDL_BYTESPERPIXEL(pixel_format));
   594         }
   595         SDL_RenderClear(renderer);
   596         SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect);
   597         SDL_RenderPresent(renderer);
   598     }
   599     SDL_DestroyRenderer(renderer);
   600     quit(0);
   601     return 0;
   602 }
   603 #endif
   604 
   605 /* vi: set ts=4 sw=4 expandtab: */