test/common.c
author Bob Pendleton <bob@pendleton.com>
Wed, 23 Sep 2009 02:52:11 +0000
changeset 3299 975fd903466b
parent 3194 c18c03927a77
child 3370 3e0f51e60fa2
permissions -rw-r--r--
int testmmousetable.c the arguments to main() are not compatible with what is required in SDL_main.h
Cleaned up testatomic.c to use the same syntax as every other test program.
     1 
     2 /* A simple test program framework */
     3 
     4 #include <stdio.h>
     5 
     6 #include "common.h"
     7 
     8 #define VIDEO_USAGE \
     9 "[--video driver] [--renderer driver] [--info all|video|modes|render|event] [--display %d] [--fullscreen | --windows N] [--title title] [--center | --position X,Y] [--geometry WxH] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab]"
    10 
    11 #define AUDIO_USAGE \
    12 "[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]"
    13 
    14 struct pformat {
    15     Uint32 id;
    16     const char* idstr;
    17 } pixel_format[]={
    18     {SDL_PIXELFORMAT_INDEX1LSB, "SDL_PIXELFORMAT_INDEX1LSB"},
    19     {SDL_PIXELFORMAT_INDEX1MSB, "SDL_PIXELFORMAT_INDEX1MSB"},
    20     {SDL_PIXELFORMAT_INDEX4LSB, "SDL_PIXELFORMAT_INDEX4LSB"},
    21     {SDL_PIXELFORMAT_INDEX4MSB, "SDL_PIXELFORMAT_INDEX4MSB"},
    22     {SDL_PIXELFORMAT_INDEX8, "SDL_PIXELFORMAT_INDEX8"},
    23     {SDL_PIXELFORMAT_RGB332, "SDL_PIXELFORMAT_RGB332"},
    24     {SDL_PIXELFORMAT_RGB444, "SDL_PIXELFORMAT_RGB444"},
    25     {SDL_PIXELFORMAT_RGB555, "SDL_PIXELFORMAT_RGB555"},
    26     {SDL_PIXELFORMAT_BGR555, "SDL_PIXELFORMAT_BGR555"},
    27     {SDL_PIXELFORMAT_ARGB4444, "SDL_PIXELFORMAT_ARGB4444"},
    28     {SDL_PIXELFORMAT_ABGR4444, "SDL_PIXELFORMAT_ABGR4444"},
    29     {SDL_PIXELFORMAT_ARGB1555, "SDL_PIXELFORMAT_ARGB1555"},
    30     {SDL_PIXELFORMAT_ABGR1555, "SDL_PIXELFORMAT_ABGR1555"},
    31     {SDL_PIXELFORMAT_RGB565, "SDL_PIXELFORMAT_RGB565"},
    32     {SDL_PIXELFORMAT_BGR565, "SDL_PIXELFORMAT_BGR565"},
    33     {SDL_PIXELFORMAT_RGB24, "SDL_PIXELFORMAT_RGB24"},
    34     {SDL_PIXELFORMAT_BGR24, "SDL_PIXELFORMAT_BGR24"},
    35     {SDL_PIXELFORMAT_RGB888, "SDL_PIXELFORMAT_RGB888"},
    36     {SDL_PIXELFORMAT_BGR888, "SDL_PIXELFORMAT_BGR888"},
    37     {SDL_PIXELFORMAT_ARGB8888, "SDL_PIXELFORMAT_ARGB8888"},
    38     {SDL_PIXELFORMAT_RGBA8888, "SDL_PIXELFORMAT_RGBA8888"},
    39     {SDL_PIXELFORMAT_ABGR8888, "SDL_PIXELFORMAT_ABGR8888"},
    40     {SDL_PIXELFORMAT_BGRA8888, "SDL_PIXELFORMAT_BGRA8888"},
    41     {SDL_PIXELFORMAT_ARGB2101010, "SDL_PIXELFORMAT_ARGB2101010"},
    42     {SDL_PIXELFORMAT_YV12, "SDL_PIXELFORMAT_YV12"},
    43     {SDL_PIXELFORMAT_IYUV, "SDL_PIXELFORMAT_IYUV"},
    44     {SDL_PIXELFORMAT_YUY2, "SDL_PIXELFORMAT_YUY2"},
    45     {SDL_PIXELFORMAT_UYVY, "SDL_PIXELFORMAT_UYVY"},
    46     {SDL_PIXELFORMAT_YVYU, "SDL_PIXELFORMAT_YVYU"}
    47 };
    48 
    49 const char* PixelFormatToString(Uint32 pformat)
    50 {
    51    Uint32 it=0;
    52 
    53    do {
    54       if (pixel_format[it].idstr == NULL) {
    55           break;
    56       }
    57       if (pixel_format[it].id == pformat) {
    58           return pixel_format[it].idstr;
    59       }
    60       it++;
    61    } while(1);
    62 
    63    return "SDL_PIXELFORMAT_UNKNOWN";
    64 }
    65 
    66 CommonState *
    67 CommonCreateState(char **argv, Uint32 flags)
    68 {
    69     CommonState *state = SDL_calloc(1, sizeof(*state));
    70     if (!state) {
    71         SDL_OutOfMemory();
    72         return NULL;
    73     }
    74 
    75     /* Initialize some defaults */
    76     state->argv = argv;
    77     state->flags = flags;
    78     state->window_title = argv[0];
    79     state->window_flags = SDL_WINDOW_SHOWN;
    80     state->window_x = SDL_WINDOWPOS_UNDEFINED;
    81     state->window_y = SDL_WINDOWPOS_UNDEFINED;
    82     state->window_w = DEFAULT_WINDOW_WIDTH;
    83     state->window_h = DEFAULT_WINDOW_HEIGHT;
    84     state->num_windows = 1;
    85     state->audiospec.freq = 22050;
    86     state->audiospec.format = AUDIO_S16;
    87     state->audiospec.channels = 2;
    88     state->audiospec.samples = 2048;
    89     return state;
    90 }
    91 
    92 int
    93 CommonArg(CommonState * state, int index)
    94 {
    95     char **argv = state->argv;
    96 
    97     if (SDL_strcasecmp(argv[index], "--video") == 0) {
    98         ++index;
    99         if (!argv[index]) {
   100             return -1;
   101         }
   102         state->videodriver = argv[index];
   103         return 2;
   104     }
   105     if (SDL_strcasecmp(argv[index], "--renderer") == 0) {
   106         ++index;
   107         if (!argv[index]) {
   108             return -1;
   109         }
   110         state->renderdriver = argv[index];
   111         return 2;
   112     }
   113     if (SDL_strcasecmp(argv[index], "--info") == 0) {
   114         ++index;
   115         if (!argv[index]) {
   116             return -1;
   117         }
   118         if (SDL_strcasecmp(argv[index], "all") == 0) {
   119             state->verbose |=
   120                 (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER |
   121                  VERBOSE_EVENT);
   122             return 2;
   123         }
   124         if (SDL_strcasecmp(argv[index], "video") == 0) {
   125             state->verbose |= VERBOSE_VIDEO;
   126             return 2;
   127         }
   128         if (SDL_strcasecmp(argv[index], "modes") == 0) {
   129             state->verbose |= VERBOSE_MODES;
   130             return 2;
   131         }
   132         if (SDL_strcasecmp(argv[index], "render") == 0) {
   133             state->verbose |= VERBOSE_RENDER;
   134             return 2;
   135         }
   136         if (SDL_strcasecmp(argv[index], "event") == 0) {
   137             state->verbose |= VERBOSE_EVENT;
   138             return 2;
   139         }
   140         return -1;
   141     }
   142     if (SDL_strcasecmp(argv[index], "--display") == 0) {
   143         ++index;
   144         if (!argv[index]) {
   145             return -1;
   146         }
   147         state->display = SDL_atoi(argv[index]);
   148         return 2;
   149     }
   150     if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
   151         state->window_flags |= SDL_WINDOW_FULLSCREEN;
   152         state->num_windows = 1;
   153         return 1;
   154     }
   155     if (SDL_strcasecmp(argv[index], "--windows") == 0) {
   156         ++index;
   157         if (!argv[index] || !SDL_isdigit(*argv[index])) {
   158             return -1;
   159         }
   160         if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
   161             state->num_windows = SDL_atoi(argv[index]);
   162         }
   163         return 2;
   164     }
   165     if (SDL_strcasecmp(argv[index], "--title") == 0) {
   166         ++index;
   167         if (!argv[index]) {
   168             return -1;
   169         }
   170         state->window_title = argv[index];
   171         return 2;
   172     }
   173     if (SDL_strcasecmp(argv[index], "--center") == 0) {
   174         state->window_x = SDL_WINDOWPOS_CENTERED;
   175         state->window_y = SDL_WINDOWPOS_CENTERED;
   176         return 1;
   177     }
   178     if (SDL_strcasecmp(argv[index], "--position") == 0) {
   179         char *x, *y;
   180         ++index;
   181         if (!argv[index]) {
   182             return -1;
   183         }
   184         x = argv[index];
   185         y = argv[index];
   186         while (*y && *y != ',') {
   187             ++y;
   188         }
   189         if (!*y) {
   190             return -1;
   191         }
   192         *y++ = '\0';
   193         state->window_x = SDL_atoi(x);
   194         state->window_y = SDL_atoi(y);
   195         return 2;
   196     }
   197     if (SDL_strcasecmp(argv[index], "--geometry") == 0) {
   198         char *w, *h;
   199         ++index;
   200         if (!argv[index]) {
   201             return -1;
   202         }
   203         w = argv[index];
   204         h = argv[index];
   205         while (*h && *h != 'x') {
   206             ++h;
   207         }
   208         if (!*h) {
   209             return -1;
   210         }
   211         *h++ = '\0';
   212         state->window_w = SDL_atoi(w);
   213         state->window_h = SDL_atoi(h);
   214         return 2;
   215     }
   216     if (SDL_strcasecmp(argv[index], "--depth") == 0) {
   217         ++index;
   218         if (!argv[index]) {
   219             return -1;
   220         }
   221         state->depth = SDL_atoi(argv[index]);
   222         return 2;
   223     }
   224     if (SDL_strcasecmp(argv[index], "--refresh") == 0) {
   225         ++index;
   226         if (!argv[index]) {
   227             return -1;
   228         }
   229         state->refresh_rate = SDL_atoi(argv[index]);
   230         return 2;
   231     }
   232     if (SDL_strcasecmp(argv[index], "--vsync") == 0) {
   233         state->render_flags |= SDL_RENDERER_PRESENTVSYNC;
   234         return 1;
   235     }
   236     if (SDL_strcasecmp(argv[index], "--noframe") == 0) {
   237         state->window_flags |= SDL_WINDOW_BORDERLESS;
   238         return 1;
   239     }
   240     if (SDL_strcasecmp(argv[index], "--resize") == 0) {
   241         state->window_flags |= SDL_WINDOW_RESIZABLE;
   242         return 1;
   243     }
   244     if (SDL_strcasecmp(argv[index], "--minimize") == 0) {
   245         state->window_flags |= SDL_WINDOW_MINIMIZED;
   246         return 1;
   247     }
   248     if (SDL_strcasecmp(argv[index], "--maximize") == 0) {
   249         state->window_flags |= SDL_WINDOW_MAXIMIZED;
   250         return 1;
   251     }
   252     if (SDL_strcasecmp(argv[index], "--grab") == 0) {
   253         state->window_flags |= SDL_WINDOW_INPUT_GRABBED;
   254         return 1;
   255     }
   256     if (SDL_strcasecmp(argv[index], "--rate") == 0) {
   257         ++index;
   258         if (!argv[index]) {
   259             return -1;
   260         }
   261         state->audiospec.freq = SDL_atoi(argv[index]);
   262         return 2;
   263     }
   264     if (SDL_strcasecmp(argv[index], "--format") == 0) {
   265         ++index;
   266         if (!argv[index]) {
   267             return -1;
   268         }
   269         if (SDL_strcasecmp(argv[index], "U8") == 0) {
   270             state->audiospec.format = AUDIO_U8;
   271             return 2;
   272         }
   273         if (SDL_strcasecmp(argv[index], "S8") == 0) {
   274             state->audiospec.format = AUDIO_S8;
   275             return 2;
   276         }
   277         if (SDL_strcasecmp(argv[index], "U16") == 0) {
   278             state->audiospec.format = AUDIO_U16;
   279             return 2;
   280         }
   281         if (SDL_strcasecmp(argv[index], "U16LE") == 0) {
   282             state->audiospec.format = AUDIO_U16LSB;
   283             return 2;
   284         }
   285         if (SDL_strcasecmp(argv[index], "U16BE") == 0) {
   286             state->audiospec.format = AUDIO_U16MSB;
   287             return 2;
   288         }
   289         if (SDL_strcasecmp(argv[index], "S16") == 0) {
   290             state->audiospec.format = AUDIO_S16;
   291             return 2;
   292         }
   293         if (SDL_strcasecmp(argv[index], "S16LE") == 0) {
   294             state->audiospec.format = AUDIO_S16LSB;
   295             return 2;
   296         }
   297         if (SDL_strcasecmp(argv[index], "S16BE") == 0) {
   298             state->audiospec.format = AUDIO_S16MSB;
   299             return 2;
   300         }
   301         return -1;
   302     }
   303     if (SDL_strcasecmp(argv[index], "--channels") == 0) {
   304         ++index;
   305         if (!argv[index]) {
   306             return -1;
   307         }
   308         state->audiospec.channels = (Uint8) SDL_atoi(argv[index]);
   309         return 2;
   310     }
   311     if (SDL_strcasecmp(argv[index], "--samples") == 0) {
   312         ++index;
   313         if (!argv[index]) {
   314             return -1;
   315         }
   316         state->audiospec.samples = (Uint16) SDL_atoi(argv[index]);
   317         return 2;
   318     }
   319     if ((SDL_strcasecmp(argv[index], "-h") == 0)
   320         || (SDL_strcasecmp(argv[index], "--help") == 0)) {
   321         /* Print the usage message */
   322         return -1;
   323     }
   324     return 0;
   325 }
   326 
   327 const char *
   328 CommonUsage(CommonState * state)
   329 {
   330     switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
   331     case SDL_INIT_VIDEO:
   332         return VIDEO_USAGE;
   333     case SDL_INIT_AUDIO:
   334         return AUDIO_USAGE;
   335     case (SDL_INIT_VIDEO | SDL_INIT_AUDIO):
   336         return VIDEO_USAGE " " AUDIO_USAGE;
   337     default:
   338         return "";
   339     }
   340 }
   341 
   342 static void
   343 PrintRendererFlag(Uint32 flag)
   344 {
   345     switch (flag) {
   346     case SDL_RENDERER_SINGLEBUFFER:
   347         fprintf(stderr, "SingleBuffer");
   348         break;
   349     case SDL_RENDERER_PRESENTCOPY:
   350         fprintf(stderr, "PresentCopy");
   351         break;
   352     case SDL_RENDERER_PRESENTFLIP2:
   353         fprintf(stderr, "PresentFlip2");
   354         break;
   355     case SDL_RENDERER_PRESENTFLIP3:
   356         fprintf(stderr, "PresentFlip3");
   357         break;
   358     case SDL_RENDERER_PRESENTDISCARD:
   359         fprintf(stderr, "PresentDiscard");
   360         break;
   361     case SDL_RENDERER_PRESENTVSYNC:
   362         fprintf(stderr, "PresentVSync");
   363         break;
   364     case SDL_RENDERER_ACCELERATED:
   365         fprintf(stderr, "Accelerated");
   366         break;
   367     default:
   368         fprintf(stderr, "0x%8.8x", flag);
   369         break;
   370     }
   371 }
   372 
   373 static void
   374 PrintBlendMode(Uint32 flag)
   375 {
   376     switch (flag) {
   377     case SDL_BLENDMODE_NONE:
   378         fprintf(stderr, "None");
   379         break;
   380     case SDL_BLENDMODE_MASK:
   381         fprintf(stderr, "Mask");
   382         break;
   383     case SDL_BLENDMODE_BLEND:
   384         fprintf(stderr, "Blend");
   385         break;
   386     case SDL_BLENDMODE_ADD:
   387         fprintf(stderr, "Add");
   388         break;
   389     case SDL_BLENDMODE_MOD:
   390         fprintf(stderr, "Mod");
   391         break;
   392     default:
   393         fprintf(stderr, "0x%8.8x", flag);
   394         break;
   395     }
   396 }
   397 
   398 static void
   399 PrintScaleMode(Uint32 flag)
   400 {
   401     switch (flag) {
   402     case SDL_TEXTURESCALEMODE_NONE:
   403         fprintf(stderr, "None");
   404         break;
   405     case SDL_TEXTURESCALEMODE_FAST:
   406         fprintf(stderr, "Fast");
   407         break;
   408     case SDL_TEXTURESCALEMODE_SLOW:
   409         fprintf(stderr, "Slow");
   410         break;
   411     case SDL_TEXTURESCALEMODE_BEST:
   412         fprintf(stderr, "Best");
   413         break;
   414     default:
   415         fprintf(stderr, "0x%8.8x", flag);
   416         break;
   417     }
   418 }
   419 
   420 static void
   421 PrintPixelFormat(Uint32 format)
   422 {
   423     switch (format) {
   424     case SDL_PIXELFORMAT_UNKNOWN:
   425         fprintf(stderr, "Unknwon");
   426         break;
   427     case SDL_PIXELFORMAT_INDEX1LSB:
   428         fprintf(stderr, "Index1LSB");
   429         break;
   430     case SDL_PIXELFORMAT_INDEX1MSB:
   431         fprintf(stderr, "Index1MSB");
   432         break;
   433     case SDL_PIXELFORMAT_INDEX4LSB:
   434         fprintf(stderr, "Index4LSB");
   435         break;
   436     case SDL_PIXELFORMAT_INDEX4MSB:
   437         fprintf(stderr, "Index4MSB");
   438         break;
   439     case SDL_PIXELFORMAT_INDEX8:
   440         fprintf(stderr, "Index8");
   441         break;
   442     case SDL_PIXELFORMAT_RGB332:
   443         fprintf(stderr, "RGB332");
   444         break;
   445     case SDL_PIXELFORMAT_RGB444:
   446         fprintf(stderr, "RGB444");
   447         break;
   448     case SDL_PIXELFORMAT_RGB555:
   449         fprintf(stderr, "RGB555");
   450         break;
   451     case SDL_PIXELFORMAT_ARGB4444:
   452         fprintf(stderr, "ARGB4444");
   453         break;
   454     case SDL_PIXELFORMAT_ABGR4444:
   455         fprintf(stderr, "ABGR4444");
   456         break;
   457     case SDL_PIXELFORMAT_ARGB1555:
   458         fprintf(stderr, "ARGB1555");
   459         break;
   460     case SDL_PIXELFORMAT_ABGR1555:
   461         fprintf(stderr, "ABGR1555");
   462         break;
   463     case SDL_PIXELFORMAT_RGB565:
   464         fprintf(stderr, "RGB565");
   465         break;
   466     case SDL_PIXELFORMAT_BGR565:
   467         fprintf(stderr, "BGR565");
   468         break;
   469     case SDL_PIXELFORMAT_RGB24:
   470         fprintf(stderr, "RGB24");
   471         break;
   472     case SDL_PIXELFORMAT_BGR24:
   473         fprintf(stderr, "BGR24");
   474         break;
   475     case SDL_PIXELFORMAT_RGB888:
   476         fprintf(stderr, "RGB888");
   477         break;
   478     case SDL_PIXELFORMAT_BGR888:
   479         fprintf(stderr, "BGR888");
   480         break;
   481     case SDL_PIXELFORMAT_ARGB8888:
   482         fprintf(stderr, "ARGB8888");
   483         break;
   484     case SDL_PIXELFORMAT_RGBA8888:
   485         fprintf(stderr, "RGBA8888");
   486         break;
   487     case SDL_PIXELFORMAT_ABGR8888:
   488         fprintf(stderr, "ABGR8888");
   489         break;
   490     case SDL_PIXELFORMAT_BGRA8888:
   491         fprintf(stderr, "BGRA8888");
   492         break;
   493     case SDL_PIXELFORMAT_ARGB2101010:
   494         fprintf(stderr, "ARGB2101010");
   495         break;
   496     case SDL_PIXELFORMAT_YV12:
   497         fprintf(stderr, "YV12");
   498         break;
   499     case SDL_PIXELFORMAT_IYUV:
   500         fprintf(stderr, "IYUV");
   501         break;
   502     case SDL_PIXELFORMAT_YUY2:
   503         fprintf(stderr, "YUY2");
   504         break;
   505     case SDL_PIXELFORMAT_UYVY:
   506         fprintf(stderr, "UYVY");
   507         break;
   508     case SDL_PIXELFORMAT_YVYU:
   509         fprintf(stderr, "YVYU");
   510         break;
   511     default:
   512         fprintf(stderr, "0x%8.8x", format);
   513         break;
   514     }
   515 }
   516 
   517 static void
   518 PrintRenderer(SDL_RendererInfo * info)
   519 {
   520     int i, count;
   521 
   522     fprintf(stderr, "  Renderer %s:\n", info->name);
   523 
   524     fprintf(stderr, "    Flags: 0x%8.8X", info->flags);
   525     fprintf(stderr, " (");
   526     count = 0;
   527     for (i = 0; i < sizeof(info->flags) * 8; ++i) {
   528         Uint32 flag = (1 << i);
   529         if (info->flags & flag) {
   530             if (count > 0) {
   531                 fprintf(stderr, " | ");
   532             }
   533             PrintRendererFlag(flag);
   534             ++count;
   535         }
   536     }
   537     fprintf(stderr, ")\n");
   538 
   539     fprintf(stderr, "    Blend: 0x%8.8X", info->blend_modes);
   540     fprintf(stderr, " (");
   541     count = 0;
   542     for (i = 0; i < sizeof(info->blend_modes) * 8; ++i) {
   543         Uint32 flag = (1 << i);
   544         if (info->blend_modes & flag) {
   545             if (count > 0) {
   546                 fprintf(stderr, " | ");
   547             }
   548             PrintBlendMode(flag);
   549             ++count;
   550         }
   551     }
   552     fprintf(stderr, ")\n");
   553 
   554     fprintf(stderr, "    Scale: 0x%8.8X", info->scale_modes);
   555     fprintf(stderr, " (");
   556     count = 0;
   557     for (i = 0; i < sizeof(info->scale_modes) * 8; ++i) {
   558         Uint32 flag = (1 << i);
   559         if (info->scale_modes & flag) {
   560             if (count > 0) {
   561                 fprintf(stderr, " | ");
   562             }
   563             PrintScaleMode(flag);
   564             ++count;
   565         }
   566     }
   567     fprintf(stderr, ")\n");
   568 
   569     fprintf(stderr, "    Texture formats (%d): ", info->num_texture_formats);
   570     for (i = 0; i < (int) info->num_texture_formats; ++i) {
   571         if (i > 0) {
   572             fprintf(stderr, ", ");
   573         }
   574         PrintPixelFormat(info->texture_formats[i]);
   575     }
   576     fprintf(stderr, "\n");
   577 
   578     if (info->max_texture_width || info->max_texture_height) {
   579         fprintf(stderr, "    Max Texture Size: %dx%d\n",
   580                 info->max_texture_width, info->max_texture_height);
   581     }
   582 }
   583 
   584 SDL_bool
   585 CommonInit(CommonState * state)
   586 {
   587     int i, j, m, n;
   588     SDL_DisplayMode fullscreen_mode;
   589 
   590     if (state->flags & SDL_INIT_VIDEO) {
   591         if (state->verbose & VERBOSE_VIDEO) {
   592             n = SDL_GetNumVideoDrivers();
   593             if (n == 0) {
   594                 fprintf(stderr, "No built-in video drivers\n");
   595             } else {
   596                 fprintf(stderr, "Built-in video drivers:");
   597                 for (i = 0; i < n; ++i) {
   598                     if (i > 0) {
   599                         fprintf(stderr, ",");
   600                     }
   601                     fprintf(stderr, " %s", SDL_GetVideoDriver(i));
   602                 }
   603                 fprintf(stderr, "\n");
   604             }
   605         }
   606         if (SDL_VideoInit(state->videodriver, 0) < 0) {
   607             fprintf(stderr, "Couldn't initialize video driver: %s\n",
   608                     SDL_GetError());
   609             return SDL_FALSE;
   610         }
   611         if (state->verbose & VERBOSE_VIDEO) {
   612             fprintf(stderr, "Video driver: %s\n",
   613                     SDL_GetCurrentVideoDriver());
   614         }
   615 
   616         if (state->verbose & VERBOSE_MODES) {
   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                 SDL_SelectVideoDisplay(i);
   626 
   627                 SDL_GetDesktopDisplayMode(&mode);
   628                 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask,
   629                                            &Bmask, &Amask);
   630                 fprintf(stderr,
   631                         "  Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
   632                         mode.w, mode.h, mode.refresh_rate, bpp,
   633                         PixelFormatToString(mode.format));
   634                 if (Rmask || Gmask || Bmask) {
   635                     fprintf(stderr, "      Red Mask   = 0x%.8x\n", Rmask);
   636                     fprintf(stderr, "      Green Mask = 0x%.8x\n", Gmask);
   637                     fprintf(stderr, "      Blue Mask  = 0x%.8x\n", Bmask);
   638                     if (Amask)
   639                         fprintf(stderr, "      Alpha Mask = 0x%.8x\n", Amask);
   640                 }
   641 
   642                 /* Print available fullscreen video modes */
   643                 m = SDL_GetNumDisplayModes();
   644                 if (m == 0) {
   645                     fprintf(stderr, "No available fullscreen video modes\n");
   646                 } else {
   647                     fprintf(stderr, "  Fullscreen video modes:\n");
   648                     for (j = 0; j < m; ++j) {
   649                         SDL_GetDisplayMode(j, &mode);
   650                         SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask,
   651                                                    &Gmask, &Bmask, &Amask);
   652                         fprintf(stderr,
   653                                 "    Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
   654                                 j, mode.w, mode.h, mode.refresh_rate, bpp,
   655                                 PixelFormatToString(mode.format));
   656                         if (Rmask || Gmask || Bmask) {
   657                             fprintf(stderr, "        Red Mask   = 0x%.8x\n",
   658                                     Rmask);
   659                             fprintf(stderr, "        Green Mask = 0x%.8x\n",
   660                                     Gmask);
   661                             fprintf(stderr, "        Blue Mask  = 0x%.8x\n",
   662                                     Bmask);
   663                             if (Amask)
   664                                 fprintf(stderr,
   665                                         "        Alpha Mask = 0x%.8x\n",
   666                                         Amask);
   667                         }
   668                     }
   669                 }
   670             }
   671         }
   672 
   673         SDL_SelectVideoDisplay(state->display);
   674         if (state->verbose & VERBOSE_RENDER) {
   675             SDL_RendererInfo info;
   676 
   677             n = SDL_GetNumRenderDrivers();
   678             if (n == 0) {
   679                 fprintf(stderr, "No built-in render drivers\n");
   680             } else {
   681                 fprintf(stderr, "Built-in render drivers:\n");
   682                 for (i = 0; i < n; ++i) {
   683                     SDL_GetRenderDriverInfo(i, &info);
   684                     PrintRenderer(&info);
   685                 }
   686             }
   687         }
   688 
   689         switch (state->depth) {
   690         case 8:
   691             fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8;
   692             break;
   693         case 15:
   694             fullscreen_mode.format = SDL_PIXELFORMAT_RGB555;
   695             break;
   696         case 16:
   697             fullscreen_mode.format = SDL_PIXELFORMAT_RGB565;
   698             break;
   699         case 24:
   700             fullscreen_mode.format = SDL_PIXELFORMAT_RGB24;
   701             break;
   702         default:
   703             fullscreen_mode.format = SDL_PIXELFORMAT_RGB888;
   704             break;
   705         }
   706         fullscreen_mode.w = state->window_w;
   707         fullscreen_mode.h = state->window_h;
   708         fullscreen_mode.refresh_rate = state->refresh_rate;
   709         if (SDL_SetFullscreenDisplayMode(&fullscreen_mode)<0) {
   710             fprintf(stderr, "Can't switch to fullscreen display mode: %s\n",
   711                     SDL_GetError());
   712             return SDL_FALSE;
   713         }
   714 
   715         state->windows =
   716             (SDL_WindowID *) SDL_malloc(state->num_windows *
   717                                         sizeof(*state->windows));
   718         if (!state->windows) {
   719             fprintf(stderr, "Out of memory!\n");
   720             return SDL_FALSE;
   721         }
   722         for (i = 0; i < state->num_windows; ++i) {
   723             char title[1024];
   724 
   725             if (state->num_windows > 1) {
   726                 SDL_snprintf(title, SDL_arraysize(title), "%s %d",
   727                              state->window_title, i + 1);
   728             } else {
   729                 SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
   730             }
   731             state->windows[i] =
   732                 SDL_CreateWindow(title, state->window_x, state->window_y,
   733                                  state->window_w, state->window_h,
   734                                  state->window_flags);
   735             if (!state->windows[i]) {
   736                 fprintf(stderr, "Couldn't create window: %s\n",
   737                         SDL_GetError());
   738                 return SDL_FALSE;
   739             }
   740 
   741             if (!state->skip_renderer
   742                 && (state->renderdriver
   743                     || !(state->window_flags & SDL_WINDOW_OPENGL))) {
   744                 m = -1;
   745                 if (state->renderdriver) {
   746                     SDL_RendererInfo info;
   747                     n = SDL_GetNumRenderDrivers();
   748                     for (j = 0; j < n; ++j) {
   749                         SDL_GetRenderDriverInfo(j, &info);
   750                         if (SDL_strcasecmp(info.name, state->renderdriver) ==
   751                             0) {
   752                             m = j;
   753                             break;
   754                         }
   755                     }
   756                     if (m == n) {
   757                         fprintf(stderr,
   758                                 "Couldn't find render driver named %s",
   759                                 state->renderdriver);
   760                         return SDL_FALSE;
   761                     }
   762                 }
   763                 if (SDL_CreateRenderer
   764                     (state->windows[i], m, state->render_flags) < 0) {
   765                     fprintf(stderr, "Couldn't create renderer: %s\n",
   766                             SDL_GetError());
   767                     return SDL_FALSE;
   768                 }
   769                 if (state->verbose & VERBOSE_RENDER) {
   770                     SDL_RendererInfo info;
   771 
   772                     fprintf(stderr, "Current renderer:\n");
   773                     SDL_GetRendererInfo(&info);
   774                     PrintRenderer(&info);
   775                 }
   776             }
   777         }
   778         SDL_SelectRenderer(state->windows[0]);
   779     }
   780 
   781     if (state->flags & SDL_INIT_AUDIO) {
   782         if (state->verbose & VERBOSE_AUDIO) {
   783             n = SDL_GetNumAudioDrivers();
   784             if (n == 0) {
   785                 fprintf(stderr, "No built-in audio drivers\n");
   786             } else {
   787                 fprintf(stderr, "Built-in audio drivers:");
   788                 for (i = 0; i < n; ++i) {
   789                     if (i > 0) {
   790                         fprintf(stderr, ",");
   791                     }
   792                     fprintf(stderr, " %s", SDL_GetAudioDriver(i));
   793                 }
   794                 fprintf(stderr, "\n");
   795             }
   796         }
   797         if (SDL_AudioInit(state->audiodriver) < 0) {
   798             fprintf(stderr, "Couldn't initialize audio driver: %s\n",
   799                     SDL_GetError());
   800             return SDL_FALSE;
   801         }
   802         if (state->verbose & VERBOSE_VIDEO) {
   803             fprintf(stderr, "Audio driver: %s\n",
   804                     SDL_GetCurrentAudioDriver());
   805         }
   806 
   807         if (SDL_OpenAudio(&state->audiospec, NULL) < 0) {
   808             fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
   809             return SDL_FALSE;
   810         }
   811     }
   812 
   813     return SDL_TRUE;
   814 }
   815 
   816 static void
   817 PrintEvent(SDL_Event * event)
   818 {
   819     fprintf(stderr, "SDL EVENT: ");
   820     switch (event->type) {
   821     case SDL_WINDOWEVENT:
   822         switch (event->window.event) {
   823         case SDL_WINDOWEVENT_SHOWN:
   824             fprintf(stderr, "Window %d shown", event->window.windowID);
   825             break;
   826         case SDL_WINDOWEVENT_HIDDEN:
   827             fprintf(stderr, "Window %d hidden", event->window.windowID);
   828             break;
   829         case SDL_WINDOWEVENT_EXPOSED:
   830             fprintf(stderr, "Window %d exposed", event->window.windowID);
   831             break;
   832         case SDL_WINDOWEVENT_MOVED:
   833             fprintf(stderr, "Window %d moved to %d,%d",
   834                     event->window.windowID, event->window.data1,
   835                     event->window.data2);
   836             break;
   837         case SDL_WINDOWEVENT_RESIZED:
   838             fprintf(stderr, "Window %d resized to %dx%d",
   839                     event->window.windowID, event->window.data1,
   840                     event->window.data2);
   841             break;
   842         case SDL_WINDOWEVENT_MINIMIZED:
   843             fprintf(stderr, "Window %d minimized", event->window.windowID);
   844             break;
   845         case SDL_WINDOWEVENT_MAXIMIZED:
   846             fprintf(stderr, "Window %d maximized", event->window.windowID);
   847             break;
   848         case SDL_WINDOWEVENT_RESTORED:
   849             fprintf(stderr, "Window %d restored", event->window.windowID);
   850             break;
   851         case SDL_WINDOWEVENT_ENTER:
   852             fprintf(stderr, "Mouse entered window %d",
   853                     event->window.windowID);
   854             break;
   855         case SDL_WINDOWEVENT_LEAVE:
   856             fprintf(stderr, "Mouse left window %d", event->window.windowID);
   857             break;
   858         case SDL_WINDOWEVENT_FOCUS_GAINED:
   859             fprintf(stderr, "Window %d gained keyboard focus",
   860                     event->window.windowID);
   861             break;
   862         case SDL_WINDOWEVENT_FOCUS_LOST:
   863             fprintf(stderr, "Window %d lost keyboard focus",
   864                     event->window.windowID);
   865             break;
   866         case SDL_WINDOWEVENT_CLOSE:
   867             fprintf(stderr, "Window %d closed", event->window.windowID);
   868             break;
   869         default:
   870             fprintf(stderr, "Window %d got unknown event %d",
   871                     event->window.windowID, event->window.event);
   872             break;
   873         }
   874         break;
   875     case SDL_KEYDOWN:
   876         fprintf(stderr,
   877                 "Keyboard %d: key pressed  in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
   878                 event->key.which, event->key.windowID,
   879                 event->key.keysym.scancode,
   880                 SDL_GetScancodeName(event->key.keysym.scancode),
   881                 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
   882         break;
   883     case SDL_KEYUP:
   884         fprintf(stderr,
   885                 "Keyboard %d: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
   886                 event->key.which, event->key.windowID,
   887                 event->key.keysym.scancode,
   888                 SDL_GetScancodeName(event->key.keysym.scancode),
   889                 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
   890         break;
   891     case SDL_TEXTINPUT:
   892         fprintf(stderr, "Keyboard %d: text input \"%s\" in window %d",
   893                 event->text.which, event->text.text, event->text.windowID);
   894         break;
   895     case SDL_MOUSEMOTION:
   896         fprintf(stderr, "Mouse %d: moved to %d,%d (%d,%d) in window %d",
   897                 event->motion.which, event->motion.x, event->motion.y,
   898                 event->motion.xrel, event->motion.yrel,
   899                 event->motion.windowID);
   900         break;
   901     case SDL_MOUSEBUTTONDOWN:
   902         fprintf(stderr, "Mouse %d: button %d pressed at %d,%d in window %d",
   903                 event->button.which, event->button.button, event->button.x,
   904                 event->button.y, event->button.windowID);
   905         break;
   906     case SDL_MOUSEBUTTONUP:
   907         fprintf(stderr, "Mouse %d: button %d released at %d,%d in window %d",
   908                 event->button.which, event->button.button, event->button.x,
   909                 event->button.y, event->button.windowID);
   910         break;
   911     case SDL_MOUSEWHEEL:
   912         fprintf(stderr,
   913                 "Mouse %d: wheel scrolled %d in x and %d in y in window %d",
   914                 event->wheel.which, event->wheel.x, event->wheel.y,
   915                 event->wheel.windowID);
   916         break;
   917     case SDL_JOYBALLMOTION:
   918         fprintf(stderr, "Joystick %d: ball %d moved by %d,%d",
   919                 event->jball.which, event->jball.ball, event->jball.xrel,
   920                 event->jball.yrel);
   921         break;
   922     case SDL_JOYHATMOTION:
   923         fprintf(stderr, "Joystick %d: hat %d moved to ", event->jhat.which,
   924                 event->jhat.hat);
   925         switch (event->jhat.value) {
   926         case SDL_HAT_CENTERED:
   927             fprintf(stderr, "CENTER");
   928             break;
   929         case SDL_HAT_UP:
   930             fprintf(stderr, "UP");
   931             break;
   932         case SDL_HAT_RIGHTUP:
   933             fprintf(stderr, "RIGHTUP");
   934             break;
   935         case SDL_HAT_RIGHT:
   936             fprintf(stderr, "RIGHT");
   937             break;
   938         case SDL_HAT_RIGHTDOWN:
   939             fprintf(stderr, "RIGHTDOWN");
   940             break;
   941         case SDL_HAT_DOWN:
   942             fprintf(stderr, "DOWN");
   943             break;
   944         case SDL_HAT_LEFTDOWN:
   945             fprintf(stderr, "LEFTDOWN");
   946             break;
   947         case SDL_HAT_LEFT:
   948             fprintf(stderr, "LEFT");
   949             break;
   950         case SDL_HAT_LEFTUP:
   951             fprintf(stderr, "LEFTUP");
   952             break;
   953         default:
   954             fprintf(stderr, "UNKNOWN");
   955             break;
   956         }
   957         break;
   958     case SDL_JOYBUTTONDOWN:
   959         fprintf(stderr, "Joystick %d: button %d pressed",
   960                 event->jbutton.which, event->jbutton.button);
   961         break;
   962     case SDL_JOYBUTTONUP:
   963         fprintf(stderr, "Joystick %d: button %d released",
   964                 event->jbutton.which, event->jbutton.button);
   965         break;
   966     case SDL_QUIT:
   967         fprintf(stderr, "Quit requested");
   968         break;
   969     case SDL_USEREVENT:
   970         fprintf(stderr, "User event %d", event->user.code);
   971         break;
   972     default:
   973         fprintf(stderr, "Unknown event %d", event->type);
   974         break;
   975     }
   976     fprintf(stderr, "\n");
   977 }
   978 
   979 void
   980 CommonEvent(CommonState * state, SDL_Event * event, int *done)
   981 {
   982     if (state->verbose & VERBOSE_EVENT) {
   983         PrintEvent(event);
   984     }
   985 
   986     switch (event->type) {
   987     case SDL_WINDOWEVENT:
   988         switch (event->window.event) {
   989         case SDL_WINDOWEVENT_CLOSE:
   990             *done = 1;
   991             break;
   992         }
   993         break;
   994     case SDL_KEYDOWN:
   995         switch (event->key.keysym.sym) {
   996             /* Add hotkeys here */
   997         case SDLK_g:
   998             if (event->key.keysym.mod & KMOD_CTRL) {
   999                 /* Ctrl-G toggle grab */
  1000             }
  1001             break;
  1002         case SDLK_ESCAPE:
  1003             *done = 1;
  1004             break;
  1005         default:
  1006             break;
  1007         }
  1008         break;
  1009     case SDL_QUIT:
  1010         *done = 1;
  1011         break;
  1012     }
  1013 }
  1014 
  1015 void
  1016 CommonQuit(CommonState * state)
  1017 {
  1018     if (state->flags & SDL_INIT_VIDEO) {
  1019         SDL_VideoQuit();
  1020     }
  1021     if (state->flags & SDL_INIT_AUDIO) {
  1022         SDL_AudioQuit();
  1023     }
  1024     if (state->windows) {
  1025         SDL_free(state->windows);
  1026     }
  1027     SDL_free(state);
  1028 }