test/common.c
author Andreas Schiffler <aschiffler@ferzkopp.net>
Wed, 26 Dec 2012 22:26:44 -0800
changeset 6773 5ebc5a9e35b4
parent 6602 533131e24aeb
child 6783 001f59dc43be
permissions -rw-r--r--
Add surface test suite; minor improvements to render suite; refactor image saving into test lib compare function; fix for Haiku build
     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 /* A simple test program framework */
    14 
    15 #include <stdio.h>
    16 
    17 #include "common.h"
    18 
    19 #define VIDEO_USAGE \
    20 "[--video driver] [--renderer driver] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]"
    21 
    22 #define AUDIO_USAGE \
    23 "[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]"
    24 
    25 CommonState *
    26 CommonCreateState(char **argv, Uint32 flags)
    27 {
    28     CommonState *state = SDL_calloc(1, sizeof(*state));
    29     if (!state) {
    30         SDL_OutOfMemory();
    31         return NULL;
    32     }
    33 
    34     /* Initialize some defaults */
    35     state->argv = argv;
    36     state->flags = flags;
    37 #ifdef __NDS__
    38     state->window_title = "";
    39 #else
    40     state->window_title = argv[0];
    41 #endif
    42     state->window_flags = 0;
    43     state->window_x = SDL_WINDOWPOS_UNDEFINED;
    44     state->window_y = SDL_WINDOWPOS_UNDEFINED;
    45     state->window_w = DEFAULT_WINDOW_WIDTH;
    46     state->window_h = DEFAULT_WINDOW_HEIGHT;
    47     state->num_windows = 1;
    48     state->audiospec.freq = 22050;
    49     state->audiospec.format = AUDIO_S16;
    50     state->audiospec.channels = 2;
    51     state->audiospec.samples = 2048;
    52 
    53     /* Set some very sane GL defaults */
    54     state->gl_red_size = 3;
    55     state->gl_green_size = 3;
    56     state->gl_blue_size = 2;
    57     state->gl_alpha_size = 0;
    58     state->gl_buffer_size = 0;
    59     state->gl_depth_size = 16;
    60     state->gl_stencil_size = 0;
    61     state->gl_double_buffer = 1;
    62     state->gl_accum_red_size = 0;
    63     state->gl_accum_green_size = 0;
    64     state->gl_accum_blue_size = 0;
    65     state->gl_accum_alpha_size = 0;
    66     state->gl_stereo = 0;
    67     state->gl_multisamplebuffers = 0;
    68     state->gl_multisamplesamples = 0;
    69     state->gl_retained_backing = 1;
    70     state->gl_accelerated = -1;
    71 
    72     return state;
    73 }
    74 
    75 int
    76 CommonArg(CommonState * state, int index)
    77 {
    78     char **argv = state->argv;
    79 
    80 #ifdef __NDS__
    81     return 0;
    82 #endif
    83 
    84     if (SDL_strcasecmp(argv[index], "--video") == 0) {
    85         ++index;
    86         if (!argv[index]) {
    87             return -1;
    88         }
    89         state->videodriver = argv[index];
    90         return 2;
    91     }
    92     if (SDL_strcasecmp(argv[index], "--renderer") == 0) {
    93         ++index;
    94         if (!argv[index]) {
    95             return -1;
    96         }
    97         state->renderdriver = argv[index];
    98         return 2;
    99     }
   100     if (SDL_strcasecmp(argv[index], "--info") == 0) {
   101         ++index;
   102         if (!argv[index]) {
   103             return -1;
   104         }
   105         if (SDL_strcasecmp(argv[index], "all") == 0) {
   106             state->verbose |=
   107                 (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER |
   108                  VERBOSE_EVENT);
   109             return 2;
   110         }
   111         if (SDL_strcasecmp(argv[index], "video") == 0) {
   112             state->verbose |= VERBOSE_VIDEO;
   113             return 2;
   114         }
   115         if (SDL_strcasecmp(argv[index], "modes") == 0) {
   116             state->verbose |= VERBOSE_MODES;
   117             return 2;
   118         }
   119         if (SDL_strcasecmp(argv[index], "render") == 0) {
   120             state->verbose |= VERBOSE_RENDER;
   121             return 2;
   122         }
   123         if (SDL_strcasecmp(argv[index], "event") == 0) {
   124             state->verbose |= VERBOSE_EVENT;
   125             return 2;
   126         }
   127         return -1;
   128     }
   129     if (SDL_strcasecmp(argv[index], "--log") == 0) {
   130         ++index;
   131         if (!argv[index]) {
   132             return -1;
   133         }
   134         if (SDL_strcasecmp(argv[index], "all") == 0) {
   135             SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
   136             return 2;
   137         }
   138         if (SDL_strcasecmp(argv[index], "error") == 0) {
   139             SDL_LogSetPriority(SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_VERBOSE);
   140             return 2;
   141         }
   142         if (SDL_strcasecmp(argv[index], "system") == 0) {
   143             SDL_LogSetPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE);
   144             return 2;
   145         }
   146         if (SDL_strcasecmp(argv[index], "audio") == 0) {
   147             SDL_LogSetPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE);
   148             return 2;
   149         }
   150         if (SDL_strcasecmp(argv[index], "video") == 0) {
   151             SDL_LogSetPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE);
   152             return 2;
   153         }
   154         if (SDL_strcasecmp(argv[index], "render") == 0) {
   155             SDL_LogSetPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE);
   156             return 2;
   157         }
   158         if (SDL_strcasecmp(argv[index], "input") == 0) {
   159             SDL_LogSetPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE);
   160             return 2;
   161         }
   162         return -1;
   163     }
   164     if (SDL_strcasecmp(argv[index], "--display") == 0) {
   165         ++index;
   166         if (!argv[index]) {
   167             return -1;
   168         }
   169         state->display = SDL_atoi(argv[index]);
   170         if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) {
   171             state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
   172             state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
   173         }
   174         if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) {
   175             state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
   176             state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
   177         }
   178         return 2;
   179     }
   180     if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
   181         state->window_flags |= SDL_WINDOW_FULLSCREEN;
   182         state->num_windows = 1;
   183         return 1;
   184     }
   185     if (SDL_strcasecmp(argv[index], "--windows") == 0) {
   186         ++index;
   187         if (!argv[index] || !SDL_isdigit(*argv[index])) {
   188             return -1;
   189         }
   190         if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
   191             state->num_windows = SDL_atoi(argv[index]);
   192         }
   193         return 2;
   194     }
   195     if (SDL_strcasecmp(argv[index], "--title") == 0) {
   196         ++index;
   197         if (!argv[index]) {
   198             return -1;
   199         }
   200         state->window_title = argv[index];
   201         return 2;
   202     }
   203     if (SDL_strcasecmp(argv[index], "--icon") == 0) {
   204         ++index;
   205         if (!argv[index]) {
   206             return -1;
   207         }
   208         state->window_icon = argv[index];
   209         return 2;
   210     }
   211     if (SDL_strcasecmp(argv[index], "--center") == 0) {
   212         state->window_x = SDL_WINDOWPOS_CENTERED;
   213         state->window_y = SDL_WINDOWPOS_CENTERED;
   214         return 1;
   215     }
   216     if (SDL_strcasecmp(argv[index], "--position") == 0) {
   217         char *x, *y;
   218         ++index;
   219         if (!argv[index]) {
   220             return -1;
   221         }
   222         x = argv[index];
   223         y = argv[index];
   224         while (*y && *y != ',') {
   225             ++y;
   226         }
   227         if (!*y) {
   228             return -1;
   229         }
   230         *y++ = '\0';
   231         state->window_x = SDL_atoi(x);
   232         state->window_y = SDL_atoi(y);
   233         return 2;
   234     }
   235     if (SDL_strcasecmp(argv[index], "--geometry") == 0) {
   236         char *w, *h;
   237         ++index;
   238         if (!argv[index]) {
   239             return -1;
   240         }
   241         w = argv[index];
   242         h = argv[index];
   243         while (*h && *h != 'x') {
   244             ++h;
   245         }
   246         if (!*h) {
   247             return -1;
   248         }
   249         *h++ = '\0';
   250         state->window_w = SDL_atoi(w);
   251         state->window_h = SDL_atoi(h);
   252         return 2;
   253     }
   254     if (SDL_strcasecmp(argv[index], "--depth") == 0) {
   255         ++index;
   256         if (!argv[index]) {
   257             return -1;
   258         }
   259         state->depth = SDL_atoi(argv[index]);
   260         return 2;
   261     }
   262     if (SDL_strcasecmp(argv[index], "--refresh") == 0) {
   263         ++index;
   264         if (!argv[index]) {
   265             return -1;
   266         }
   267         state->refresh_rate = SDL_atoi(argv[index]);
   268         return 2;
   269     }
   270     if (SDL_strcasecmp(argv[index], "--vsync") == 0) {
   271         state->render_flags |= SDL_RENDERER_PRESENTVSYNC;
   272         return 1;
   273     }
   274     if (SDL_strcasecmp(argv[index], "--noframe") == 0) {
   275         state->window_flags |= SDL_WINDOW_BORDERLESS;
   276         return 1;
   277     }
   278     if (SDL_strcasecmp(argv[index], "--resize") == 0) {
   279         state->window_flags |= SDL_WINDOW_RESIZABLE;
   280         return 1;
   281     }
   282     if (SDL_strcasecmp(argv[index], "--minimize") == 0) {
   283         state->window_flags |= SDL_WINDOW_MINIMIZED;
   284         return 1;
   285     }
   286     if (SDL_strcasecmp(argv[index], "--maximize") == 0) {
   287         state->window_flags |= SDL_WINDOW_MAXIMIZED;
   288         return 1;
   289     }
   290     if (SDL_strcasecmp(argv[index], "--grab") == 0) {
   291         state->window_flags |= SDL_WINDOW_INPUT_GRABBED;
   292         return 1;
   293     }
   294     if (SDL_strcasecmp(argv[index], "--rate") == 0) {
   295         ++index;
   296         if (!argv[index]) {
   297             return -1;
   298         }
   299         state->audiospec.freq = SDL_atoi(argv[index]);
   300         return 2;
   301     }
   302     if (SDL_strcasecmp(argv[index], "--format") == 0) {
   303         ++index;
   304         if (!argv[index]) {
   305             return -1;
   306         }
   307         if (SDL_strcasecmp(argv[index], "U8") == 0) {
   308             state->audiospec.format = AUDIO_U8;
   309             return 2;
   310         }
   311         if (SDL_strcasecmp(argv[index], "S8") == 0) {
   312             state->audiospec.format = AUDIO_S8;
   313             return 2;
   314         }
   315         if (SDL_strcasecmp(argv[index], "U16") == 0) {
   316             state->audiospec.format = AUDIO_U16;
   317             return 2;
   318         }
   319         if (SDL_strcasecmp(argv[index], "U16LE") == 0) {
   320             state->audiospec.format = AUDIO_U16LSB;
   321             return 2;
   322         }
   323         if (SDL_strcasecmp(argv[index], "U16BE") == 0) {
   324             state->audiospec.format = AUDIO_U16MSB;
   325             return 2;
   326         }
   327         if (SDL_strcasecmp(argv[index], "S16") == 0) {
   328             state->audiospec.format = AUDIO_S16;
   329             return 2;
   330         }
   331         if (SDL_strcasecmp(argv[index], "S16LE") == 0) {
   332             state->audiospec.format = AUDIO_S16LSB;
   333             return 2;
   334         }
   335         if (SDL_strcasecmp(argv[index], "S16BE") == 0) {
   336             state->audiospec.format = AUDIO_S16MSB;
   337             return 2;
   338         }
   339         return -1;
   340     }
   341     if (SDL_strcasecmp(argv[index], "--channels") == 0) {
   342         ++index;
   343         if (!argv[index]) {
   344             return -1;
   345         }
   346         state->audiospec.channels = (Uint8) SDL_atoi(argv[index]);
   347         return 2;
   348     }
   349     if (SDL_strcasecmp(argv[index], "--samples") == 0) {
   350         ++index;
   351         if (!argv[index]) {
   352             return -1;
   353         }
   354         state->audiospec.samples = (Uint16) SDL_atoi(argv[index]);
   355         return 2;
   356     }
   357     if ((SDL_strcasecmp(argv[index], "-h") == 0)
   358         || (SDL_strcasecmp(argv[index], "--help") == 0)) {
   359         /* Print the usage message */
   360         return -1;
   361     }
   362     if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) {
   363 	/* Debug flag sent by Xcode */
   364         return 2;
   365     }
   366     return 0;
   367 }
   368 
   369 const char *
   370 CommonUsage(CommonState * state)
   371 {
   372     switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
   373     case SDL_INIT_VIDEO:
   374         return VIDEO_USAGE;
   375     case SDL_INIT_AUDIO:
   376         return AUDIO_USAGE;
   377     case (SDL_INIT_VIDEO | SDL_INIT_AUDIO):
   378         return VIDEO_USAGE " " AUDIO_USAGE;
   379     default:
   380         return "";
   381     }
   382 }
   383 
   384 static void
   385 PrintRendererFlag(Uint32 flag)
   386 {
   387     switch (flag) {
   388     case SDL_RENDERER_PRESENTVSYNC:
   389         fprintf(stderr, "PresentVSync");
   390         break;
   391     case SDL_RENDERER_ACCELERATED:
   392         fprintf(stderr, "Accelerated");
   393         break;
   394     default:
   395         fprintf(stderr, "0x%8.8x", flag);
   396         break;
   397     }
   398 }
   399 
   400 static void
   401 PrintPixelFormat(Uint32 format)
   402 {
   403     switch (format) {
   404     case SDL_PIXELFORMAT_UNKNOWN:
   405         fprintf(stderr, "Unknwon");
   406         break;
   407     case SDL_PIXELFORMAT_INDEX1LSB:
   408         fprintf(stderr, "Index1LSB");
   409         break;
   410     case SDL_PIXELFORMAT_INDEX1MSB:
   411         fprintf(stderr, "Index1MSB");
   412         break;
   413     case SDL_PIXELFORMAT_INDEX4LSB:
   414         fprintf(stderr, "Index4LSB");
   415         break;
   416     case SDL_PIXELFORMAT_INDEX4MSB:
   417         fprintf(stderr, "Index4MSB");
   418         break;
   419     case SDL_PIXELFORMAT_INDEX8:
   420         fprintf(stderr, "Index8");
   421         break;
   422     case SDL_PIXELFORMAT_RGB332:
   423         fprintf(stderr, "RGB332");
   424         break;
   425     case SDL_PIXELFORMAT_RGB444:
   426         fprintf(stderr, "RGB444");
   427         break;
   428     case SDL_PIXELFORMAT_RGB555:
   429         fprintf(stderr, "RGB555");
   430         break;
   431     case SDL_PIXELFORMAT_BGR555:
   432         fprintf(stderr, "BGR555");
   433         break;
   434     case SDL_PIXELFORMAT_ARGB4444:
   435         fprintf(stderr, "ARGB4444");
   436         break;
   437     case SDL_PIXELFORMAT_ABGR4444:
   438         fprintf(stderr, "ABGR4444");
   439         break;
   440     case SDL_PIXELFORMAT_ARGB1555:
   441         fprintf(stderr, "ARGB1555");
   442         break;
   443     case SDL_PIXELFORMAT_ABGR1555:
   444         fprintf(stderr, "ABGR1555");
   445         break;
   446     case SDL_PIXELFORMAT_RGB565:
   447         fprintf(stderr, "RGB565");
   448         break;
   449     case SDL_PIXELFORMAT_BGR565:
   450         fprintf(stderr, "BGR565");
   451         break;
   452     case SDL_PIXELFORMAT_RGB24:
   453         fprintf(stderr, "RGB24");
   454         break;
   455     case SDL_PIXELFORMAT_BGR24:
   456         fprintf(stderr, "BGR24");
   457         break;
   458     case SDL_PIXELFORMAT_RGB888:
   459         fprintf(stderr, "RGB888");
   460         break;
   461     case SDL_PIXELFORMAT_BGR888:
   462         fprintf(stderr, "BGR888");
   463         break;
   464     case SDL_PIXELFORMAT_ARGB8888:
   465         fprintf(stderr, "ARGB8888");
   466         break;
   467     case SDL_PIXELFORMAT_RGBA8888:
   468         fprintf(stderr, "RGBA8888");
   469         break;
   470     case SDL_PIXELFORMAT_ABGR8888:
   471         fprintf(stderr, "ABGR8888");
   472         break;
   473     case SDL_PIXELFORMAT_BGRA8888:
   474         fprintf(stderr, "BGRA8888");
   475         break;
   476     case SDL_PIXELFORMAT_ARGB2101010:
   477         fprintf(stderr, "ARGB2101010");
   478         break;
   479     case SDL_PIXELFORMAT_YV12:
   480         fprintf(stderr, "YV12");
   481         break;
   482     case SDL_PIXELFORMAT_IYUV:
   483         fprintf(stderr, "IYUV");
   484         break;
   485     case SDL_PIXELFORMAT_YUY2:
   486         fprintf(stderr, "YUY2");
   487         break;
   488     case SDL_PIXELFORMAT_UYVY:
   489         fprintf(stderr, "UYVY");
   490         break;
   491     case SDL_PIXELFORMAT_YVYU:
   492         fprintf(stderr, "YVYU");
   493         break;
   494     default:
   495         fprintf(stderr, "0x%8.8x", format);
   496         break;
   497     }
   498 }
   499 
   500 static void
   501 PrintRenderer(SDL_RendererInfo * info)
   502 {
   503     int i, count;
   504 
   505     fprintf(stderr, "  Renderer %s:\n", info->name);
   506 
   507     fprintf(stderr, "    Flags: 0x%8.8X", info->flags);
   508     fprintf(stderr, " (");
   509     count = 0;
   510     for (i = 0; i < sizeof(info->flags) * 8; ++i) {
   511         Uint32 flag = (1 << i);
   512         if (info->flags & flag) {
   513             if (count > 0) {
   514                 fprintf(stderr, " | ");
   515             }
   516             PrintRendererFlag(flag);
   517             ++count;
   518         }
   519     }
   520     fprintf(stderr, ")\n");
   521 
   522     fprintf(stderr, "    Texture formats (%d): ", info->num_texture_formats);
   523     for (i = 0; i < (int) info->num_texture_formats; ++i) {
   524         if (i > 0) {
   525             fprintf(stderr, ", ");
   526         }
   527         PrintPixelFormat(info->texture_formats[i]);
   528     }
   529     fprintf(stderr, "\n");
   530 
   531     if (info->max_texture_width || info->max_texture_height) {
   532         fprintf(stderr, "    Max Texture Size: %dx%d\n",
   533                 info->max_texture_width, info->max_texture_height);
   534     }
   535 }
   536 
   537 static SDL_Surface *
   538 LoadIcon(const char *file)
   539 {
   540     SDL_Surface *icon;
   541 
   542     /* Load the icon surface */
   543     icon = SDL_LoadBMP(file);
   544     if (icon == NULL) {
   545         fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
   546         return (NULL);
   547     }
   548 
   549     if (icon->format->palette) {
   550         /* Set the colorkey */
   551         SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels));
   552     }
   553 
   554     return (icon);
   555 }
   556 
   557 SDL_bool
   558 CommonInit(CommonState * state)
   559 {
   560     int i, j, m, n, w, h;
   561     SDL_DisplayMode fullscreen_mode;
   562 
   563     if (state->flags & SDL_INIT_VIDEO) {
   564         if (state->verbose & VERBOSE_VIDEO) {
   565             n = SDL_GetNumVideoDrivers();
   566             if (n == 0) {
   567                 fprintf(stderr, "No built-in video drivers\n");
   568             } else {
   569                 fprintf(stderr, "Built-in video drivers:");
   570                 for (i = 0; i < n; ++i) {
   571                     if (i > 0) {
   572                         fprintf(stderr, ",");
   573                     }
   574                     fprintf(stderr, " %s", SDL_GetVideoDriver(i));
   575                 }
   576                 fprintf(stderr, "\n");
   577             }
   578         }
   579         if (SDL_VideoInit(state->videodriver) < 0) {
   580             fprintf(stderr, "Couldn't initialize video driver: %s\n",
   581                     SDL_GetError());
   582             return SDL_FALSE;
   583         }
   584         if (state->verbose & VERBOSE_VIDEO) {
   585             fprintf(stderr, "Video driver: %s\n",
   586                     SDL_GetCurrentVideoDriver());
   587         }
   588 
   589         /* Upload GL settings */
   590         SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size);
   591         SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size);
   592         SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size);
   593         SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size);
   594         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer);
   595         SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size);
   596         SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size);
   597         SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size);
   598         SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size);
   599         SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size);
   600         SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size);
   601         SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size);
   602         SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo);
   603         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers);
   604         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples);
   605         if (state->gl_accelerated >= 0) {
   606             SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
   607                                 state->gl_accelerated);
   608         }
   609         SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing);
   610         if (state->gl_major_version) {
   611             SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version);
   612             SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version);
   613         }
   614 
   615         if (state->verbose & VERBOSE_MODES) {
   616             SDL_Rect bounds;
   617             SDL_DisplayMode mode;
   618             int bpp;
   619             Uint32 Rmask, Gmask, Bmask, Amask;
   620 
   621             n = SDL_GetNumVideoDisplays();
   622             fprintf(stderr, "Number of displays: %d\n", n);
   623             for (i = 0; i < n; ++i) {
   624                 fprintf(stderr, "Display %d:\n", i);
   625 
   626                 SDL_zero(bounds);
   627                 SDL_GetDisplayBounds(i, &bounds);
   628                 fprintf(stderr, "Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y);
   629 
   630                 SDL_GetDesktopDisplayMode(i, &mode);
   631                 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask,
   632                                            &Bmask, &Amask);
   633                 fprintf(stderr,
   634                         "  Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
   635                         mode.w, mode.h, mode.refresh_rate, bpp,
   636                         SDL_GetPixelFormatName(mode.format));
   637                 if (Rmask || Gmask || Bmask) {
   638                     fprintf(stderr, "      Red Mask   = 0x%.8x\n", Rmask);
   639                     fprintf(stderr, "      Green Mask = 0x%.8x\n", Gmask);
   640                     fprintf(stderr, "      Blue Mask  = 0x%.8x\n", Bmask);
   641                     if (Amask)
   642                         fprintf(stderr, "      Alpha Mask = 0x%.8x\n", Amask);
   643                 }
   644 
   645                 /* Print available fullscreen video modes */
   646                 m = SDL_GetNumDisplayModes(i);
   647                 if (m == 0) {
   648                     fprintf(stderr, "No available fullscreen video modes\n");
   649                 } else {
   650                     fprintf(stderr, "  Fullscreen video modes:\n");
   651                     for (j = 0; j < m; ++j) {
   652                         SDL_GetDisplayMode(i, j, &mode);
   653                         SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask,
   654                                                    &Gmask, &Bmask, &Amask);
   655                         fprintf(stderr,
   656                                 "    Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
   657                                 j, mode.w, mode.h, mode.refresh_rate, bpp,
   658                                 SDL_GetPixelFormatName(mode.format));
   659                         if (Rmask || Gmask || Bmask) {
   660                             fprintf(stderr, "        Red Mask   = 0x%.8x\n",
   661                                     Rmask);
   662                             fprintf(stderr, "        Green Mask = 0x%.8x\n",
   663                                     Gmask);
   664                             fprintf(stderr, "        Blue Mask  = 0x%.8x\n",
   665                                     Bmask);
   666                             if (Amask)
   667                                 fprintf(stderr,
   668                                         "        Alpha Mask = 0x%.8x\n",
   669                                         Amask);
   670                         }
   671                     }
   672                 }
   673             }
   674         }
   675 
   676         if (state->verbose & VERBOSE_RENDER) {
   677             SDL_RendererInfo info;
   678 
   679             n = SDL_GetNumRenderDrivers();
   680             if (n == 0) {
   681                 fprintf(stderr, "No built-in render drivers\n");
   682             } else {
   683                 fprintf(stderr, "Built-in render drivers:\n");
   684                 for (i = 0; i < n; ++i) {
   685                     SDL_GetRenderDriverInfo(i, &info);
   686                     PrintRenderer(&info);
   687                 }
   688             }
   689         }
   690 
   691         SDL_zero(fullscreen_mode);
   692         switch (state->depth) {
   693         case 8:
   694             fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8;
   695             break;
   696         case 15:
   697             fullscreen_mode.format = SDL_PIXELFORMAT_RGB555;
   698             break;
   699         case 16:
   700             fullscreen_mode.format = SDL_PIXELFORMAT_RGB565;
   701             break;
   702         case 24:
   703             fullscreen_mode.format = SDL_PIXELFORMAT_RGB24;
   704             break;
   705         default:
   706             fullscreen_mode.format = SDL_PIXELFORMAT_RGB888;
   707             break;
   708         }
   709         fullscreen_mode.refresh_rate = state->refresh_rate;
   710 
   711         state->windows =
   712             (SDL_Window **) SDL_malloc(state->num_windows *
   713                                         sizeof(*state->windows));
   714         state->renderers =
   715             (SDL_Renderer **) SDL_malloc(state->num_windows *
   716                                         sizeof(*state->renderers));
   717         if (!state->windows || !state->renderers) {
   718             fprintf(stderr, "Out of memory!\n");
   719             return SDL_FALSE;
   720         }
   721         for (i = 0; i < state->num_windows; ++i) {
   722             char title[1024];
   723 
   724             if (state->num_windows > 1) {
   725                 SDL_snprintf(title, SDL_arraysize(title), "%s %d",
   726                              state->window_title, i + 1);
   727             } else {
   728                 SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
   729             }
   730             state->windows[i] =
   731                 SDL_CreateWindow(title, state->window_x, state->window_y,
   732                                  state->window_w, state->window_h,
   733                                  state->window_flags);
   734             if (!state->windows[i]) {
   735                 fprintf(stderr, "Couldn't create window: %s\n",
   736                         SDL_GetError());
   737                 return SDL_FALSE;
   738             }
   739             SDL_GetWindowSize(state->windows[i], &w, &h);
   740             if (!(state->window_flags & SDL_WINDOW_RESIZABLE) &&
   741                 (w != state->window_w || h != state->window_h)) {
   742                 printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h);
   743                 state->window_w = w;
   744                 state->window_h = h;
   745             }
   746             if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) {
   747                 fprintf(stderr, "Can't set up fullscreen display mode: %s\n",
   748                         SDL_GetError());
   749                 return SDL_FALSE;
   750             }
   751 
   752             if (state->window_icon) {
   753                 SDL_Surface *icon = LoadIcon(state->window_icon);
   754                 if (icon) {
   755                     SDL_SetWindowIcon(state->windows[i], icon);
   756                     SDL_FreeSurface(icon);
   757                 }
   758             }
   759 
   760             SDL_ShowWindow(state->windows[i]);
   761 
   762             state->renderers[i] = NULL;
   763 
   764             if (!state->skip_renderer
   765                 && (state->renderdriver
   766                     || !(state->window_flags & SDL_WINDOW_OPENGL))) {
   767                 m = -1;
   768                 if (state->renderdriver) {
   769                     SDL_RendererInfo info;
   770                     n = SDL_GetNumRenderDrivers();
   771                     for (j = 0; j < n; ++j) {
   772                         SDL_GetRenderDriverInfo(j, &info);
   773                         if (SDL_strcasecmp(info.name, state->renderdriver) ==
   774                             0) {
   775                             m = j;
   776                             break;
   777                         }
   778                     }
   779                     if (m == n) {
   780                         fprintf(stderr,
   781                                 "Couldn't find render driver named %s",
   782                                 state->renderdriver);
   783                         return SDL_FALSE;
   784                     }
   785                 }
   786                 state->renderers[i] = SDL_CreateRenderer(state->windows[i],
   787                                             m, state->render_flags);
   788                 if (!state->renderers[i]) {
   789                     fprintf(stderr, "Couldn't create renderer: %s\n",
   790                             SDL_GetError());
   791                     return SDL_FALSE;
   792                 }
   793                 if (state->verbose & VERBOSE_RENDER) {
   794                     SDL_RendererInfo info;
   795 
   796                     fprintf(stderr, "Current renderer:\n");
   797                     SDL_GetRendererInfo(state->renderers[i], &info);
   798                     PrintRenderer(&info);
   799                 }
   800             }
   801         }
   802     }
   803 
   804     if (state->flags & SDL_INIT_AUDIO) {
   805         if (state->verbose & VERBOSE_AUDIO) {
   806             n = SDL_GetNumAudioDrivers();
   807             if (n == 0) {
   808                 fprintf(stderr, "No built-in audio drivers\n");
   809             } else {
   810                 fprintf(stderr, "Built-in audio drivers:");
   811                 for (i = 0; i < n; ++i) {
   812                     if (i > 0) {
   813                         fprintf(stderr, ",");
   814                     }
   815                     fprintf(stderr, " %s", SDL_GetAudioDriver(i));
   816                 }
   817                 fprintf(stderr, "\n");
   818             }
   819         }
   820         if (SDL_AudioInit(state->audiodriver) < 0) {
   821             fprintf(stderr, "Couldn't initialize audio driver: %s\n",
   822                     SDL_GetError());
   823             return SDL_FALSE;
   824         }
   825         if (state->verbose & VERBOSE_VIDEO) {
   826             fprintf(stderr, "Audio driver: %s\n",
   827                     SDL_GetCurrentAudioDriver());
   828         }
   829 
   830         if (SDL_OpenAudio(&state->audiospec, NULL) < 0) {
   831             fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
   832             return SDL_FALSE;
   833         }
   834     }
   835 
   836     return SDL_TRUE;
   837 }
   838 
   839 static void
   840 PrintEvent(SDL_Event * event)
   841 {
   842     if (event->type == SDL_MOUSEMOTION) {
   843         /* Mouse motion is really spammy */
   844         //return;
   845     }
   846 
   847     fprintf(stderr, "SDL EVENT: ");
   848     switch (event->type) {
   849     case SDL_WINDOWEVENT:
   850         switch (event->window.event) {
   851         case SDL_WINDOWEVENT_SHOWN:
   852             fprintf(stderr, "Window %d shown", event->window.windowID);
   853             break;
   854         case SDL_WINDOWEVENT_HIDDEN:
   855             fprintf(stderr, "Window %d hidden", event->window.windowID);
   856             break;
   857         case SDL_WINDOWEVENT_EXPOSED:
   858             fprintf(stderr, "Window %d exposed", event->window.windowID);
   859             break;
   860         case SDL_WINDOWEVENT_MOVED:
   861             fprintf(stderr, "Window %d moved to %d,%d",
   862                     event->window.windowID, event->window.data1,
   863                     event->window.data2);
   864             break;
   865         case SDL_WINDOWEVENT_RESIZED:
   866             fprintf(stderr, "Window %d resized to %dx%d",
   867                     event->window.windowID, event->window.data1,
   868                     event->window.data2);
   869             break;
   870         case SDL_WINDOWEVENT_SIZE_CHANGED:
   871             fprintf(stderr, "Window %d changed size to %dx%d",
   872                     event->window.windowID, event->window.data1,
   873                     event->window.data2);
   874             break;
   875         case SDL_WINDOWEVENT_MINIMIZED:
   876             fprintf(stderr, "Window %d minimized", event->window.windowID);
   877             break;
   878         case SDL_WINDOWEVENT_MAXIMIZED:
   879             fprintf(stderr, "Window %d maximized", event->window.windowID);
   880             break;
   881         case SDL_WINDOWEVENT_RESTORED:
   882             fprintf(stderr, "Window %d restored", event->window.windowID);
   883             break;
   884         case SDL_WINDOWEVENT_ENTER:
   885             fprintf(stderr, "Mouse entered window %d",
   886                     event->window.windowID);
   887             break;
   888         case SDL_WINDOWEVENT_LEAVE:
   889             fprintf(stderr, "Mouse left window %d", event->window.windowID);
   890             break;
   891         case SDL_WINDOWEVENT_FOCUS_GAINED:
   892             fprintf(stderr, "Window %d gained keyboard focus",
   893                     event->window.windowID);
   894             break;
   895         case SDL_WINDOWEVENT_FOCUS_LOST:
   896             fprintf(stderr, "Window %d lost keyboard focus",
   897                     event->window.windowID);
   898             break;
   899         case SDL_WINDOWEVENT_CLOSE:
   900             fprintf(stderr, "Window %d closed", event->window.windowID);
   901             break;
   902         default:
   903             fprintf(stderr, "Window %d got unknown event %d",
   904                     event->window.windowID, event->window.event);
   905             break;
   906         }
   907         break;
   908     case SDL_KEYDOWN:
   909         fprintf(stderr,
   910                 "Keyboard: key pressed  in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
   911                 event->key.windowID,
   912                 event->key.keysym.scancode,
   913                 SDL_GetScancodeName(event->key.keysym.scancode),
   914                 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
   915         break;
   916     case SDL_KEYUP:
   917         fprintf(stderr,
   918                 "Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
   919                 event->key.windowID,
   920                 event->key.keysym.scancode,
   921                 SDL_GetScancodeName(event->key.keysym.scancode),
   922                 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
   923         break;
   924     case SDL_TEXTINPUT:
   925         fprintf(stderr, "Keyboard: text input \"%s\" in window %d",
   926                 event->text.text, event->text.windowID);
   927         break;
   928     case SDL_MOUSEMOTION:
   929         fprintf(stderr, "Mouse: moved to %d,%d (%d,%d) in window %d",
   930                 event->motion.x, event->motion.y,
   931                 event->motion.xrel, event->motion.yrel,
   932                 event->motion.windowID);
   933         break;
   934     case SDL_MOUSEBUTTONDOWN:
   935         fprintf(stderr, "Mouse: button %d pressed at %d,%d in window %d",
   936                 event->button.button, event->button.x, event->button.y,
   937                 event->button.windowID);
   938         break;
   939     case SDL_MOUSEBUTTONUP:
   940         fprintf(stderr, "Mouse: button %d released at %d,%d in window %d",
   941                 event->button.button, event->button.x, event->button.y,
   942                 event->button.windowID);
   943         break;
   944     case SDL_MOUSEWHEEL:
   945         fprintf(stderr,
   946                 "Mouse: wheel scrolled %d in x and %d in y in window %d",
   947                 event->wheel.x, event->wheel.y, event->wheel.windowID);
   948         break;
   949     case SDL_JOYBALLMOTION:
   950         fprintf(stderr, "Joystick %d: ball %d moved by %d,%d",
   951                 event->jball.which, event->jball.ball, event->jball.xrel,
   952                 event->jball.yrel);
   953         break;
   954     case SDL_JOYHATMOTION:
   955         fprintf(stderr, "Joystick %d: hat %d moved to ", event->jhat.which,
   956                 event->jhat.hat);
   957         switch (event->jhat.value) {
   958         case SDL_HAT_CENTERED:
   959             fprintf(stderr, "CENTER");
   960             break;
   961         case SDL_HAT_UP:
   962             fprintf(stderr, "UP");
   963             break;
   964         case SDL_HAT_RIGHTUP:
   965             fprintf(stderr, "RIGHTUP");
   966             break;
   967         case SDL_HAT_RIGHT:
   968             fprintf(stderr, "RIGHT");
   969             break;
   970         case SDL_HAT_RIGHTDOWN:
   971             fprintf(stderr, "RIGHTDOWN");
   972             break;
   973         case SDL_HAT_DOWN:
   974             fprintf(stderr, "DOWN");
   975             break;
   976         case SDL_HAT_LEFTDOWN:
   977             fprintf(stderr, "LEFTDOWN");
   978             break;
   979         case SDL_HAT_LEFT:
   980             fprintf(stderr, "LEFT");
   981             break;
   982         case SDL_HAT_LEFTUP:
   983             fprintf(stderr, "LEFTUP");
   984             break;
   985         default:
   986             fprintf(stderr, "UNKNOWN");
   987             break;
   988         }
   989         break;
   990     case SDL_JOYBUTTONDOWN:
   991         fprintf(stderr, "Joystick %d: button %d pressed",
   992                 event->jbutton.which, event->jbutton.button);
   993         break;
   994     case SDL_JOYBUTTONUP:
   995         fprintf(stderr, "Joystick %d: button %d released",
   996                 event->jbutton.which, event->jbutton.button);
   997         break;
   998     case SDL_CLIPBOARDUPDATE:
   999         fprintf(stderr, "Clipboard updated");
  1000         break;
  1001     case SDL_QUIT:
  1002         fprintf(stderr, "Quit requested");
  1003         break;
  1004     case SDL_USEREVENT:
  1005         fprintf(stderr, "User event %d", event->user.code);
  1006         break;
  1007     default:
  1008         fprintf(stderr, "Unknown event %d", event->type);
  1009         break;
  1010     }
  1011     fprintf(stderr, "\n");
  1012 }
  1013 
  1014 static void
  1015 ScreenShot(SDL_Renderer *renderer)
  1016 {
  1017     SDL_Rect viewport;
  1018     SDL_Surface *surface;
  1019 
  1020     if (!renderer) {
  1021         return;
  1022     }
  1023 
  1024     SDL_RenderGetViewport(renderer, &viewport);
  1025     surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24,
  1026 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  1027                     0x00FF0000, 0x0000FF00, 0x000000FF,
  1028 #else
  1029                     0x000000FF, 0x0000FF00, 0x00FF0000,
  1030 #endif
  1031                     0x00000000);
  1032     if (!surface) {
  1033         fprintf(stderr, "Couldn't create surface: %s\n", SDL_GetError());
  1034         return;
  1035     }
  1036 
  1037     if (SDL_RenderReadPixels(renderer, NULL, surface->format->format,
  1038                              surface->pixels, surface->pitch) < 0) {
  1039         fprintf(stderr, "Couldn't read screen: %s\n", SDL_GetError());
  1040         return;
  1041     }
  1042 
  1043     if (SDL_SaveBMP(surface, "screenshot.bmp") < 0) {
  1044         fprintf(stderr, "Couldn't save screenshot.bmp: %s\n", SDL_GetError());
  1045         return;
  1046     }
  1047 }
  1048 
  1049 void
  1050 CommonEvent(CommonState * state, SDL_Event * event, int *done)
  1051 {
  1052     int i;
  1053 
  1054     if (state->verbose & VERBOSE_EVENT) {
  1055         PrintEvent(event);
  1056     }
  1057 
  1058     switch (event->type) {
  1059     case SDL_WINDOWEVENT:
  1060         switch (event->window.event) {
  1061         case SDL_WINDOWEVENT_SIZE_CHANGED:
  1062             {
  1063                 SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
  1064                 if (window) {
  1065                     for (i = 0; i < state->num_windows; ++i) {
  1066                         if (window == state->windows[i] &&
  1067                             (state->window_flags & SDL_WINDOW_RESIZABLE)) {
  1068                             SDL_Rect viewport;
  1069 
  1070                             viewport.x = 0;
  1071                             viewport.y = 0;
  1072                             SDL_GetWindowSize(window, &viewport.w, &viewport.h);
  1073                             SDL_RenderSetViewport(state->renderers[i], &viewport);
  1074                         }
  1075                     }
  1076                 }
  1077             }
  1078             break;
  1079         case SDL_WINDOWEVENT_CLOSE:
  1080 			{
  1081                 SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
  1082                 if (window) {
  1083 					SDL_DestroyWindow(window);
  1084 				}
  1085 			}
  1086             break;
  1087         }
  1088         break;
  1089     case SDL_KEYDOWN:
  1090         switch (event->key.keysym.sym) {
  1091             /* Add hotkeys here */
  1092         case SDLK_PRINTSCREEN: {
  1093                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1094                 if (window) {
  1095                     for (i = 0; i < state->num_windows; ++i) {
  1096                         if (window == state->windows[i]) {
  1097                             ScreenShot(state->renderers[i]);
  1098                         }
  1099                     }
  1100                 }
  1101             }
  1102             break;
  1103         case SDLK_EQUALS:
  1104             if (event->key.keysym.mod & KMOD_CTRL) {
  1105                 /* Ctrt-+ double the size of the window */
  1106                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1107                 if (window) {
  1108                     int w, h;
  1109                     SDL_GetWindowSize(window, &w, &h);
  1110                     SDL_SetWindowSize(window, w*2, h*2);
  1111                 }
  1112             }
  1113             break;
  1114         case SDLK_MINUS:
  1115             if (event->key.keysym.mod & KMOD_CTRL) {
  1116                 /* Ctrt-- double the size of the window */
  1117                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1118                 if (window) {
  1119                     int w, h;
  1120                     SDL_GetWindowSize(window, &w, &h);
  1121                     SDL_SetWindowSize(window, w/2, h/2);
  1122                 }
  1123             }
  1124             break;
  1125         case SDLK_c:
  1126             if (event->key.keysym.mod & KMOD_CTRL) {
  1127                 /* Ctrl-C copy awesome text! */
  1128                 SDL_SetClipboardText("SDL rocks!\nYou know it!");
  1129                 printf("Copied text to clipboard\n");
  1130             }
  1131             break;
  1132         case SDLK_v:
  1133             if (event->key.keysym.mod & KMOD_CTRL) {
  1134                 /* Ctrl-V paste awesome text! */
  1135                 char *text = SDL_GetClipboardText();
  1136                 if (*text) {
  1137                     printf("Clipboard: %s\n", text);
  1138                 } else {
  1139                     printf("Clipboard is empty\n");
  1140                 }
  1141                 SDL_free(text);
  1142             }
  1143             break;
  1144         case SDLK_g:
  1145             if (event->key.keysym.mod & KMOD_CTRL) {
  1146                 /* Ctrl-G toggle grab */
  1147                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1148                 if (window) {
  1149                     SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window));
  1150                 }
  1151             }
  1152             break;
  1153         case SDLK_m:
  1154             if (event->key.keysym.mod & KMOD_CTRL) {
  1155                 /* Ctrl-M maximize */
  1156                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1157                 if (window) {
  1158                     Uint32 flags = SDL_GetWindowFlags(window);
  1159                     if (flags & SDL_WINDOW_MAXIMIZED) {
  1160                         SDL_RestoreWindow(window);
  1161                     } else {
  1162                         SDL_MaximizeWindow(window);
  1163                     }
  1164                 }
  1165             }
  1166             break;
  1167         case SDLK_r:
  1168             if (event->key.keysym.mod & KMOD_CTRL) {
  1169                 /* Ctrl-R toggle mouse relative mode */
  1170                 SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode());
  1171             }
  1172             break;
  1173         case SDLK_z:
  1174             if (event->key.keysym.mod & KMOD_CTRL) {
  1175                 /* Ctrl-Z minimize */
  1176                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1177                 if (window) {
  1178                     SDL_MinimizeWindow(window);
  1179                 }
  1180             }
  1181             break;
  1182         case SDLK_RETURN:
  1183             if (event->key.keysym.mod & KMOD_CTRL) {
  1184                 /* Ctrl-Enter toggle fullscreen */
  1185                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1186                 if (window) {
  1187                     Uint32 flags = SDL_GetWindowFlags(window);
  1188                     if (flags & SDL_WINDOW_FULLSCREEN) {
  1189                         SDL_SetWindowFullscreen(window, SDL_FALSE);
  1190                     } else {
  1191                         SDL_SetWindowFullscreen(window, SDL_TRUE);
  1192                     }
  1193                 }
  1194             }
  1195             break;
  1196         case SDLK_b:
  1197             if (event->key.keysym.mod & KMOD_CTRL) {
  1198                 /* Ctrl-B toggle window border */
  1199                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1200                 if (window) {
  1201                     const Uint32 flags = SDL_GetWindowFlags(window);
  1202                     const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0);
  1203                     SDL_SetWindowBordered(window, b);
  1204                 }
  1205             }
  1206             break;
  1207         case SDLK_1:
  1208             if (event->key.keysym.mod & KMOD_CTRL) {
  1209                 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
  1210                 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Test Message", "You're awesome!", window);
  1211             }
  1212             break;
  1213         case SDLK_ESCAPE:
  1214             *done = 1;
  1215             break;
  1216         default:
  1217             break;
  1218         }
  1219         break;
  1220     case SDL_QUIT:
  1221         *done = 1;
  1222         break;
  1223     }
  1224 }
  1225 
  1226 void
  1227 CommonQuit(CommonState * state)
  1228 {
  1229     int i;
  1230 
  1231     if (state->windows) {
  1232         SDL_free(state->windows);
  1233     }
  1234     if (state->renderers) {
  1235         for (i = 0; i < state->num_windows; ++i) {
  1236             if (state->renderers[i]) {
  1237                 SDL_DestroyRenderer(state->renderers[i]);
  1238             }
  1239         }
  1240         SDL_free(state->renderers);
  1241     }
  1242     if (state->flags & SDL_INIT_VIDEO) {
  1243         SDL_VideoQuit();
  1244     }
  1245     if (state->flags & SDL_INIT_AUDIO) {
  1246         SDL_AudioQuit();
  1247     }
  1248     SDL_free(state);
  1249 }
  1250 
  1251 /* vi: set ts=4 sw=4 expandtab: */