src/test/SDL_test_common.c
author Sam Lantinga
Fri, 27 Jan 2017 21:23:27 -0800
changeset 10861 71d8f9afb690
parent 10737 3406a0f8b041
child 10866 ed2b5c68379d
permissions -rw-r--r--
Fixed bug 3569 - GL_UpdateViewport leaves PROJECTION matrix selected

Tom Seddon

GL_ActivateRenderer may call GL_UpdateViewport, which leaves the GL_PROJECTION matrix selected. But after GL_ResetState, the GL_MODELVIEW matrix is selected, suggesting that's the intended default state.

It seems at least like these should be consistent. Presumably GL_UpdateViewport should be doing a glMatrixMode(GL_MODELVIEW) before it finishes.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2017 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 
    22 /* Ported from original test\common.c file. */
    23 
    24 #include "SDL_config.h"
    25 #include "SDL_test.h"
    26 
    27 #include <stdio.h>
    28 
    29 #define VIDEO_USAGE \
    30 "[--video driver] [--renderer driver] [--gldebug] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--min-geometry WxH] [--max-geometry WxH] [--logical WxH] [--scale N] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab] [--allow-highdpi]"
    31 
    32 #define AUDIO_USAGE \
    33 "[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]"
    34 
    35 SDLTest_CommonState *
    36 SDLTest_CommonCreateState(char **argv, Uint32 flags)
    37 {
    38     SDLTest_CommonState *state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state));
    39     if (!state) {
    40         SDL_OutOfMemory();
    41         return NULL;
    42     }
    43 
    44     /* Initialize some defaults */
    45     state->argv = argv;
    46     state->flags = flags;
    47     state->window_title = argv[0];
    48     state->window_flags = 0;
    49     state->window_x = SDL_WINDOWPOS_UNDEFINED;
    50     state->window_y = SDL_WINDOWPOS_UNDEFINED;
    51     state->window_w = DEFAULT_WINDOW_WIDTH;
    52     state->window_h = DEFAULT_WINDOW_HEIGHT;
    53     state->num_windows = 1;
    54     state->audiospec.freq = 22050;
    55     state->audiospec.format = AUDIO_S16;
    56     state->audiospec.channels = 2;
    57     state->audiospec.samples = 2048;
    58 
    59     /* Set some very sane GL defaults */
    60     state->gl_red_size = 3;
    61     state->gl_green_size = 3;
    62     state->gl_blue_size = 2;
    63     state->gl_alpha_size = 0;
    64     state->gl_buffer_size = 0;
    65     state->gl_depth_size = 16;
    66     state->gl_stencil_size = 0;
    67     state->gl_double_buffer = 1;
    68     state->gl_accum_red_size = 0;
    69     state->gl_accum_green_size = 0;
    70     state->gl_accum_blue_size = 0;
    71     state->gl_accum_alpha_size = 0;
    72     state->gl_stereo = 0;
    73     state->gl_multisamplebuffers = 0;
    74     state->gl_multisamplesamples = 0;
    75     state->gl_retained_backing = 1;
    76     state->gl_accelerated = -1;
    77     state->gl_debug = 0;
    78 
    79     return state;
    80 }
    81 
    82 int
    83 SDLTest_CommonArg(SDLTest_CommonState * state, int index)
    84 {
    85     char **argv = state->argv;
    86 
    87     if (SDL_strcasecmp(argv[index], "--video") == 0) {
    88         ++index;
    89         if (!argv[index]) {
    90             return -1;
    91         }
    92         state->videodriver = argv[index];
    93         return 2;
    94     }
    95     if (SDL_strcasecmp(argv[index], "--renderer") == 0) {
    96         ++index;
    97         if (!argv[index]) {
    98             return -1;
    99         }
   100         state->renderdriver = argv[index];
   101         return 2;
   102     }
   103     if (SDL_strcasecmp(argv[index], "--gldebug") == 0) {
   104         state->gl_debug = 1;
   105         return 1;
   106     }
   107     if (SDL_strcasecmp(argv[index], "--info") == 0) {
   108         ++index;
   109         if (!argv[index]) {
   110             return -1;
   111         }
   112         if (SDL_strcasecmp(argv[index], "all") == 0) {
   113             state->verbose |=
   114                 (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER |
   115                  VERBOSE_EVENT);
   116             return 2;
   117         }
   118         if (SDL_strcasecmp(argv[index], "video") == 0) {
   119             state->verbose |= VERBOSE_VIDEO;
   120             return 2;
   121         }
   122         if (SDL_strcasecmp(argv[index], "modes") == 0) {
   123             state->verbose |= VERBOSE_MODES;
   124             return 2;
   125         }
   126         if (SDL_strcasecmp(argv[index], "render") == 0) {
   127             state->verbose |= VERBOSE_RENDER;
   128             return 2;
   129         }
   130         if (SDL_strcasecmp(argv[index], "event") == 0) {
   131             state->verbose |= VERBOSE_EVENT;
   132             return 2;
   133         }
   134         return -1;
   135     }
   136     if (SDL_strcasecmp(argv[index], "--log") == 0) {
   137         ++index;
   138         if (!argv[index]) {
   139             return -1;
   140         }
   141         if (SDL_strcasecmp(argv[index], "all") == 0) {
   142             SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
   143             return 2;
   144         }
   145         if (SDL_strcasecmp(argv[index], "error") == 0) {
   146             SDL_LogSetPriority(SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_VERBOSE);
   147             return 2;
   148         }
   149         if (SDL_strcasecmp(argv[index], "system") == 0) {
   150             SDL_LogSetPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE);
   151             return 2;
   152         }
   153         if (SDL_strcasecmp(argv[index], "audio") == 0) {
   154             SDL_LogSetPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE);
   155             return 2;
   156         }
   157         if (SDL_strcasecmp(argv[index], "video") == 0) {
   158             SDL_LogSetPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE);
   159             return 2;
   160         }
   161         if (SDL_strcasecmp(argv[index], "render") == 0) {
   162             SDL_LogSetPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE);
   163             return 2;
   164         }
   165         if (SDL_strcasecmp(argv[index], "input") == 0) {
   166             SDL_LogSetPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE);
   167             return 2;
   168         }
   169         return -1;
   170     }
   171     if (SDL_strcasecmp(argv[index], "--display") == 0) {
   172         ++index;
   173         if (!argv[index]) {
   174             return -1;
   175         }
   176         state->display = SDL_atoi(argv[index]);
   177         if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) {
   178             state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
   179             state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
   180         }
   181         if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) {
   182             state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
   183             state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
   184         }
   185         return 2;
   186     }
   187     if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
   188         state->window_flags |= SDL_WINDOW_FULLSCREEN;
   189         state->num_windows = 1;
   190         return 1;
   191     }
   192     if (SDL_strcasecmp(argv[index], "--fullscreen-desktop") == 0) {
   193         state->window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
   194         state->num_windows = 1;
   195         return 1;
   196     }
   197     if (SDL_strcasecmp(argv[index], "--allow-highdpi") == 0) {
   198         state->window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
   199         return 1;
   200     }
   201     if (SDL_strcasecmp(argv[index], "--windows") == 0) {
   202         ++index;
   203         if (!argv[index] || !SDL_isdigit(*argv[index])) {
   204             return -1;
   205         }
   206         if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
   207             state->num_windows = SDL_atoi(argv[index]);
   208         }
   209         return 2;
   210     }
   211     if (SDL_strcasecmp(argv[index], "--title") == 0) {
   212         ++index;
   213         if (!argv[index]) {
   214             return -1;
   215         }
   216         state->window_title = argv[index];
   217         return 2;
   218     }
   219     if (SDL_strcasecmp(argv[index], "--icon") == 0) {
   220         ++index;
   221         if (!argv[index]) {
   222             return -1;
   223         }
   224         state->window_icon = argv[index];
   225         return 2;
   226     }
   227     if (SDL_strcasecmp(argv[index], "--center") == 0) {
   228         state->window_x = SDL_WINDOWPOS_CENTERED;
   229         state->window_y = SDL_WINDOWPOS_CENTERED;
   230         return 1;
   231     }
   232     if (SDL_strcasecmp(argv[index], "--position") == 0) {
   233         char *x, *y;
   234         ++index;
   235         if (!argv[index]) {
   236             return -1;
   237         }
   238         x = argv[index];
   239         y = argv[index];
   240         while (*y && *y != ',') {
   241             ++y;
   242         }
   243         if (!*y) {
   244             return -1;
   245         }
   246         *y++ = '\0';
   247         state->window_x = SDL_atoi(x);
   248         state->window_y = SDL_atoi(y);
   249         return 2;
   250     }
   251     if (SDL_strcasecmp(argv[index], "--geometry") == 0) {
   252         char *w, *h;
   253         ++index;
   254         if (!argv[index]) {
   255             return -1;
   256         }
   257         w = argv[index];
   258         h = argv[index];
   259         while (*h && *h != 'x') {
   260             ++h;
   261         }
   262         if (!*h) {
   263             return -1;
   264         }
   265         *h++ = '\0';
   266         state->window_w = SDL_atoi(w);
   267         state->window_h = SDL_atoi(h);
   268         return 2;
   269     }
   270     if (SDL_strcasecmp(argv[index], "--min-geometry") == 0) {
   271         char *w, *h;
   272         ++index;
   273         if (!argv[index]) {
   274             return -1;
   275         }
   276         w = argv[index];
   277         h = argv[index];
   278         while (*h && *h != 'x') {
   279             ++h;
   280         }
   281         if (!*h) {
   282             return -1;
   283         }
   284         *h++ = '\0';
   285         state->window_minW = SDL_atoi(w);
   286         state->window_minH = SDL_atoi(h);
   287         return 2;
   288     }
   289     if (SDL_strcasecmp(argv[index], "--max-geometry") == 0) {
   290         char *w, *h;
   291         ++index;
   292         if (!argv[index]) {
   293             return -1;
   294         }
   295         w = argv[index];
   296         h = argv[index];
   297         while (*h && *h != 'x') {
   298             ++h;
   299         }
   300         if (!*h) {
   301             return -1;
   302         }
   303         *h++ = '\0';
   304         state->window_maxW = SDL_atoi(w);
   305         state->window_maxH = SDL_atoi(h);
   306         return 2;
   307     }
   308     if (SDL_strcasecmp(argv[index], "--logical") == 0) {
   309         char *w, *h;
   310         ++index;
   311         if (!argv[index]) {
   312             return -1;
   313         }
   314         w = argv[index];
   315         h = argv[index];
   316         while (*h && *h != 'x') {
   317             ++h;
   318         }
   319         if (!*h) {
   320             return -1;
   321         }
   322         *h++ = '\0';
   323         state->logical_w = SDL_atoi(w);
   324         state->logical_h = SDL_atoi(h);
   325         return 2;
   326     }
   327     if (SDL_strcasecmp(argv[index], "--scale") == 0) {
   328         ++index;
   329         if (!argv[index]) {
   330             return -1;
   331         }
   332         state->scale = (float)SDL_atof(argv[index]);
   333         return 2;
   334     }
   335     if (SDL_strcasecmp(argv[index], "--depth") == 0) {
   336         ++index;
   337         if (!argv[index]) {
   338             return -1;
   339         }
   340         state->depth = SDL_atoi(argv[index]);
   341         return 2;
   342     }
   343     if (SDL_strcasecmp(argv[index], "--refresh") == 0) {
   344         ++index;
   345         if (!argv[index]) {
   346             return -1;
   347         }
   348         state->refresh_rate = SDL_atoi(argv[index]);
   349         return 2;
   350     }
   351     if (SDL_strcasecmp(argv[index], "--vsync") == 0) {
   352         state->render_flags |= SDL_RENDERER_PRESENTVSYNC;
   353         return 1;
   354     }
   355     if (SDL_strcasecmp(argv[index], "--noframe") == 0) {
   356         state->window_flags |= SDL_WINDOW_BORDERLESS;
   357         return 1;
   358     }
   359     if (SDL_strcasecmp(argv[index], "--resize") == 0) {
   360         state->window_flags |= SDL_WINDOW_RESIZABLE;
   361         return 1;
   362     }
   363     if (SDL_strcasecmp(argv[index], "--minimize") == 0) {
   364         state->window_flags |= SDL_WINDOW_MINIMIZED;
   365         return 1;
   366     }
   367     if (SDL_strcasecmp(argv[index], "--maximize") == 0) {
   368         state->window_flags |= SDL_WINDOW_MAXIMIZED;
   369         return 1;
   370     }
   371     if (SDL_strcasecmp(argv[index], "--grab") == 0) {
   372         state->window_flags |= SDL_WINDOW_INPUT_GRABBED;
   373         return 1;
   374     }
   375     if (SDL_strcasecmp(argv[index], "--rate") == 0) {
   376         ++index;
   377         if (!argv[index]) {
   378             return -1;
   379         }
   380         state->audiospec.freq = SDL_atoi(argv[index]);
   381         return 2;
   382     }
   383     if (SDL_strcasecmp(argv[index], "--format") == 0) {
   384         ++index;
   385         if (!argv[index]) {
   386             return -1;
   387         }
   388         if (SDL_strcasecmp(argv[index], "U8") == 0) {
   389             state->audiospec.format = AUDIO_U8;
   390             return 2;
   391         }
   392         if (SDL_strcasecmp(argv[index], "S8") == 0) {
   393             state->audiospec.format = AUDIO_S8;
   394             return 2;
   395         }
   396         if (SDL_strcasecmp(argv[index], "U16") == 0) {
   397             state->audiospec.format = AUDIO_U16;
   398             return 2;
   399         }
   400         if (SDL_strcasecmp(argv[index], "U16LE") == 0) {
   401             state->audiospec.format = AUDIO_U16LSB;
   402             return 2;
   403         }
   404         if (SDL_strcasecmp(argv[index], "U16BE") == 0) {
   405             state->audiospec.format = AUDIO_U16MSB;
   406             return 2;
   407         }
   408         if (SDL_strcasecmp(argv[index], "S16") == 0) {
   409             state->audiospec.format = AUDIO_S16;
   410             return 2;
   411         }
   412         if (SDL_strcasecmp(argv[index], "S16LE") == 0) {
   413             state->audiospec.format = AUDIO_S16LSB;
   414             return 2;
   415         }
   416         if (SDL_strcasecmp(argv[index], "S16BE") == 0) {
   417             state->audiospec.format = AUDIO_S16MSB;
   418             return 2;
   419         }
   420         return -1;
   421     }
   422     if (SDL_strcasecmp(argv[index], "--channels") == 0) {
   423         ++index;
   424         if (!argv[index]) {
   425             return -1;
   426         }
   427         state->audiospec.channels = (Uint8) SDL_atoi(argv[index]);
   428         return 2;
   429     }
   430     if (SDL_strcasecmp(argv[index], "--samples") == 0) {
   431         ++index;
   432         if (!argv[index]) {
   433             return -1;
   434         }
   435         state->audiospec.samples = (Uint16) SDL_atoi(argv[index]);
   436         return 2;
   437     }
   438     if ((SDL_strcasecmp(argv[index], "-h") == 0)
   439         || (SDL_strcasecmp(argv[index], "--help") == 0)) {
   440         /* Print the usage message */
   441         return -1;
   442     }
   443     if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) {
   444     /* Debug flag sent by Xcode */
   445         return 2;
   446     }
   447     return 0;
   448 }
   449 
   450 const char *
   451 SDLTest_CommonUsage(SDLTest_CommonState * state)
   452 {
   453     switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
   454     case SDL_INIT_VIDEO:
   455         return VIDEO_USAGE;
   456     case SDL_INIT_AUDIO:
   457         return AUDIO_USAGE;
   458     case (SDL_INIT_VIDEO | SDL_INIT_AUDIO):
   459         return VIDEO_USAGE " " AUDIO_USAGE;
   460     default:
   461         return "";
   462     }
   463 }
   464 
   465 static void
   466 SDLTest_PrintRendererFlag(Uint32 flag)
   467 {
   468     switch (flag) {
   469     case SDL_RENDERER_PRESENTVSYNC:
   470         fprintf(stderr, "PresentVSync");
   471         break;
   472     case SDL_RENDERER_ACCELERATED:
   473         fprintf(stderr, "Accelerated");
   474         break;
   475     default:
   476         fprintf(stderr, "0x%8.8x", flag);
   477         break;
   478     }
   479 }
   480 
   481 static void
   482 SDLTest_PrintPixelFormat(Uint32 format)
   483 {
   484     switch (format) {
   485     case SDL_PIXELFORMAT_UNKNOWN:
   486         fprintf(stderr, "Unknwon");
   487         break;
   488     case SDL_PIXELFORMAT_INDEX1LSB:
   489         fprintf(stderr, "Index1LSB");
   490         break;
   491     case SDL_PIXELFORMAT_INDEX1MSB:
   492         fprintf(stderr, "Index1MSB");
   493         break;
   494     case SDL_PIXELFORMAT_INDEX4LSB:
   495         fprintf(stderr, "Index4LSB");
   496         break;
   497     case SDL_PIXELFORMAT_INDEX4MSB:
   498         fprintf(stderr, "Index4MSB");
   499         break;
   500     case SDL_PIXELFORMAT_INDEX8:
   501         fprintf(stderr, "Index8");
   502         break;
   503     case SDL_PIXELFORMAT_RGB332:
   504         fprintf(stderr, "RGB332");
   505         break;
   506     case SDL_PIXELFORMAT_RGB444:
   507         fprintf(stderr, "RGB444");
   508         break;
   509     case SDL_PIXELFORMAT_RGB555:
   510         fprintf(stderr, "RGB555");
   511         break;
   512     case SDL_PIXELFORMAT_BGR555:
   513         fprintf(stderr, "BGR555");
   514         break;
   515     case SDL_PIXELFORMAT_ARGB4444:
   516         fprintf(stderr, "ARGB4444");
   517         break;
   518     case SDL_PIXELFORMAT_ABGR4444:
   519         fprintf(stderr, "ABGR4444");
   520         break;
   521     case SDL_PIXELFORMAT_ARGB1555:
   522         fprintf(stderr, "ARGB1555");
   523         break;
   524     case SDL_PIXELFORMAT_ABGR1555:
   525         fprintf(stderr, "ABGR1555");
   526         break;
   527     case SDL_PIXELFORMAT_RGB565:
   528         fprintf(stderr, "RGB565");
   529         break;
   530     case SDL_PIXELFORMAT_BGR565:
   531         fprintf(stderr, "BGR565");
   532         break;
   533     case SDL_PIXELFORMAT_RGB24:
   534         fprintf(stderr, "RGB24");
   535         break;
   536     case SDL_PIXELFORMAT_BGR24:
   537         fprintf(stderr, "BGR24");
   538         break;
   539     case SDL_PIXELFORMAT_RGB888:
   540         fprintf(stderr, "RGB888");
   541         break;
   542     case SDL_PIXELFORMAT_BGR888:
   543         fprintf(stderr, "BGR888");
   544         break;
   545     case SDL_PIXELFORMAT_ARGB8888:
   546         fprintf(stderr, "ARGB8888");
   547         break;
   548     case SDL_PIXELFORMAT_RGBA8888:
   549         fprintf(stderr, "RGBA8888");
   550         break;
   551     case SDL_PIXELFORMAT_ABGR8888:
   552         fprintf(stderr, "ABGR8888");
   553         break;
   554     case SDL_PIXELFORMAT_BGRA8888:
   555         fprintf(stderr, "BGRA8888");
   556         break;
   557     case SDL_PIXELFORMAT_ARGB2101010:
   558         fprintf(stderr, "ARGB2101010");
   559         break;
   560     case SDL_PIXELFORMAT_YV12:
   561         fprintf(stderr, "YV12");
   562         break;
   563     case SDL_PIXELFORMAT_IYUV:
   564         fprintf(stderr, "IYUV");
   565         break;
   566     case SDL_PIXELFORMAT_YUY2:
   567         fprintf(stderr, "YUY2");
   568         break;
   569     case SDL_PIXELFORMAT_UYVY:
   570         fprintf(stderr, "UYVY");
   571         break;
   572     case SDL_PIXELFORMAT_YVYU:
   573         fprintf(stderr, "YVYU");
   574         break;
   575     case SDL_PIXELFORMAT_NV12:
   576         fprintf(stderr, "NV12");
   577         break;
   578     case SDL_PIXELFORMAT_NV21:
   579         fprintf(stderr, "NV21");
   580         break;
   581     default:
   582         fprintf(stderr, "0x%8.8x", format);
   583         break;
   584     }
   585 }
   586 
   587 static void
   588 SDLTest_PrintRenderer(SDL_RendererInfo * info)
   589 {
   590     int i, count;
   591 
   592     fprintf(stderr, "  Renderer %s:\n", info->name);
   593 
   594     fprintf(stderr, "    Flags: 0x%8.8X", info->flags);
   595     fprintf(stderr, " (");
   596     count = 0;
   597     for (i = 0; i < sizeof(info->flags) * 8; ++i) {
   598         Uint32 flag = (1 << i);
   599         if (info->flags & flag) {
   600             if (count > 0) {
   601                 fprintf(stderr, " | ");
   602             }
   603             SDLTest_PrintRendererFlag(flag);
   604             ++count;
   605         }
   606     }
   607     fprintf(stderr, ")\n");
   608 
   609     fprintf(stderr, "    Texture formats (%d): ", info->num_texture_formats);
   610     for (i = 0; i < (int) info->num_texture_formats; ++i) {
   611         if (i > 0) {
   612             fprintf(stderr, ", ");
   613         }
   614         SDLTest_PrintPixelFormat(info->texture_formats[i]);
   615     }
   616     fprintf(stderr, "\n");
   617 
   618     if (info->max_texture_width || info->max_texture_height) {
   619         fprintf(stderr, "    Max Texture Size: %dx%d\n",
   620                 info->max_texture_width, info->max_texture_height);
   621     }
   622 }
   623 
   624 static SDL_Surface *
   625 SDLTest_LoadIcon(const char *file)
   626 {
   627     SDL_Surface *icon;
   628 
   629     /* Load the icon surface */
   630     icon = SDL_LoadBMP(file);
   631     if (icon == NULL) {
   632         fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
   633         return (NULL);
   634     }
   635 
   636     if (icon->format->palette) {
   637         /* Set the colorkey */
   638         SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels));
   639     }
   640 
   641     return (icon);
   642 }
   643 
   644 SDL_bool
   645 SDLTest_CommonInit(SDLTest_CommonState * state)
   646 {
   647     int i, j, m, n, w, h;
   648     SDL_DisplayMode fullscreen_mode;
   649 
   650     if (state->flags & SDL_INIT_VIDEO) {
   651         if (state->verbose & VERBOSE_VIDEO) {
   652             n = SDL_GetNumVideoDrivers();
   653             if (n == 0) {
   654                 fprintf(stderr, "No built-in video drivers\n");
   655             } else {
   656                 fprintf(stderr, "Built-in video drivers:");
   657                 for (i = 0; i < n; ++i) {
   658                     if (i > 0) {
   659                         fprintf(stderr, ",");
   660                     }
   661                     fprintf(stderr, " %s", SDL_GetVideoDriver(i));
   662                 }
   663                 fprintf(stderr, "\n");
   664             }
   665         }
   666         if (SDL_VideoInit(state->videodriver) < 0) {
   667             fprintf(stderr, "Couldn't initialize video driver: %s\n",
   668                     SDL_GetError());
   669             return SDL_FALSE;
   670         }
   671         if (state->verbose & VERBOSE_VIDEO) {
   672             fprintf(stderr, "Video driver: %s\n",
   673                     SDL_GetCurrentVideoDriver());
   674         }
   675 
   676         /* Upload GL settings */
   677         SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size);
   678         SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size);
   679         SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size);
   680         SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size);
   681         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer);
   682         SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size);
   683         SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size);
   684         SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size);
   685         SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size);
   686         SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size);
   687         SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size);
   688         SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size);
   689         SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo);
   690         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers);
   691         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples);
   692         if (state->gl_accelerated >= 0) {
   693             SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
   694                                 state->gl_accelerated);
   695         }
   696         SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing);
   697         if (state->gl_major_version) {
   698             SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version);
   699             SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version);
   700         }
   701         if (state->gl_debug) {
   702             SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
   703         }
   704         if (state->gl_profile_mask) {
   705             SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, state->gl_profile_mask);
   706         }
   707 
   708         if (state->verbose & VERBOSE_MODES) {
   709             SDL_Rect bounds;
   710             SDL_DisplayMode mode;
   711             int bpp;
   712             Uint32 Rmask, Gmask, Bmask, Amask;
   713 #if SDL_VIDEO_DRIVER_WINDOWS
   714 			int adapterIndex = 0;
   715 			int outputIndex = 0;
   716 #endif
   717             n = SDL_GetNumVideoDisplays();
   718             fprintf(stderr, "Number of displays: %d\n", n);
   719             for (i = 0; i < n; ++i) {
   720                 fprintf(stderr, "Display %d: %s\n", i, SDL_GetDisplayName(i));
   721 
   722                 SDL_zero(bounds);
   723                 SDL_GetDisplayBounds(i, &bounds);
   724                 fprintf(stderr, "Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y);
   725 
   726                 SDL_GetDesktopDisplayMode(i, &mode);
   727                 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask,
   728                                            &Bmask, &Amask);
   729                 fprintf(stderr,
   730                         "  Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
   731                         mode.w, mode.h, mode.refresh_rate, bpp,
   732                         SDL_GetPixelFormatName(mode.format));
   733                 if (Rmask || Gmask || Bmask) {
   734                     fprintf(stderr, "      Red Mask   = 0x%.8x\n", Rmask);
   735                     fprintf(stderr, "      Green Mask = 0x%.8x\n", Gmask);
   736                     fprintf(stderr, "      Blue Mask  = 0x%.8x\n", Bmask);
   737                     if (Amask)
   738                         fprintf(stderr, "      Alpha Mask = 0x%.8x\n", Amask);
   739                 }
   740 
   741                 /* Print available fullscreen video modes */
   742                 m = SDL_GetNumDisplayModes(i);
   743                 if (m == 0) {
   744                     fprintf(stderr, "No available fullscreen video modes\n");
   745                 } else {
   746                     fprintf(stderr, "  Fullscreen video modes:\n");
   747                     for (j = 0; j < m; ++j) {
   748                         SDL_GetDisplayMode(i, j, &mode);
   749                         SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask,
   750                                                    &Gmask, &Bmask, &Amask);
   751                         fprintf(stderr,
   752                                 "    Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
   753                                 j, mode.w, mode.h, mode.refresh_rate, bpp,
   754                                 SDL_GetPixelFormatName(mode.format));
   755                         if (Rmask || Gmask || Bmask) {
   756                             fprintf(stderr, "        Red Mask   = 0x%.8x\n",
   757                                     Rmask);
   758                             fprintf(stderr, "        Green Mask = 0x%.8x\n",
   759                                     Gmask);
   760                             fprintf(stderr, "        Blue Mask  = 0x%.8x\n",
   761                                     Bmask);
   762                             if (Amask)
   763                                 fprintf(stderr,
   764                                         "        Alpha Mask = 0x%.8x\n",
   765                                         Amask);
   766                         }
   767                     }
   768                 }
   769 
   770 #if SDL_VIDEO_DRIVER_WINDOWS
   771 				/* Print the D3D9 adapter index */
   772 				adapterIndex = SDL_Direct3D9GetAdapterIndex( i );
   773 				fprintf( stderr, "D3D9 Adapter Index: %d", adapterIndex );
   774 
   775 				/* Print the DXGI adapter and output indices */
   776 				SDL_DXGIGetOutputInfo(i, &adapterIndex, &outputIndex);
   777 				fprintf( stderr, "DXGI Adapter Index: %d  Output Index: %d", adapterIndex, outputIndex );
   778 #endif
   779             }
   780         }
   781 
   782         if (state->verbose & VERBOSE_RENDER) {
   783             SDL_RendererInfo info;
   784 
   785             n = SDL_GetNumRenderDrivers();
   786             if (n == 0) {
   787                 fprintf(stderr, "No built-in render drivers\n");
   788             } else {
   789                 fprintf(stderr, "Built-in render drivers:\n");
   790                 for (i = 0; i < n; ++i) {
   791                     SDL_GetRenderDriverInfo(i, &info);
   792                     SDLTest_PrintRenderer(&info);
   793                 }
   794             }
   795         }
   796 
   797         SDL_zero(fullscreen_mode);
   798         switch (state->depth) {
   799         case 8:
   800             fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8;
   801             break;
   802         case 15:
   803             fullscreen_mode.format = SDL_PIXELFORMAT_RGB555;
   804             break;
   805         case 16:
   806             fullscreen_mode.format = SDL_PIXELFORMAT_RGB565;
   807             break;
   808         case 24:
   809             fullscreen_mode.format = SDL_PIXELFORMAT_RGB24;
   810             break;
   811         default:
   812             fullscreen_mode.format = SDL_PIXELFORMAT_RGB888;
   813             break;
   814         }
   815         fullscreen_mode.refresh_rate = state->refresh_rate;
   816 
   817         state->windows =
   818             (SDL_Window **) SDL_malloc(state->num_windows *
   819                                         sizeof(*state->windows));
   820         state->renderers =
   821             (SDL_Renderer **) SDL_malloc(state->num_windows *
   822                                         sizeof(*state->renderers));
   823         state->targets =
   824             (SDL_Texture **) SDL_malloc(state->num_windows *
   825                                         sizeof(*state->targets));
   826         if (!state->windows || !state->renderers) {
   827             fprintf(stderr, "Out of memory!\n");
   828             return SDL_FALSE;
   829         }
   830         for (i = 0; i < state->num_windows; ++i) {
   831             char title[1024];
   832 
   833             if (state->num_windows > 1) {
   834                 SDL_snprintf(title, SDL_arraysize(title), "%s %d",
   835                              state->window_title, i + 1);
   836             } else {
   837                 SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
   838             }
   839             state->windows[i] =
   840                 SDL_CreateWindow(title, state->window_x, state->window_y,
   841                                  state->window_w, state->window_h,
   842                                  state->window_flags);
   843             if (!state->windows[i]) {
   844                 fprintf(stderr, "Couldn't create window: %s\n",
   845                         SDL_GetError());
   846                 return SDL_FALSE;
   847             }
   848             if (state->window_minW || state->window_minH) {
   849                 SDL_SetWindowMinimumSize(state->windows[i], state->window_minW, state->window_minH);
   850             }
   851             if (state->window_maxW || state->window_maxH) {
   852                 SDL_SetWindowMaximumSize(state->windows[i], state->window_maxW, state->window_maxH);
   853             }
   854             SDL_GetWindowSize(state->windows[i], &w, &h);
   855             if (!(state->window_flags & SDL_WINDOW_RESIZABLE) &&
   856                 (w != state->window_w || h != state->window_h)) {
   857                 printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h);
   858                 state->window_w = w;
   859                 state->window_h = h;
   860             }
   861             if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) {
   862                 fprintf(stderr, "Can't set up fullscreen display mode: %s\n",
   863                         SDL_GetError());
   864                 return SDL_FALSE;
   865             }
   866 
   867             if (state->window_icon) {
   868                 SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon);
   869                 if (icon) {
   870                     SDL_SetWindowIcon(state->windows[i], icon);
   871                     SDL_FreeSurface(icon);
   872                 }
   873             }
   874 
   875             SDL_ShowWindow(state->windows[i]);
   876 
   877             state->renderers[i] = NULL;
   878             state->targets[i] = NULL;
   879 
   880             if (!state->skip_renderer
   881                 && (state->renderdriver
   882                     || !(state->window_flags & SDL_WINDOW_OPENGL))) {
   883                 m = -1;
   884                 if (state->renderdriver) {
   885                     SDL_RendererInfo info;
   886                     n = SDL_GetNumRenderDrivers();
   887                     for (j = 0; j < n; ++j) {
   888                         SDL_GetRenderDriverInfo(j, &info);
   889                         if (SDL_strcasecmp(info.name, state->renderdriver) ==
   890                             0) {
   891                             m = j;
   892                             break;
   893                         }
   894                     }
   895                     if (m == -1) {
   896                         fprintf(stderr,
   897                                 "Couldn't find render driver named %s",
   898                                 state->renderdriver);
   899                         return SDL_FALSE;
   900                     }
   901                 }
   902                 state->renderers[i] = SDL_CreateRenderer(state->windows[i],
   903                                             m, state->render_flags);
   904                 if (!state->renderers[i]) {
   905                     fprintf(stderr, "Couldn't create renderer: %s\n",
   906                             SDL_GetError());
   907                     return SDL_FALSE;
   908                 }
   909                 if (state->logical_w && state->logical_h) {
   910                     SDL_RenderSetLogicalSize(state->renderers[i], state->logical_w, state->logical_h);
   911                 } else if (state->scale) {
   912                     SDL_RenderSetScale(state->renderers[i], state->scale, state->scale);
   913                 }
   914                 if (state->verbose & VERBOSE_RENDER) {
   915                     SDL_RendererInfo info;
   916 
   917                     fprintf(stderr, "Current renderer:\n");
   918                     SDL_GetRendererInfo(state->renderers[i], &info);
   919                     SDLTest_PrintRenderer(&info);
   920                 }
   921             }
   922         }
   923     }
   924 
   925     if (state->flags & SDL_INIT_AUDIO) {
   926         if (state->verbose & VERBOSE_AUDIO) {
   927             n = SDL_GetNumAudioDrivers();
   928             if (n == 0) {
   929                 fprintf(stderr, "No built-in audio drivers\n");
   930             } else {
   931                 fprintf(stderr, "Built-in audio drivers:");
   932                 for (i = 0; i < n; ++i) {
   933                     if (i > 0) {
   934                         fprintf(stderr, ",");
   935                     }
   936                     fprintf(stderr, " %s", SDL_GetAudioDriver(i));
   937                 }
   938                 fprintf(stderr, "\n");
   939             }
   940         }
   941         if (SDL_AudioInit(state->audiodriver) < 0) {
   942             fprintf(stderr, "Couldn't initialize audio driver: %s\n",
   943                     SDL_GetError());
   944             return SDL_FALSE;
   945         }
   946         if (state->verbose & VERBOSE_VIDEO) {
   947             fprintf(stderr, "Audio driver: %s\n",
   948                     SDL_GetCurrentAudioDriver());
   949         }
   950 
   951         if (SDL_OpenAudio(&state->audiospec, NULL) < 0) {
   952             fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
   953             return SDL_FALSE;
   954         }
   955     }
   956 
   957     return SDL_TRUE;
   958 }
   959 
   960 static const char *
   961 ControllerAxisName(const SDL_GameControllerAxis axis)
   962 {
   963     switch (axis)
   964     {
   965 #define AXIS_CASE(ax) case SDL_CONTROLLER_AXIS_##ax: return #ax
   966         AXIS_CASE(INVALID);
   967         AXIS_CASE(LEFTX);
   968         AXIS_CASE(LEFTY);
   969         AXIS_CASE(RIGHTX);
   970         AXIS_CASE(RIGHTY);
   971         AXIS_CASE(TRIGGERLEFT);
   972         AXIS_CASE(TRIGGERRIGHT);
   973 #undef AXIS_CASE
   974 default: return "???";
   975     }
   976 }
   977 
   978 static const char *
   979 ControllerButtonName(const SDL_GameControllerButton button)
   980 {
   981     switch (button)
   982     {
   983 #define BUTTON_CASE(btn) case SDL_CONTROLLER_BUTTON_##btn: return #btn
   984         BUTTON_CASE(INVALID);
   985         BUTTON_CASE(A);
   986         BUTTON_CASE(B);
   987         BUTTON_CASE(X);
   988         BUTTON_CASE(Y);
   989         BUTTON_CASE(BACK);
   990         BUTTON_CASE(GUIDE);
   991         BUTTON_CASE(START);
   992         BUTTON_CASE(LEFTSTICK);
   993         BUTTON_CASE(RIGHTSTICK);
   994         BUTTON_CASE(LEFTSHOULDER);
   995         BUTTON_CASE(RIGHTSHOULDER);
   996         BUTTON_CASE(DPAD_UP);
   997         BUTTON_CASE(DPAD_DOWN);
   998         BUTTON_CASE(DPAD_LEFT);
   999         BUTTON_CASE(DPAD_RIGHT);
  1000 #undef BUTTON_CASE
  1001 default: return "???";
  1002     }
  1003 }
  1004 
  1005 static void
  1006 SDLTest_PrintEvent(SDL_Event * event)
  1007 {
  1008     if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) {
  1009         /* Mouse and finger motion are really spammy */
  1010         return;
  1011     }
  1012 
  1013     switch (event->type) {
  1014     case SDL_WINDOWEVENT:
  1015         switch (event->window.event) {
  1016         case SDL_WINDOWEVENT_SHOWN:
  1017             SDL_Log("SDL EVENT: Window %d shown", event->window.windowID);
  1018             break;
  1019         case SDL_WINDOWEVENT_HIDDEN:
  1020             SDL_Log("SDL EVENT: Window %d hidden", event->window.windowID);
  1021             break;
  1022         case SDL_WINDOWEVENT_EXPOSED:
  1023             SDL_Log("SDL EVENT: Window %d exposed", event->window.windowID);
  1024             break;
  1025         case SDL_WINDOWEVENT_MOVED:
  1026             SDL_Log("SDL EVENT: Window %d moved to %d,%d",
  1027                     event->window.windowID, event->window.data1,
  1028                     event->window.data2);
  1029             break;
  1030         case SDL_WINDOWEVENT_RESIZED:
  1031             SDL_Log("SDL EVENT: Window %d resized to %dx%d",
  1032                     event->window.windowID, event->window.data1,
  1033                     event->window.data2);
  1034             break;
  1035         case SDL_WINDOWEVENT_SIZE_CHANGED:
  1036             SDL_Log("SDL EVENT: Window %d changed size to %dx%d",
  1037                     event->window.windowID, event->window.data1,
  1038                     event->window.data2);
  1039             break;
  1040         case SDL_WINDOWEVENT_MINIMIZED:
  1041             SDL_Log("SDL EVENT: Window %d minimized", event->window.windowID);
  1042             break;
  1043         case SDL_WINDOWEVENT_MAXIMIZED:
  1044             SDL_Log("SDL EVENT: Window %d maximized", event->window.windowID);
  1045             break;
  1046         case SDL_WINDOWEVENT_RESTORED:
  1047             SDL_Log("SDL EVENT: Window %d restored", event->window.windowID);
  1048             break;
  1049         case SDL_WINDOWEVENT_ENTER:
  1050             SDL_Log("SDL EVENT: Mouse entered window %d",
  1051                     event->window.windowID);
  1052             break;
  1053         case SDL_WINDOWEVENT_LEAVE:
  1054             SDL_Log("SDL EVENT: Mouse left window %d", event->window.windowID);
  1055             break;
  1056         case SDL_WINDOWEVENT_FOCUS_GAINED:
  1057             SDL_Log("SDL EVENT: Window %d gained keyboard focus",
  1058                     event->window.windowID);
  1059             break;
  1060         case SDL_WINDOWEVENT_FOCUS_LOST:
  1061             SDL_Log("SDL EVENT: Window %d lost keyboard focus",
  1062                     event->window.windowID);
  1063             break;
  1064         case SDL_WINDOWEVENT_CLOSE:
  1065             SDL_Log("SDL EVENT: Window %d closed", event->window.windowID);
  1066             break;
  1067         case SDL_WINDOWEVENT_TAKE_FOCUS:
  1068             SDL_Log("SDL EVENT: Window %d take focus", event->window.windowID);
  1069             break;
  1070         case SDL_WINDOWEVENT_HIT_TEST:
  1071             SDL_Log("SDL EVENT: Window %d hit test", event->window.windowID);
  1072             break;
  1073         default:
  1074             SDL_Log("SDL EVENT: Window %d got unknown event %d",
  1075                     event->window.windowID, event->window.event);
  1076             break;
  1077         }
  1078         break;
  1079     case SDL_KEYDOWN:
  1080         SDL_Log("SDL EVENT: Keyboard: key pressed  in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
  1081                 event->key.windowID,
  1082                 event->key.keysym.scancode,
  1083                 SDL_GetScancodeName(event->key.keysym.scancode),
  1084                 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
  1085         break;
  1086     case SDL_KEYUP:
  1087         SDL_Log("SDL EVENT: Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
  1088                 event->key.windowID,
  1089                 event->key.keysym.scancode,
  1090                 SDL_GetScancodeName(event->key.keysym.scancode),
  1091                 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
  1092         break;
  1093     case SDL_TEXTINPUT:
  1094         SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %d",
  1095                 event->text.text, event->text.windowID);
  1096         break;
  1097     case SDL_MOUSEMOTION:
  1098         SDL_Log("SDL EVENT: Mouse: moved to %d,%d (%d,%d) in window %d",
  1099                 event->motion.x, event->motion.y,
  1100                 event->motion.xrel, event->motion.yrel,
  1101                 event->motion.windowID);
  1102         break;
  1103     case SDL_MOUSEBUTTONDOWN:
  1104         SDL_Log("SDL EVENT: Mouse: button %d pressed at %d,%d with click count %d in window %d",
  1105                 event->button.button, event->button.x, event->button.y, event->button.clicks,
  1106                 event->button.windowID);
  1107         break;
  1108     case SDL_MOUSEBUTTONUP:
  1109         SDL_Log("SDL EVENT: Mouse: button %d released at %d,%d with click count %d in window %d",
  1110                 event->button.button, event->button.x, event->button.y, event->button.clicks,
  1111                 event->button.windowID);
  1112         break;
  1113     case SDL_MOUSEWHEEL:
  1114         SDL_Log("SDL EVENT: Mouse: wheel scrolled %d in x and %d in y (reversed: %d) in window %d",
  1115                 event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID);
  1116         break;
  1117     case SDL_JOYDEVICEADDED:
  1118         SDL_Log("SDL EVENT: Joystick index %d attached",
  1119             event->jdevice.which);
  1120         break;
  1121     case SDL_JOYDEVICEREMOVED:
  1122         SDL_Log("SDL EVENT: Joystick %d removed",
  1123             event->jdevice.which);
  1124         break;
  1125     case SDL_JOYBALLMOTION:
  1126         SDL_Log("SDL EVENT: Joystick %d: ball %d moved by %d,%d",
  1127                 event->jball.which, event->jball.ball, event->jball.xrel,
  1128                 event->jball.yrel);
  1129         break;
  1130     case SDL_JOYHATMOTION:
  1131         {
  1132             const char *position = "UNKNOWN";
  1133             switch (event->jhat.value) {
  1134             case SDL_HAT_CENTERED:
  1135                 position = "CENTER";
  1136                 break;
  1137             case SDL_HAT_UP:
  1138                 position = "UP";
  1139                 break;
  1140             case SDL_HAT_RIGHTUP:
  1141                 position = "RIGHTUP";
  1142                 break;
  1143             case SDL_HAT_RIGHT:
  1144                 position = "RIGHT";
  1145                 break;
  1146             case SDL_HAT_RIGHTDOWN:
  1147                 position = "RIGHTDOWN";
  1148                 break;
  1149             case SDL_HAT_DOWN:
  1150                 position = "DOWN";
  1151                 break;
  1152             case SDL_HAT_LEFTDOWN:
  1153                 position = "LEFTDOWN";
  1154                 break;
  1155             case SDL_HAT_LEFT:
  1156                 position = "LEFT";
  1157                 break;
  1158             case SDL_HAT_LEFTUP:
  1159                 position = "LEFTUP";
  1160                 break;
  1161             }
  1162             SDL_Log("SDL EVENT: Joystick %d: hat %d moved to %s", event->jhat.which,
  1163                 event->jhat.hat, position);
  1164         }
  1165         break;
  1166     case SDL_JOYBUTTONDOWN:
  1167         SDL_Log("SDL EVENT: Joystick %d: button %d pressed",
  1168                 event->jbutton.which, event->jbutton.button);
  1169         break;
  1170     case SDL_JOYBUTTONUP:
  1171         SDL_Log("SDL EVENT: Joystick %d: button %d released",
  1172                 event->jbutton.which, event->jbutton.button);
  1173         break;
  1174     case SDL_CONTROLLERDEVICEADDED:
  1175         SDL_Log("SDL EVENT: Controller index %d attached",
  1176             event->cdevice.which);
  1177         break;
  1178     case SDL_CONTROLLERDEVICEREMOVED:
  1179         SDL_Log("SDL EVENT: Controller %d removed",
  1180             event->cdevice.which);
  1181         break;
  1182     case SDL_CONTROLLERAXISMOTION:
  1183         SDL_Log("SDL EVENT: Controller %d axis %d ('%s') value: %d",
  1184             event->caxis.which,
  1185             event->caxis.axis,
  1186             ControllerAxisName((SDL_GameControllerAxis)event->caxis.axis),
  1187             event->caxis.value);
  1188         break;
  1189     case SDL_CONTROLLERBUTTONDOWN:
  1190         SDL_Log("SDL EVENT: Controller %d button %d ('%s') down",
  1191             event->cbutton.which, event->cbutton.button,
  1192             ControllerButtonName((SDL_GameControllerButton)event->cbutton.button));
  1193         break;
  1194     case SDL_CONTROLLERBUTTONUP:
  1195         SDL_Log("SDL EVENT: Controller %d button %d ('%s') up",
  1196             event->cbutton.which, event->cbutton.button,
  1197             ControllerButtonName((SDL_GameControllerButton)event->cbutton.button));
  1198         break;
  1199     case SDL_CLIPBOARDUPDATE:
  1200         SDL_Log("SDL EVENT: Clipboard updated");
  1201         break;
  1202 
  1203     case SDL_FINGERDOWN:
  1204     case SDL_FINGERUP:
  1205         SDL_Log("SDL EVENT: Finger: %s touch=%ld, finger=%ld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
  1206                 (event->type == SDL_FINGERDOWN) ? "down" : "up",
  1207                 (long) event->tfinger.touchId,
  1208                 (long) event->tfinger.fingerId,
  1209                 event->tfinger.x, event->tfinger.y,
  1210                 event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
  1211         break;
  1212     case SDL_DOLLARGESTURE:
  1213         SDL_Log("SDL_EVENT: Dollar gesture detect: %ld", (long) event->dgesture.gestureId);
  1214         break;
  1215     case SDL_DOLLARRECORD:
  1216         SDL_Log("SDL_EVENT: Dollar gesture record: %ld", (long) event->dgesture.gestureId);
  1217         break;
  1218     case SDL_MULTIGESTURE:
  1219         SDL_Log("SDL_EVENT: Multi gesture fingers: %d", event->mgesture.numFingers);
  1220         break;
  1221 
  1222     case SDL_RENDER_DEVICE_RESET:
  1223         SDL_Log("SDL EVENT: render device reset");
  1224         break;
  1225     case SDL_RENDER_TARGETS_RESET:
  1226         SDL_Log("SDL EVENT: render targets reset");
  1227         break;
  1228 
  1229     case SDL_QUIT:
  1230         SDL_Log("SDL EVENT: Quit requested");
  1231         break;
  1232     case SDL_USEREVENT:
  1233         SDL_Log("SDL EVENT: User event %d", event->user.code);
  1234         break;
  1235     default:
  1236         SDL_Log("Unknown event %04x", event->type);
  1237         break;
  1238     }
  1239 }
  1240 
  1241 static void
  1242 SDLTest_ScreenShot(SDL_Renderer *renderer)
  1243 {
  1244     SDL_Rect viewport;
  1245     SDL_Surface *surface;
  1246 
  1247     if (!renderer) {
  1248         return;
  1249     }
  1250 
  1251     SDL_RenderGetViewport(renderer, &viewport);
  1252     surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24,
  1253 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  1254                     0x00FF0000, 0x0000FF00, 0x000000FF,
  1255 #else
  1256                     0x000000FF, 0x0000FF00, 0x00FF0000,
  1257 #endif
  1258                     0x00000000);
  1259     if (!surface) {
  1260         fprintf(stderr, "Couldn't create surface: %s\n", SDL_GetError());
  1261         return;
  1262     }
  1263 
  1264     if (SDL_RenderReadPixels(renderer, NULL, surface->format->format,
  1265                              surface->pixels, surface->pitch) < 0) {
  1266         fprintf(stderr, "Couldn't read screen: %s\n", SDL_GetError());
  1267         SDL_free(surface);
  1268         return;
  1269     }
  1270 
  1271     if (SDL_SaveBMP(surface, "screenshot.bmp") < 0) {
  1272         fprintf(stderr, "Couldn't save screenshot.bmp: %s\n", SDL_GetError());
  1273         SDL_free(surface);
  1274         return;
  1275     }
  1276 }
  1277 
  1278 static void
  1279 FullscreenTo(int index, int windowId)
  1280 {
  1281     Uint32 flags;
  1282     struct SDL_Rect rect = { 0, 0, 0, 0 };
  1283     SDL_Window *window = SDL_GetWindowFromID(windowId);
  1284     if (!window) {
  1285         return;
  1286     }
  1287 
  1288     SDL_GetDisplayBounds( index, &rect );
  1289 
  1290     flags = SDL_GetWindowFlags(window);
  1291     if (flags & SDL_WINDOW_FULLSCREEN) {
  1292         SDL_SetWindowFullscreen( window, SDL_FALSE );
  1293         SDL_Delay( 15 );
  1294     }
  1295 
  1296     SDL_SetWindowPosition( window, rect.x, rect.y );
  1297     SDL_SetWindowFullscreen( window, SDL_TRUE );
  1298 }
  1299 
  1300 void
  1301 SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
  1302 {
  1303     int i;
  1304     static SDL_MouseMotionEvent lastEvent;
  1305 
  1306     if (state->verbose & VERBOSE_EVENT) {
  1307         SDLTest_PrintEvent(event);
  1308     }
  1309 
  1310     switch (event->type) {
  1311     case SDL_WINDOWEVENT:
  1312         switch (event->window.event) {
  1313         case SDL_WINDOWEVENT_CLOSE:
  1314             {
  1315                 SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
  1316                 if (window) {
  1317                     for (i = 0; i < state->num_windows; ++i) {
  1318                         if (window == state->windows[i]) {
  1319                             if (state->targets[i]) {
  1320                                 SDL_DestroyTexture(state->targets[i]);
  1321                                 state->targets[i] = NULL;
  1322                             }
  1323                             if (state->renderers[i]) {
  1324                                 SDL_DestroyRenderer(state->renderers[i]);
  1325                                 state->renderers[i] = NULL;
  1326                             }
  1327                             SDL_DestroyWindow(state->windows[i]);
  1328                             state->windows[i] = NULL;
  1329                             break;
  1330                         }
  1331                     }
  1332                 }
  1333             }
  1334             break;
  1335         }
  1336         break;
  1337     case SDL_KEYDOWN: {
  1338         SDL_bool withControl = !!(event->key.keysym.mod & KMOD_CTRL);
  1339         SDL_bool withShift = !!(event->key.keysym.mod & KMOD_SHIFT);
  1340         SDL_bool withAlt = !!(event->key.keysym.mod & KMOD_ALT);
  1341 
  1342         switch (event->key.keysym.sym) {
  1343             /* Add hotkeys here */
  1344         case SDLK_PRINTSCREEN: {
  1345                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1346                 if (window) {
  1347                     for (i = 0; i < state->num_windows; ++i) {
  1348                         if (window == state->windows[i]) {
  1349                             SDLTest_ScreenShot(state->renderers[i]);
  1350                         }
  1351                     }
  1352                 }
  1353             }
  1354             break;
  1355         case SDLK_EQUALS:
  1356             if (withControl) {
  1357                 /* Ctrl-+ double the size of the window */
  1358                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1359                 if (window) {
  1360                     int w, h;
  1361                     SDL_GetWindowSize(window, &w, &h);
  1362                     SDL_SetWindowSize(window, w*2, h*2);
  1363                 }
  1364             }
  1365             break;
  1366         case SDLK_MINUS:
  1367             if (withControl) {
  1368                 /* Ctrl-- half the size of the window */
  1369                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1370                 if (window) {
  1371                     int w, h;
  1372                     SDL_GetWindowSize(window, &w, &h);
  1373                     SDL_SetWindowSize(window, w/2, h/2);
  1374                 }
  1375             }
  1376             break;
  1377         case SDLK_o:
  1378             if (withControl) {
  1379                 /* Ctrl-O (or Ctrl-Shift-O) changes window opacity. */
  1380                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1381                 if (window) {
  1382                     float opacity;
  1383                     if (SDL_GetWindowOpacity(window, &opacity) == 0) {
  1384                         if (withShift) {
  1385                             opacity += 0.20f;
  1386                         } else {
  1387                             opacity -= 0.20f;
  1388                         }
  1389                         SDL_SetWindowOpacity(window, opacity);
  1390                     }
  1391                 }
  1392             }
  1393             break;
  1394 
  1395         case SDLK_c:
  1396             if (withControl) {
  1397                 /* Ctrl-C copy awesome text! */
  1398                 SDL_SetClipboardText("SDL rocks!\nYou know it!");
  1399                 printf("Copied text to clipboard\n");
  1400             }
  1401             if (withAlt) {
  1402                 /* Alt-C toggle a render clip rectangle */
  1403                 for (i = 0; i < state->num_windows; ++i) {
  1404                     int w, h;
  1405                     if (state->renderers[i]) {
  1406                         SDL_Rect clip;
  1407                         SDL_GetWindowSize(state->windows[i], &w, &h);
  1408                         SDL_RenderGetClipRect(state->renderers[i], &clip);
  1409                         if (SDL_RectEmpty(&clip)) {
  1410                             clip.x = w/4;
  1411                             clip.y = h/4;
  1412                             clip.w = w/2;
  1413                             clip.h = h/2;
  1414                             SDL_RenderSetClipRect(state->renderers[i], &clip);
  1415                         } else {
  1416                             SDL_RenderSetClipRect(state->renderers[i], NULL);
  1417                         }
  1418                     }
  1419                 }
  1420             }
  1421             if (withShift) {
  1422                 SDL_Window *current_win = SDL_GetKeyboardFocus();
  1423                 if (current_win) {
  1424                     const SDL_bool shouldCapture = (SDL_GetWindowFlags(current_win) & SDL_WINDOW_MOUSE_CAPTURE) == 0;
  1425                     const int rc = SDL_CaptureMouse(shouldCapture);
  1426                     SDL_Log("%sapturing mouse %s!\n", shouldCapture ? "C" : "Unc", (rc == 0) ? "succeeded" : "failed");
  1427                 }
  1428             }
  1429             break;
  1430         case SDLK_v:
  1431             if (withControl) {
  1432                 /* Ctrl-V paste awesome text! */
  1433                 char *text = SDL_GetClipboardText();
  1434                 if (*text) {
  1435                     printf("Clipboard: %s\n", text);
  1436                 } else {
  1437                     printf("Clipboard is empty\n");
  1438                 }
  1439                 SDL_free(text);
  1440             }
  1441             break;
  1442         case SDLK_g:
  1443             if (withControl) {
  1444                 /* Ctrl-G toggle grab */
  1445                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1446                 if (window) {
  1447                     SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window) ? SDL_TRUE : SDL_FALSE);
  1448                 }
  1449             }
  1450             break;
  1451         case SDLK_m:
  1452             if (withControl) {
  1453                 /* Ctrl-M maximize */
  1454                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1455                 if (window) {
  1456                     Uint32 flags = SDL_GetWindowFlags(window);
  1457                     if (flags & SDL_WINDOW_MAXIMIZED) {
  1458                         SDL_RestoreWindow(window);
  1459                     } else {
  1460                         SDL_MaximizeWindow(window);
  1461                     }
  1462                 }
  1463             }
  1464             break;
  1465         case SDLK_r:
  1466             if (withControl) {
  1467                 /* Ctrl-R toggle mouse relative mode */
  1468                 SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode() ? SDL_TRUE : SDL_FALSE);
  1469             }
  1470             break;
  1471         case SDLK_z:
  1472             if (withControl) {
  1473                 /* Ctrl-Z minimize */
  1474                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1475                 if (window) {
  1476                     SDL_MinimizeWindow(window);
  1477                 }
  1478             }
  1479             break;
  1480         case SDLK_RETURN:
  1481             if (withControl) {
  1482                 /* Ctrl-Enter toggle fullscreen */
  1483                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1484                 if (window) {
  1485                     Uint32 flags = SDL_GetWindowFlags(window);
  1486                     if (flags & SDL_WINDOW_FULLSCREEN) {
  1487                         SDL_SetWindowFullscreen(window, SDL_FALSE);
  1488                     } else {
  1489                         SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
  1490                     }
  1491                 }
  1492             } else if (withAlt) {
  1493                 /* Alt-Enter toggle fullscreen desktop */
  1494                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1495                 if (window) {
  1496                     Uint32 flags = SDL_GetWindowFlags(window);
  1497                     if (flags & SDL_WINDOW_FULLSCREEN) {
  1498                         SDL_SetWindowFullscreen(window, SDL_FALSE);
  1499                     } else {
  1500                         SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
  1501                     }
  1502                 }
  1503             } else if (withShift) {
  1504                 /* Shift-Enter toggle fullscreen desktop / fullscreen */
  1505                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1506                 if (window) {
  1507                     Uint32 flags = SDL_GetWindowFlags(window);
  1508                     if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
  1509                         SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
  1510                     } else {
  1511                         SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
  1512                     }
  1513                 }
  1514             }
  1515 
  1516             break;
  1517         case SDLK_b:
  1518             if (withControl) {
  1519                 /* Ctrl-B toggle window border */
  1520                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1521                 if (window) {
  1522                     const Uint32 flags = SDL_GetWindowFlags(window);
  1523                     const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0) ? SDL_TRUE : SDL_FALSE;
  1524                     SDL_SetWindowBordered(window, b);
  1525                 }
  1526             }
  1527             break;
  1528         case SDLK_a:
  1529             if (withControl) {
  1530                 /* Ctrl-A reports absolute mouse position. */
  1531                 int x, y;
  1532                 const Uint32 mask = SDL_GetGlobalMouseState(&x, &y);
  1533                 SDL_Log("ABSOLUTE MOUSE: (%d, %d)%s%s%s%s%s\n", x, y,
  1534                         (mask & SDL_BUTTON_LMASK) ? " [LBUTTON]" : "",
  1535                         (mask & SDL_BUTTON_MMASK) ? " [MBUTTON]" : "",
  1536                         (mask & SDL_BUTTON_RMASK) ? " [RBUTTON]" : "",
  1537                         (mask & SDL_BUTTON_X1MASK) ? " [X2BUTTON]" : "",
  1538                         (mask & SDL_BUTTON_X2MASK) ? " [X2BUTTON]" : "");
  1539             }
  1540             break;
  1541         case SDLK_0:
  1542             if (withControl) {
  1543                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1544                 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Test Message", "You're awesome!", window);
  1545             }
  1546             break;
  1547         case SDLK_1:
  1548             if (withControl) {
  1549                 FullscreenTo(0, event->key.windowID);
  1550             }
  1551             break;
  1552         case SDLK_2:
  1553             if (withControl) {
  1554                 FullscreenTo(1, event->key.windowID);
  1555             }
  1556             break;
  1557         case SDLK_ESCAPE:
  1558             *done = 1;
  1559             break;
  1560         case SDLK_SPACE:
  1561         {
  1562             char message[256];
  1563             SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1564 
  1565             SDL_snprintf(message, sizeof(message), "(%i, %i), rel (%i, %i)\n", lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel);
  1566             SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Last mouse position", message, window);
  1567             break;
  1568         }
  1569         default:
  1570             break;
  1571         }
  1572         break;
  1573     }
  1574     case SDL_QUIT:
  1575         *done = 1;
  1576         break;
  1577     case SDL_MOUSEMOTION:
  1578         lastEvent = event->motion;
  1579         break;
  1580     }
  1581 }
  1582 
  1583 void
  1584 SDLTest_CommonQuit(SDLTest_CommonState * state)
  1585 {
  1586     int i;
  1587 
  1588     SDL_free(state->windows);
  1589     if (state->targets) {
  1590         for (i = 0; i < state->num_windows; ++i) {
  1591             if (state->targets[i]) {
  1592                 SDL_DestroyTexture(state->targets[i]);
  1593             }
  1594         }
  1595         SDL_free(state->targets);
  1596     }
  1597     if (state->renderers) {
  1598         for (i = 0; i < state->num_windows; ++i) {
  1599             if (state->renderers[i]) {
  1600                 SDL_DestroyRenderer(state->renderers[i]);
  1601             }
  1602         }
  1603         SDL_free(state->renderers);
  1604     }
  1605     if (state->flags & SDL_INIT_VIDEO) {
  1606         SDL_VideoQuit();
  1607     }
  1608     if (state->flags & SDL_INIT_AUDIO) {
  1609         SDL_AudioQuit();
  1610     }
  1611     SDL_free(state);
  1612     SDL_Quit();
  1613 }
  1614 
  1615 /* vi: set ts=4 sw=4 expandtab: */