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