test/common.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 19 Jan 2011 22:20:44 -0800
changeset 5046 4cb778067834
parent 4982 660d3a432102
child 5113 686d795b1b29
permissions -rw-r--r--
Clearing the API changes for the 1.3.0 release
     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 PrintScaleMode(Uint32 flag)
   386 {
   387     switch (flag) {
   388     case SDL_SCALEMODE_NONE:
   389         fprintf(stderr, "None");
   390         break;
   391     case SDL_SCALEMODE_FAST:
   392         fprintf(stderr, "Fast");
   393         break;
   394     case SDL_SCALEMODE_SLOW:
   395         fprintf(stderr, "Slow");
   396         break;
   397     case SDL_SCALEMODE_BEST:
   398         fprintf(stderr, "Best");
   399         break;
   400     default:
   401         fprintf(stderr, "0x%8.8x", flag);
   402         break;
   403     }
   404 }
   405 
   406 static void
   407 PrintPixelFormat(Uint32 format)
   408 {
   409     switch (format) {
   410     case SDL_PIXELFORMAT_UNKNOWN:
   411         fprintf(stderr, "Unknwon");
   412         break;
   413     case SDL_PIXELFORMAT_INDEX1LSB:
   414         fprintf(stderr, "Index1LSB");
   415         break;
   416     case SDL_PIXELFORMAT_INDEX1MSB:
   417         fprintf(stderr, "Index1MSB");
   418         break;
   419     case SDL_PIXELFORMAT_INDEX4LSB:
   420         fprintf(stderr, "Index4LSB");
   421         break;
   422     case SDL_PIXELFORMAT_INDEX4MSB:
   423         fprintf(stderr, "Index4MSB");
   424         break;
   425     case SDL_PIXELFORMAT_INDEX8:
   426         fprintf(stderr, "Index8");
   427         break;
   428     case SDL_PIXELFORMAT_RGB332:
   429         fprintf(stderr, "RGB332");
   430         break;
   431     case SDL_PIXELFORMAT_RGB444:
   432         fprintf(stderr, "RGB444");
   433         break;
   434     case SDL_PIXELFORMAT_RGB555:
   435         fprintf(stderr, "RGB555");
   436         break;
   437     case SDL_PIXELFORMAT_BGR555:
   438         fprintf(stderr, "BGR555");
   439         break;
   440     case SDL_PIXELFORMAT_ARGB4444:
   441         fprintf(stderr, "ARGB4444");
   442         break;
   443     case SDL_PIXELFORMAT_ABGR4444:
   444         fprintf(stderr, "ABGR4444");
   445         break;
   446     case SDL_PIXELFORMAT_ARGB1555:
   447         fprintf(stderr, "ARGB1555");
   448         break;
   449     case SDL_PIXELFORMAT_ABGR1555:
   450         fprintf(stderr, "ABGR1555");
   451         break;
   452     case SDL_PIXELFORMAT_RGB565:
   453         fprintf(stderr, "RGB565");
   454         break;
   455     case SDL_PIXELFORMAT_BGR565:
   456         fprintf(stderr, "BGR565");
   457         break;
   458     case SDL_PIXELFORMAT_RGB24:
   459         fprintf(stderr, "RGB24");
   460         break;
   461     case SDL_PIXELFORMAT_BGR24:
   462         fprintf(stderr, "BGR24");
   463         break;
   464     case SDL_PIXELFORMAT_RGB888:
   465         fprintf(stderr, "RGB888");
   466         break;
   467     case SDL_PIXELFORMAT_BGR888:
   468         fprintf(stderr, "BGR888");
   469         break;
   470     case SDL_PIXELFORMAT_ARGB8888:
   471         fprintf(stderr, "ARGB8888");
   472         break;
   473     case SDL_PIXELFORMAT_RGBA8888:
   474         fprintf(stderr, "RGBA8888");
   475         break;
   476     case SDL_PIXELFORMAT_ABGR8888:
   477         fprintf(stderr, "ABGR8888");
   478         break;
   479     case SDL_PIXELFORMAT_BGRA8888:
   480         fprintf(stderr, "BGRA8888");
   481         break;
   482     case SDL_PIXELFORMAT_ARGB2101010:
   483         fprintf(stderr, "ARGB2101010");
   484         break;
   485     case SDL_PIXELFORMAT_YV12:
   486         fprintf(stderr, "YV12");
   487         break;
   488     case SDL_PIXELFORMAT_IYUV:
   489         fprintf(stderr, "IYUV");
   490         break;
   491     case SDL_PIXELFORMAT_YUY2:
   492         fprintf(stderr, "YUY2");
   493         break;
   494     case SDL_PIXELFORMAT_UYVY:
   495         fprintf(stderr, "UYVY");
   496         break;
   497     case SDL_PIXELFORMAT_YVYU:
   498         fprintf(stderr, "YVYU");
   499         break;
   500     default:
   501         fprintf(stderr, "0x%8.8x", format);
   502         break;
   503     }
   504 }
   505 
   506 static void
   507 PrintRenderer(SDL_RendererInfo * info)
   508 {
   509     int i, count;
   510 
   511     fprintf(stderr, "  Renderer %s:\n", info->name);
   512 
   513     fprintf(stderr, "    Flags: 0x%8.8X", info->flags);
   514     fprintf(stderr, " (");
   515     count = 0;
   516     for (i = 0; i < sizeof(info->flags) * 8; ++i) {
   517         Uint32 flag = (1 << i);
   518         if (info->flags & flag) {
   519             if (count > 0) {
   520                 fprintf(stderr, " | ");
   521             }
   522             PrintRendererFlag(flag);
   523             ++count;
   524         }
   525     }
   526     fprintf(stderr, ")\n");
   527 
   528     fprintf(stderr, "    Blend: 0x%8.8X", info->blend_modes);
   529     fprintf(stderr, " (");
   530     count = 0;
   531     for (i = 0; i < sizeof(info->blend_modes) * 8; ++i) {
   532         Uint32 flag = (1 << i);
   533         if (info->blend_modes & flag) {
   534             if (count > 0) {
   535                 fprintf(stderr, " | ");
   536             }
   537             PrintBlendMode(flag);
   538             ++count;
   539         }
   540     }
   541     fprintf(stderr, ")\n");
   542 
   543     fprintf(stderr, "    Scale: 0x%8.8X", info->scale_modes);
   544     fprintf(stderr, " (");
   545     count = 0;
   546     for (i = 0; i < sizeof(info->scale_modes) * 8; ++i) {
   547         Uint32 flag = (1 << i);
   548         if (info->scale_modes & flag) {
   549             if (count > 0) {
   550                 fprintf(stderr, " | ");
   551             }
   552             PrintScaleMode(flag);
   553             ++count;
   554         }
   555     }
   556     fprintf(stderr, ")\n");
   557 
   558     fprintf(stderr, "    Texture formats (%d): ", info->num_texture_formats);
   559     for (i = 0; i < (int) info->num_texture_formats; ++i) {
   560         if (i > 0) {
   561             fprintf(stderr, ", ");
   562         }
   563         PrintPixelFormat(info->texture_formats[i]);
   564     }
   565     fprintf(stderr, "\n");
   566 
   567     if (info->max_texture_width || info->max_texture_height) {
   568         fprintf(stderr, "    Max Texture Size: %dx%d\n",
   569                 info->max_texture_width, info->max_texture_height);
   570     }
   571 }
   572 
   573 static SDL_Surface *
   574 LoadIcon(const char *file)
   575 {
   576     SDL_Surface *icon;
   577 
   578     /* Load the icon surface */
   579     icon = SDL_LoadBMP(file);
   580     if (icon == NULL) {
   581         fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
   582         return (NULL);
   583     }
   584 
   585     if (icon->format->palette == NULL) {
   586         fprintf(stderr, "Icon must have a palette!\n");
   587         SDL_FreeSurface(icon);
   588         return (NULL);
   589     }
   590 
   591     /* Set the colorkey */
   592     SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels));
   593 
   594     return (icon);
   595 }
   596 
   597 SDL_bool
   598 CommonInit(CommonState * state)
   599 {
   600     int i, j, m, n;
   601     SDL_DisplayMode fullscreen_mode;
   602 
   603     if (state->flags & SDL_INIT_VIDEO) {
   604         if (state->verbose & VERBOSE_VIDEO) {
   605             n = SDL_GetNumVideoDrivers();
   606             if (n == 0) {
   607                 fprintf(stderr, "No built-in video drivers\n");
   608             } else {
   609                 fprintf(stderr, "Built-in video drivers:");
   610                 for (i = 0; i < n; ++i) {
   611                     if (i > 0) {
   612                         fprintf(stderr, ",");
   613                     }
   614                     fprintf(stderr, " %s", SDL_GetVideoDriver(i));
   615                 }
   616                 fprintf(stderr, "\n");
   617             }
   618         }
   619         if (SDL_VideoInit(state->videodriver, 0) < 0) {
   620             fprintf(stderr, "Couldn't initialize video driver: %s\n",
   621                     SDL_GetError());
   622             return SDL_FALSE;
   623         }
   624         if (state->verbose & VERBOSE_VIDEO) {
   625             fprintf(stderr, "Video driver: %s\n",
   626                     SDL_GetCurrentVideoDriver());
   627         }
   628 
   629         /* Upload GL settings */
   630         SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size);
   631         SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size);
   632         SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size);
   633         SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size);
   634         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer);
   635         SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size);
   636         SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size);
   637         SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size);
   638         SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size);
   639         SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size);
   640         SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size);
   641         SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size);
   642         SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo);
   643         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers);
   644         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples);
   645         if (state->gl_accelerated >= 0) {
   646             SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
   647                                 state->gl_accelerated);
   648         }
   649         SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing);
   650         SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version);
   651         SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version);
   652 
   653         if (state->verbose & VERBOSE_MODES) {
   654             SDL_DisplayMode mode;
   655             int bpp;
   656             Uint32 Rmask, Gmask, Bmask, Amask;
   657 
   658             n = SDL_GetNumVideoDisplays();
   659             fprintf(stderr, "Number of displays: %d\n", n);
   660             for (i = 0; i < n; ++i) {
   661                 fprintf(stderr, "Display %d:\n", i);
   662                 SDL_SelectVideoDisplay(i);
   663 
   664                 SDL_GetDesktopDisplayMode(&mode);
   665                 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask,
   666                                            &Bmask, &Amask);
   667                 fprintf(stderr,
   668                         "  Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
   669                         mode.w, mode.h, mode.refresh_rate, bpp,
   670                         SDL_GetPixelFormatName(mode.format));
   671                 if (Rmask || Gmask || Bmask) {
   672                     fprintf(stderr, "      Red Mask   = 0x%.8x\n", Rmask);
   673                     fprintf(stderr, "      Green Mask = 0x%.8x\n", Gmask);
   674                     fprintf(stderr, "      Blue Mask  = 0x%.8x\n", Bmask);
   675                     if (Amask)
   676                         fprintf(stderr, "      Alpha Mask = 0x%.8x\n", Amask);
   677                 }
   678 
   679                 /* Print available fullscreen video modes */
   680                 m = SDL_GetNumDisplayModes();
   681                 if (m == 0) {
   682                     fprintf(stderr, "No available fullscreen video modes\n");
   683                 } else {
   684                     fprintf(stderr, "  Fullscreen video modes:\n");
   685                     for (j = 0; j < m; ++j) {
   686                         SDL_GetDisplayMode(j, &mode);
   687                         SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask,
   688                                                    &Gmask, &Bmask, &Amask);
   689                         fprintf(stderr,
   690                                 "    Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
   691                                 j, mode.w, mode.h, mode.refresh_rate, bpp,
   692                                 SDL_GetPixelFormatName(mode.format));
   693                         if (Rmask || Gmask || Bmask) {
   694                             fprintf(stderr, "        Red Mask   = 0x%.8x\n",
   695                                     Rmask);
   696                             fprintf(stderr, "        Green Mask = 0x%.8x\n",
   697                                     Gmask);
   698                             fprintf(stderr, "        Blue Mask  = 0x%.8x\n",
   699                                     Bmask);
   700                             if (Amask)
   701                                 fprintf(stderr,
   702                                         "        Alpha Mask = 0x%.8x\n",
   703                                         Amask);
   704                         }
   705                     }
   706                 }
   707             }
   708         }
   709 
   710         SDL_SelectVideoDisplay(state->display);
   711         if (state->verbose & VERBOSE_RENDER) {
   712             SDL_RendererInfo info;
   713 
   714             n = SDL_GetNumRenderDrivers();
   715             if (n == 0) {
   716                 fprintf(stderr, "No built-in render drivers\n");
   717             } else {
   718                 fprintf(stderr, "Built-in render drivers:\n");
   719                 for (i = 0; i < n; ++i) {
   720                     SDL_GetRenderDriverInfo(i, &info);
   721                     PrintRenderer(&info);
   722                 }
   723             }
   724         }
   725 
   726         SDL_zero(fullscreen_mode);
   727         switch (state->depth) {
   728         case 8:
   729             fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8;
   730             break;
   731         case 15:
   732             fullscreen_mode.format = SDL_PIXELFORMAT_RGB555;
   733             break;
   734         case 16:
   735             fullscreen_mode.format = SDL_PIXELFORMAT_RGB565;
   736             break;
   737         case 24:
   738             fullscreen_mode.format = SDL_PIXELFORMAT_RGB24;
   739             break;
   740         default:
   741             fullscreen_mode.format = SDL_PIXELFORMAT_RGB888;
   742             break;
   743         }
   744         fullscreen_mode.refresh_rate = state->refresh_rate;
   745 
   746         state->windows =
   747             (SDL_Window **) SDL_malloc(state->num_windows *
   748                                         sizeof(*state->windows));
   749         if (!state->windows) {
   750             fprintf(stderr, "Out of memory!\n");
   751             return SDL_FALSE;
   752         }
   753         for (i = 0; i < state->num_windows; ++i) {
   754             char title[1024];
   755 
   756             if (state->num_windows > 1) {
   757                 SDL_snprintf(title, SDL_arraysize(title), "%s %d",
   758                              state->window_title, i + 1);
   759             } else {
   760                 SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
   761             }
   762             state->windows[i] =
   763                 SDL_CreateWindow(title, state->window_x, state->window_y,
   764                                  state->window_w, state->window_h,
   765                                  state->window_flags);
   766             if (!state->windows[i]) {
   767                 fprintf(stderr, "Couldn't create window: %s\n",
   768                         SDL_GetError());
   769                 return SDL_FALSE;
   770             }
   771 
   772             if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) {
   773                 fprintf(stderr, "Can't set up fullscreen display mode: %s\n",
   774                         SDL_GetError());
   775                 return SDL_FALSE;
   776             }
   777 
   778             if (state->window_icon) {
   779                 SDL_Surface *icon = LoadIcon(state->window_icon);
   780                 if (icon) {
   781                     SDL_SetWindowIcon(state->windows[i], icon);
   782                     SDL_FreeSurface(icon);
   783                 }
   784             }
   785 
   786             SDL_ShowWindow(state->windows[i]);
   787 
   788             if (!state->skip_renderer
   789                 && (state->renderdriver
   790                     || !(state->window_flags & SDL_WINDOW_OPENGL))) {
   791                 m = -1;
   792                 if (state->renderdriver) {
   793                     SDL_RendererInfo info;
   794                     n = SDL_GetNumRenderDrivers();
   795                     for (j = 0; j < n; ++j) {
   796                         SDL_GetRenderDriverInfo(j, &info);
   797                         if (SDL_strcasecmp(info.name, state->renderdriver) ==
   798                             0) {
   799                             m = j;
   800                             break;
   801                         }
   802                     }
   803                     if (m == n) {
   804                         fprintf(stderr,
   805                                 "Couldn't find render driver named %s",
   806                                 state->renderdriver);
   807                         return SDL_FALSE;
   808                     }
   809                 }
   810                 if (SDL_CreateRenderer
   811                     (state->windows[i], m, state->render_flags) < 0) {
   812                     fprintf(stderr, "Couldn't create renderer: %s\n",
   813                             SDL_GetError());
   814                     return SDL_FALSE;
   815                 }
   816                 if (state->verbose & VERBOSE_RENDER) {
   817                     SDL_RendererInfo info;
   818 
   819                     fprintf(stderr, "Current renderer:\n");
   820                     SDL_GetRendererInfo(&info);
   821                     PrintRenderer(&info);
   822                 }
   823             }
   824         }
   825         SDL_SelectRenderer(state->windows[0]);
   826     }
   827 
   828     if (state->flags & SDL_INIT_AUDIO) {
   829         if (state->verbose & VERBOSE_AUDIO) {
   830             n = SDL_GetNumAudioDrivers();
   831             if (n == 0) {
   832                 fprintf(stderr, "No built-in audio drivers\n");
   833             } else {
   834                 fprintf(stderr, "Built-in audio drivers:");
   835                 for (i = 0; i < n; ++i) {
   836                     if (i > 0) {
   837                         fprintf(stderr, ",");
   838                     }
   839                     fprintf(stderr, " %s", SDL_GetAudioDriver(i));
   840                 }
   841                 fprintf(stderr, "\n");
   842             }
   843         }
   844         if (SDL_AudioInit(state->audiodriver) < 0) {
   845             fprintf(stderr, "Couldn't initialize audio driver: %s\n",
   846                     SDL_GetError());
   847             return SDL_FALSE;
   848         }
   849         if (state->verbose & VERBOSE_VIDEO) {
   850             fprintf(stderr, "Audio driver: %s\n",
   851                     SDL_GetCurrentAudioDriver());
   852         }
   853 
   854         if (SDL_OpenAudio(&state->audiospec, NULL) < 0) {
   855             fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
   856             return SDL_FALSE;
   857         }
   858     }
   859 
   860     return SDL_TRUE;
   861 }
   862 
   863 static void
   864 PrintEvent(SDL_Event * event)
   865 {
   866     fprintf(stderr, "SDL EVENT: ");
   867     switch (event->type) {
   868     case SDL_WINDOWEVENT:
   869         switch (event->window.event) {
   870         case SDL_WINDOWEVENT_SHOWN:
   871             fprintf(stderr, "Window %d shown", event->window.windowID);
   872             break;
   873         case SDL_WINDOWEVENT_HIDDEN:
   874             fprintf(stderr, "Window %d hidden", event->window.windowID);
   875             break;
   876         case SDL_WINDOWEVENT_EXPOSED:
   877             fprintf(stderr, "Window %d exposed", event->window.windowID);
   878             break;
   879         case SDL_WINDOWEVENT_MOVED:
   880             fprintf(stderr, "Window %d moved to %d,%d",
   881                     event->window.windowID, event->window.data1,
   882                     event->window.data2);
   883             break;
   884         case SDL_WINDOWEVENT_RESIZED:
   885             fprintf(stderr, "Window %d resized to %dx%d",
   886                     event->window.windowID, event->window.data1,
   887                     event->window.data2);
   888             break;
   889         case SDL_WINDOWEVENT_MINIMIZED:
   890             fprintf(stderr, "Window %d minimized", event->window.windowID);
   891             break;
   892         case SDL_WINDOWEVENT_MAXIMIZED:
   893             fprintf(stderr, "Window %d maximized", event->window.windowID);
   894             break;
   895         case SDL_WINDOWEVENT_RESTORED:
   896             fprintf(stderr, "Window %d restored", event->window.windowID);
   897             break;
   898         case SDL_WINDOWEVENT_ENTER:
   899             fprintf(stderr, "Mouse entered window %d",
   900                     event->window.windowID);
   901             break;
   902         case SDL_WINDOWEVENT_LEAVE:
   903             fprintf(stderr, "Mouse left window %d", event->window.windowID);
   904             break;
   905         case SDL_WINDOWEVENT_FOCUS_GAINED:
   906             fprintf(stderr, "Window %d gained keyboard focus",
   907                     event->window.windowID);
   908             break;
   909         case SDL_WINDOWEVENT_FOCUS_LOST:
   910             fprintf(stderr, "Window %d lost keyboard focus",
   911                     event->window.windowID);
   912             break;
   913         case SDL_WINDOWEVENT_CLOSE:
   914             fprintf(stderr, "Window %d closed", event->window.windowID);
   915             break;
   916         default:
   917             fprintf(stderr, "Window %d got unknown event %d",
   918                     event->window.windowID, event->window.event);
   919             break;
   920         }
   921         break;
   922     case SDL_KEYDOWN:
   923         fprintf(stderr,
   924                 "Keyboard: key pressed  in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
   925                 event->key.windowID,
   926                 event->key.keysym.scancode,
   927                 SDL_GetScancodeName(event->key.keysym.scancode),
   928                 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
   929         break;
   930     case SDL_KEYUP:
   931         fprintf(stderr,
   932                 "Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
   933                 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_TEXTINPUT:
   939         fprintf(stderr, "Keyboard: text input \"%s\" in window %d",
   940                 event->text.text, event->text.windowID);
   941         break;
   942     case SDL_MOUSEMOTION:
   943         fprintf(stderr, "Mouse: moved to %d,%d (%d,%d) in window %d",
   944                 event->motion.x, event->motion.y,
   945                 event->motion.xrel, event->motion.yrel,
   946                 event->motion.windowID);
   947         break;
   948     case SDL_MOUSEBUTTONDOWN:
   949         fprintf(stderr, "Mouse: button %d pressed at %d,%d in window %d",
   950                 event->button.button, event->button.x, event->button.y,
   951                 event->button.windowID);
   952         break;
   953     case SDL_MOUSEBUTTONUP:
   954         fprintf(stderr, "Mouse: button %d released at %d,%d in window %d",
   955                 event->button.button, event->button.x, event->button.y,
   956                 event->button.windowID);
   957         break;
   958     case SDL_MOUSEWHEEL:
   959         fprintf(stderr,
   960                 "Mouse: wheel scrolled %d in x and %d in y in window %d",
   961                 event->wheel.x, event->wheel.y, event->wheel.windowID);
   962         break;
   963     case SDL_JOYBALLMOTION:
   964         fprintf(stderr, "Joystick %d: ball %d moved by %d,%d",
   965                 event->jball.which, event->jball.ball, event->jball.xrel,
   966                 event->jball.yrel);
   967         break;
   968     case SDL_JOYHATMOTION:
   969         fprintf(stderr, "Joystick %d: hat %d moved to ", event->jhat.which,
   970                 event->jhat.hat);
   971         switch (event->jhat.value) {
   972         case SDL_HAT_CENTERED:
   973             fprintf(stderr, "CENTER");
   974             break;
   975         case SDL_HAT_UP:
   976             fprintf(stderr, "UP");
   977             break;
   978         case SDL_HAT_RIGHTUP:
   979             fprintf(stderr, "RIGHTUP");
   980             break;
   981         case SDL_HAT_RIGHT:
   982             fprintf(stderr, "RIGHT");
   983             break;
   984         case SDL_HAT_RIGHTDOWN:
   985             fprintf(stderr, "RIGHTDOWN");
   986             break;
   987         case SDL_HAT_DOWN:
   988             fprintf(stderr, "DOWN");
   989             break;
   990         case SDL_HAT_LEFTDOWN:
   991             fprintf(stderr, "LEFTDOWN");
   992             break;
   993         case SDL_HAT_LEFT:
   994             fprintf(stderr, "LEFT");
   995             break;
   996         case SDL_HAT_LEFTUP:
   997             fprintf(stderr, "LEFTUP");
   998             break;
   999         default:
  1000             fprintf(stderr, "UNKNOWN");
  1001             break;
  1002         }
  1003         break;
  1004     case SDL_JOYBUTTONDOWN:
  1005         fprintf(stderr, "Joystick %d: button %d pressed",
  1006                 event->jbutton.which, event->jbutton.button);
  1007         break;
  1008     case SDL_JOYBUTTONUP:
  1009         fprintf(stderr, "Joystick %d: button %d released",
  1010                 event->jbutton.which, event->jbutton.button);
  1011         break;
  1012     case SDL_CLIPBOARDUPDATE:
  1013         fprintf(stderr, "Clipboard updated");
  1014         break;
  1015     case SDL_QUIT:
  1016         fprintf(stderr, "Quit requested");
  1017         break;
  1018     case SDL_USEREVENT:
  1019         fprintf(stderr, "User event %d", event->user.code);
  1020         break;
  1021     default:
  1022         fprintf(stderr, "Unknown event %d", event->type);
  1023         break;
  1024     }
  1025     fprintf(stderr, "\n");
  1026 }
  1027 
  1028 void
  1029 CommonEvent(CommonState * state, SDL_Event * event, int *done)
  1030 {
  1031     int i;
  1032 
  1033     if (state->verbose & VERBOSE_EVENT) {
  1034         PrintEvent(event);
  1035     }
  1036 
  1037     switch (event->type) {
  1038     case SDL_WINDOWEVENT:
  1039         switch (event->window.event) {
  1040         case SDL_WINDOWEVENT_CLOSE:
  1041             *done = 1;
  1042             break;
  1043         }
  1044         break;
  1045     case SDL_KEYDOWN:
  1046         switch (event->key.keysym.sym) {
  1047             /* Add hotkeys here */
  1048         case SDLK_c:
  1049             if (event->key.keysym.mod & KMOD_CTRL) {
  1050                 /* Ctrl-C copy awesome text! */
  1051                 SDL_SetClipboardText("SDL rocks!\nYou know it!");
  1052                 printf("Copied text to clipboard\n");
  1053             }
  1054             break;
  1055         case SDLK_v:
  1056             if (event->key.keysym.mod & KMOD_CTRL) {
  1057                 /* Ctrl-V paste awesome text! */
  1058                 char *text = SDL_GetClipboardText();
  1059                 if (*text) {
  1060                     printf("Clipboard: %s\n", text);
  1061                 } else {
  1062                     printf("Clipboard is empty\n");
  1063                 }
  1064                 SDL_free(text);
  1065             }
  1066             break;
  1067         case SDLK_g:
  1068             if (event->key.keysym.mod & KMOD_CTRL) {
  1069                 /* Ctrl-G toggle grab */
  1070             }
  1071             break;
  1072         case SDLK_m:
  1073             if (event->key.keysym.mod & KMOD_CTRL) {
  1074                 /* Ctrl-M maximize */
  1075                 /* FIXME: Which window has focus for this keyboard? */
  1076                 for (i = 0; i < state->num_windows; ++i) {
  1077                     if (SDL_GetWindowFlags(state->windows[i]) & SDL_WINDOW_MAXIMIZED) {
  1078                         SDL_RestoreWindow(state->windows[i]);
  1079                     } else {
  1080                         SDL_MaximizeWindow(state->windows[i]);
  1081                     }
  1082                 }
  1083             }
  1084             break;
  1085         case SDLK_z:
  1086             if (event->key.keysym.mod & KMOD_CTRL) {
  1087                 /* Ctrl-Z minimize */
  1088                 /* FIXME: Which window has focus for this keyboard? */
  1089                 for (i = 0; i < state->num_windows; ++i) {
  1090                     SDL_MinimizeWindow(state->windows[i]);
  1091                 }
  1092             }
  1093             break;
  1094         case SDLK_ESCAPE:
  1095             *done = 1;
  1096             break;
  1097         default:
  1098             break;
  1099         }
  1100         break;
  1101     case SDL_QUIT:
  1102         *done = 1;
  1103         break;
  1104     }
  1105 }
  1106 
  1107 void
  1108 CommonQuit(CommonState * state)
  1109 {
  1110     if (state->flags & SDL_INIT_VIDEO) {
  1111         SDL_VideoQuit();
  1112     }
  1113     if (state->flags & SDL_INIT_AUDIO) {
  1114         SDL_AudioQuit();
  1115     }
  1116     if (state->windows) {
  1117         SDL_free(state->windows);
  1118     }
  1119     SDL_free(state);
  1120 }
  1121 
  1122 /* vi: set ts=4 sw=4 expandtab: */