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