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