cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_test_common.c (54882B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      4
      5  This software is provided 'as-is', without any express or implied
      6  warranty.  In no event will the authors be held liable for any damages
      7  arising from the use of this software.
      8
      9  Permission is granted to anyone to use this software for any purpose,
     10  including commercial applications, and to alter it and redistribute it
     11  freely, subject to the following restrictions:
     12
     13  1. The origin of this software must not be misrepresented; you must not
     14     claim that you wrote the original software. If you use this software
     15     in a product, an acknowledgment in the product documentation would be
     16     appreciated but is not required.
     17  2. Altered source versions must be plainly marked as such, and must not be
     18     misrepresented as being the original software.
     19  3. This notice may not be removed or altered from any source distribution.
     20*/
     21
     22/* Ported from original test\common.c file. */
     23
     24#include "SDL_config.h"
     25#include "SDL_test.h"
     26
     27#include <stdio.h>
     28
     29#define VIDEO_USAGE \
     30"[--video driver] [--renderer driver] [--gldebug] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--min-geometry WxH] [--max-geometry WxH] [--logical WxH] [--scale N] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab] [--allow-highdpi]"
     31
     32#define AUDIO_USAGE \
     33"[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]"
     34
     35SDLTest_CommonState *
     36SDLTest_CommonCreateState(char **argv, Uint32 flags)
     37{
     38    SDLTest_CommonState *state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state));
     39    if (!state) {
     40        SDL_OutOfMemory();
     41        return NULL;
     42    }
     43
     44    /* Initialize some defaults */
     45    state->argv = argv;
     46    state->flags = flags;
     47    state->window_title = argv[0];
     48    state->window_flags = 0;
     49    state->window_x = SDL_WINDOWPOS_UNDEFINED;
     50    state->window_y = SDL_WINDOWPOS_UNDEFINED;
     51    state->window_w = DEFAULT_WINDOW_WIDTH;
     52    state->window_h = DEFAULT_WINDOW_HEIGHT;
     53    state->num_windows = 1;
     54    state->audiospec.freq = 22050;
     55    state->audiospec.format = AUDIO_S16;
     56    state->audiospec.channels = 2;
     57    state->audiospec.samples = 2048;
     58
     59    /* Set some very sane GL defaults */
     60    state->gl_red_size = 3;
     61    state->gl_green_size = 3;
     62    state->gl_blue_size = 2;
     63    state->gl_alpha_size = 0;
     64    state->gl_buffer_size = 0;
     65    state->gl_depth_size = 16;
     66    state->gl_stencil_size = 0;
     67    state->gl_double_buffer = 1;
     68    state->gl_accum_red_size = 0;
     69    state->gl_accum_green_size = 0;
     70    state->gl_accum_blue_size = 0;
     71    state->gl_accum_alpha_size = 0;
     72    state->gl_stereo = 0;
     73    state->gl_multisamplebuffers = 0;
     74    state->gl_multisamplesamples = 0;
     75    state->gl_retained_backing = 1;
     76    state->gl_accelerated = -1;
     77    state->gl_debug = 0;
     78
     79    return state;
     80}
     81
     82int
     83SDLTest_CommonArg(SDLTest_CommonState * state, int index)
     84{
     85    char **argv = state->argv;
     86
     87    if (SDL_strcasecmp(argv[index], "--video") == 0) {
     88        ++index;
     89        if (!argv[index]) {
     90            return -1;
     91        }
     92        state->videodriver = argv[index];
     93        return 2;
     94    }
     95    if (SDL_strcasecmp(argv[index], "--renderer") == 0) {
     96        ++index;
     97        if (!argv[index]) {
     98            return -1;
     99        }
    100        state->renderdriver = argv[index];
    101        return 2;
    102    }
    103    if (SDL_strcasecmp(argv[index], "--gldebug") == 0) {
    104        state->gl_debug = 1;
    105        return 1;
    106    }
    107    if (SDL_strcasecmp(argv[index], "--info") == 0) {
    108        ++index;
    109        if (!argv[index]) {
    110            return -1;
    111        }
    112        if (SDL_strcasecmp(argv[index], "all") == 0) {
    113            state->verbose |=
    114                (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER |
    115                 VERBOSE_EVENT);
    116            return 2;
    117        }
    118        if (SDL_strcasecmp(argv[index], "video") == 0) {
    119            state->verbose |= VERBOSE_VIDEO;
    120            return 2;
    121        }
    122        if (SDL_strcasecmp(argv[index], "modes") == 0) {
    123            state->verbose |= VERBOSE_MODES;
    124            return 2;
    125        }
    126        if (SDL_strcasecmp(argv[index], "render") == 0) {
    127            state->verbose |= VERBOSE_RENDER;
    128            return 2;
    129        }
    130        if (SDL_strcasecmp(argv[index], "event") == 0) {
    131            state->verbose |= VERBOSE_EVENT;
    132            return 2;
    133        }
    134        return -1;
    135    }
    136    if (SDL_strcasecmp(argv[index], "--log") == 0) {
    137        ++index;
    138        if (!argv[index]) {
    139            return -1;
    140        }
    141        if (SDL_strcasecmp(argv[index], "all") == 0) {
    142            SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
    143            return 2;
    144        }
    145        if (SDL_strcasecmp(argv[index], "error") == 0) {
    146            SDL_LogSetPriority(SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_VERBOSE);
    147            return 2;
    148        }
    149        if (SDL_strcasecmp(argv[index], "system") == 0) {
    150            SDL_LogSetPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE);
    151            return 2;
    152        }
    153        if (SDL_strcasecmp(argv[index], "audio") == 0) {
    154            SDL_LogSetPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE);
    155            return 2;
    156        }
    157        if (SDL_strcasecmp(argv[index], "video") == 0) {
    158            SDL_LogSetPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE);
    159            return 2;
    160        }
    161        if (SDL_strcasecmp(argv[index], "render") == 0) {
    162            SDL_LogSetPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE);
    163            return 2;
    164        }
    165        if (SDL_strcasecmp(argv[index], "input") == 0) {
    166            SDL_LogSetPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE);
    167            return 2;
    168        }
    169        return -1;
    170    }
    171    if (SDL_strcasecmp(argv[index], "--display") == 0) {
    172        ++index;
    173        if (!argv[index]) {
    174            return -1;
    175        }
    176        state->display = SDL_atoi(argv[index]);
    177        if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) {
    178            state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
    179            state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
    180        }
    181        if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) {
    182            state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
    183            state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
    184        }
    185        return 2;
    186    }
    187    if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
    188        state->window_flags |= SDL_WINDOW_FULLSCREEN;
    189        state->num_windows = 1;
    190        return 1;
    191    }
    192    if (SDL_strcasecmp(argv[index], "--fullscreen-desktop") == 0) {
    193        state->window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
    194        state->num_windows = 1;
    195        return 1;
    196    }
    197    if (SDL_strcasecmp(argv[index], "--allow-highdpi") == 0) {
    198        state->window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
    199        return 1;
    200    }
    201    if (SDL_strcasecmp(argv[index], "--windows") == 0) {
    202        ++index;
    203        if (!argv[index] || !SDL_isdigit(*argv[index])) {
    204            return -1;
    205        }
    206        if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
    207            state->num_windows = SDL_atoi(argv[index]);
    208        }
    209        return 2;
    210    }
    211    if (SDL_strcasecmp(argv[index], "--title") == 0) {
    212        ++index;
    213        if (!argv[index]) {
    214            return -1;
    215        }
    216        state->window_title = argv[index];
    217        return 2;
    218    }
    219    if (SDL_strcasecmp(argv[index], "--icon") == 0) {
    220        ++index;
    221        if (!argv[index]) {
    222            return -1;
    223        }
    224        state->window_icon = argv[index];
    225        return 2;
    226    }
    227    if (SDL_strcasecmp(argv[index], "--center") == 0) {
    228        state->window_x = SDL_WINDOWPOS_CENTERED;
    229        state->window_y = SDL_WINDOWPOS_CENTERED;
    230        return 1;
    231    }
    232    if (SDL_strcasecmp(argv[index], "--position") == 0) {
    233        char *x, *y;
    234        ++index;
    235        if (!argv[index]) {
    236            return -1;
    237        }
    238        x = argv[index];
    239        y = argv[index];
    240        while (*y && *y != ',') {
    241            ++y;
    242        }
    243        if (!*y) {
    244            return -1;
    245        }
    246        *y++ = '\0';
    247        state->window_x = SDL_atoi(x);
    248        state->window_y = SDL_atoi(y);
    249        return 2;
    250    }
    251    if (SDL_strcasecmp(argv[index], "--geometry") == 0) {
    252        char *w, *h;
    253        ++index;
    254        if (!argv[index]) {
    255            return -1;
    256        }
    257        w = argv[index];
    258        h = argv[index];
    259        while (*h && *h != 'x') {
    260            ++h;
    261        }
    262        if (!*h) {
    263            return -1;
    264        }
    265        *h++ = '\0';
    266        state->window_w = SDL_atoi(w);
    267        state->window_h = SDL_atoi(h);
    268        return 2;
    269    }
    270    if (SDL_strcasecmp(argv[index], "--min-geometry") == 0) {
    271        char *w, *h;
    272        ++index;
    273        if (!argv[index]) {
    274            return -1;
    275        }
    276        w = argv[index];
    277        h = argv[index];
    278        while (*h && *h != 'x') {
    279            ++h;
    280        }
    281        if (!*h) {
    282            return -1;
    283        }
    284        *h++ = '\0';
    285        state->window_minW = SDL_atoi(w);
    286        state->window_minH = SDL_atoi(h);
    287        return 2;
    288    }
    289    if (SDL_strcasecmp(argv[index], "--max-geometry") == 0) {
    290        char *w, *h;
    291        ++index;
    292        if (!argv[index]) {
    293            return -1;
    294        }
    295        w = argv[index];
    296        h = argv[index];
    297        while (*h && *h != 'x') {
    298            ++h;
    299        }
    300        if (!*h) {
    301            return -1;
    302        }
    303        *h++ = '\0';
    304        state->window_maxW = SDL_atoi(w);
    305        state->window_maxH = SDL_atoi(h);
    306        return 2;
    307    }
    308    if (SDL_strcasecmp(argv[index], "--logical") == 0) {
    309        char *w, *h;
    310        ++index;
    311        if (!argv[index]) {
    312            return -1;
    313        }
    314        w = argv[index];
    315        h = argv[index];
    316        while (*h && *h != 'x') {
    317            ++h;
    318        }
    319        if (!*h) {
    320            return -1;
    321        }
    322        *h++ = '\0';
    323        state->logical_w = SDL_atoi(w);
    324        state->logical_h = SDL_atoi(h);
    325        return 2;
    326    }
    327    if (SDL_strcasecmp(argv[index], "--scale") == 0) {
    328        ++index;
    329        if (!argv[index]) {
    330            return -1;
    331        }
    332        state->scale = (float)SDL_atof(argv[index]);
    333        return 2;
    334    }
    335    if (SDL_strcasecmp(argv[index], "--depth") == 0) {
    336        ++index;
    337        if (!argv[index]) {
    338            return -1;
    339        }
    340        state->depth = SDL_atoi(argv[index]);
    341        return 2;
    342    }
    343    if (SDL_strcasecmp(argv[index], "--refresh") == 0) {
    344        ++index;
    345        if (!argv[index]) {
    346            return -1;
    347        }
    348        state->refresh_rate = SDL_atoi(argv[index]);
    349        return 2;
    350    }
    351    if (SDL_strcasecmp(argv[index], "--vsync") == 0) {
    352        state->render_flags |= SDL_RENDERER_PRESENTVSYNC;
    353        return 1;
    354    }
    355    if (SDL_strcasecmp(argv[index], "--noframe") == 0) {
    356        state->window_flags |= SDL_WINDOW_BORDERLESS;
    357        return 1;
    358    }
    359    if (SDL_strcasecmp(argv[index], "--resize") == 0) {
    360        state->window_flags |= SDL_WINDOW_RESIZABLE;
    361        return 1;
    362    }
    363    if (SDL_strcasecmp(argv[index], "--minimize") == 0) {
    364        state->window_flags |= SDL_WINDOW_MINIMIZED;
    365        return 1;
    366    }
    367    if (SDL_strcasecmp(argv[index], "--maximize") == 0) {
    368        state->window_flags |= SDL_WINDOW_MAXIMIZED;
    369        return 1;
    370    }
    371    if (SDL_strcasecmp(argv[index], "--grab") == 0) {
    372        state->window_flags |= SDL_WINDOW_INPUT_GRABBED;
    373        return 1;
    374    }
    375    if (SDL_strcasecmp(argv[index], "--rate") == 0) {
    376        ++index;
    377        if (!argv[index]) {
    378            return -1;
    379        }
    380        state->audiospec.freq = SDL_atoi(argv[index]);
    381        return 2;
    382    }
    383    if (SDL_strcasecmp(argv[index], "--format") == 0) {
    384        ++index;
    385        if (!argv[index]) {
    386            return -1;
    387        }
    388        if (SDL_strcasecmp(argv[index], "U8") == 0) {
    389            state->audiospec.format = AUDIO_U8;
    390            return 2;
    391        }
    392        if (SDL_strcasecmp(argv[index], "S8") == 0) {
    393            state->audiospec.format = AUDIO_S8;
    394            return 2;
    395        }
    396        if (SDL_strcasecmp(argv[index], "U16") == 0) {
    397            state->audiospec.format = AUDIO_U16;
    398            return 2;
    399        }
    400        if (SDL_strcasecmp(argv[index], "U16LE") == 0) {
    401            state->audiospec.format = AUDIO_U16LSB;
    402            return 2;
    403        }
    404        if (SDL_strcasecmp(argv[index], "U16BE") == 0) {
    405            state->audiospec.format = AUDIO_U16MSB;
    406            return 2;
    407        }
    408        if (SDL_strcasecmp(argv[index], "S16") == 0) {
    409            state->audiospec.format = AUDIO_S16;
    410            return 2;
    411        }
    412        if (SDL_strcasecmp(argv[index], "S16LE") == 0) {
    413            state->audiospec.format = AUDIO_S16LSB;
    414            return 2;
    415        }
    416        if (SDL_strcasecmp(argv[index], "S16BE") == 0) {
    417            state->audiospec.format = AUDIO_S16MSB;
    418            return 2;
    419        }
    420        return -1;
    421    }
    422    if (SDL_strcasecmp(argv[index], "--channels") == 0) {
    423        ++index;
    424        if (!argv[index]) {
    425            return -1;
    426        }
    427        state->audiospec.channels = (Uint8) SDL_atoi(argv[index]);
    428        return 2;
    429    }
    430    if (SDL_strcasecmp(argv[index], "--samples") == 0) {
    431        ++index;
    432        if (!argv[index]) {
    433            return -1;
    434        }
    435        state->audiospec.samples = (Uint16) SDL_atoi(argv[index]);
    436        return 2;
    437    }
    438    if ((SDL_strcasecmp(argv[index], "-h") == 0)
    439        || (SDL_strcasecmp(argv[index], "--help") == 0)) {
    440        /* Print the usage message */
    441        return -1;
    442    }
    443    if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) {
    444    /* Debug flag sent by Xcode */
    445        return 2;
    446    }
    447    return 0;
    448}
    449
    450const char *
    451SDLTest_CommonUsage(SDLTest_CommonState * state)
    452{
    453    switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
    454    case SDL_INIT_VIDEO:
    455        return VIDEO_USAGE;
    456    case SDL_INIT_AUDIO:
    457        return AUDIO_USAGE;
    458    case (SDL_INIT_VIDEO | SDL_INIT_AUDIO):
    459        return VIDEO_USAGE " " AUDIO_USAGE;
    460    default:
    461        return "";
    462    }
    463}
    464
    465static void
    466SDLTest_PrintRendererFlag(Uint32 flag)
    467{
    468    switch (flag) {
    469    case SDL_RENDERER_PRESENTVSYNC:
    470        fprintf(stderr, "PresentVSync");
    471        break;
    472    case SDL_RENDERER_ACCELERATED:
    473        fprintf(stderr, "Accelerated");
    474        break;
    475    default:
    476        fprintf(stderr, "0x%8.8x", flag);
    477        break;
    478    }
    479}
    480
    481static void
    482SDLTest_PrintPixelFormat(Uint32 format)
    483{
    484    switch (format) {
    485    case SDL_PIXELFORMAT_UNKNOWN:
    486        fprintf(stderr, "Unknwon");
    487        break;
    488    case SDL_PIXELFORMAT_INDEX1LSB:
    489        fprintf(stderr, "Index1LSB");
    490        break;
    491    case SDL_PIXELFORMAT_INDEX1MSB:
    492        fprintf(stderr, "Index1MSB");
    493        break;
    494    case SDL_PIXELFORMAT_INDEX4LSB:
    495        fprintf(stderr, "Index4LSB");
    496        break;
    497    case SDL_PIXELFORMAT_INDEX4MSB:
    498        fprintf(stderr, "Index4MSB");
    499        break;
    500    case SDL_PIXELFORMAT_INDEX8:
    501        fprintf(stderr, "Index8");
    502        break;
    503    case SDL_PIXELFORMAT_RGB332:
    504        fprintf(stderr, "RGB332");
    505        break;
    506    case SDL_PIXELFORMAT_RGB444:
    507        fprintf(stderr, "RGB444");
    508        break;
    509    case SDL_PIXELFORMAT_RGB555:
    510        fprintf(stderr, "RGB555");
    511        break;
    512    case SDL_PIXELFORMAT_BGR555:
    513        fprintf(stderr, "BGR555");
    514        break;
    515    case SDL_PIXELFORMAT_ARGB4444:
    516        fprintf(stderr, "ARGB4444");
    517        break;
    518    case SDL_PIXELFORMAT_ABGR4444:
    519        fprintf(stderr, "ABGR4444");
    520        break;
    521    case SDL_PIXELFORMAT_ARGB1555:
    522        fprintf(stderr, "ARGB1555");
    523        break;
    524    case SDL_PIXELFORMAT_ABGR1555:
    525        fprintf(stderr, "ABGR1555");
    526        break;
    527    case SDL_PIXELFORMAT_RGB565:
    528        fprintf(stderr, "RGB565");
    529        break;
    530    case SDL_PIXELFORMAT_BGR565:
    531        fprintf(stderr, "BGR565");
    532        break;
    533    case SDL_PIXELFORMAT_RGB24:
    534        fprintf(stderr, "RGB24");
    535        break;
    536    case SDL_PIXELFORMAT_BGR24:
    537        fprintf(stderr, "BGR24");
    538        break;
    539    case SDL_PIXELFORMAT_RGB888:
    540        fprintf(stderr, "RGB888");
    541        break;
    542    case SDL_PIXELFORMAT_BGR888:
    543        fprintf(stderr, "BGR888");
    544        break;
    545    case SDL_PIXELFORMAT_ARGB8888:
    546        fprintf(stderr, "ARGB8888");
    547        break;
    548    case SDL_PIXELFORMAT_RGBA8888:
    549        fprintf(stderr, "RGBA8888");
    550        break;
    551    case SDL_PIXELFORMAT_ABGR8888:
    552        fprintf(stderr, "ABGR8888");
    553        break;
    554    case SDL_PIXELFORMAT_BGRA8888:
    555        fprintf(stderr, "BGRA8888");
    556        break;
    557    case SDL_PIXELFORMAT_ARGB2101010:
    558        fprintf(stderr, "ARGB2101010");
    559        break;
    560    case SDL_PIXELFORMAT_YV12:
    561        fprintf(stderr, "YV12");
    562        break;
    563    case SDL_PIXELFORMAT_IYUV:
    564        fprintf(stderr, "IYUV");
    565        break;
    566    case SDL_PIXELFORMAT_YUY2:
    567        fprintf(stderr, "YUY2");
    568        break;
    569    case SDL_PIXELFORMAT_UYVY:
    570        fprintf(stderr, "UYVY");
    571        break;
    572    case SDL_PIXELFORMAT_YVYU:
    573        fprintf(stderr, "YVYU");
    574        break;
    575    case SDL_PIXELFORMAT_NV12:
    576        fprintf(stderr, "NV12");
    577        break;
    578    case SDL_PIXELFORMAT_NV21:
    579        fprintf(stderr, "NV21");
    580        break;
    581    default:
    582        fprintf(stderr, "0x%8.8x", format);
    583        break;
    584    }
    585}
    586
    587static void
    588SDLTest_PrintRenderer(SDL_RendererInfo * info)
    589{
    590    int i, count;
    591
    592    fprintf(stderr, "  Renderer %s:\n", info->name);
    593
    594    fprintf(stderr, "    Flags: 0x%8.8X", info->flags);
    595    fprintf(stderr, " (");
    596    count = 0;
    597    for (i = 0; i < sizeof(info->flags) * 8; ++i) {
    598        Uint32 flag = (1 << i);
    599        if (info->flags & flag) {
    600            if (count > 0) {
    601                fprintf(stderr, " | ");
    602            }
    603            SDLTest_PrintRendererFlag(flag);
    604            ++count;
    605        }
    606    }
    607    fprintf(stderr, ")\n");
    608
    609    fprintf(stderr, "    Texture formats (%d): ", info->num_texture_formats);
    610    for (i = 0; i < (int) info->num_texture_formats; ++i) {
    611        if (i > 0) {
    612            fprintf(stderr, ", ");
    613        }
    614        SDLTest_PrintPixelFormat(info->texture_formats[i]);
    615    }
    616    fprintf(stderr, "\n");
    617
    618    if (info->max_texture_width || info->max_texture_height) {
    619        fprintf(stderr, "    Max Texture Size: %dx%d\n",
    620                info->max_texture_width, info->max_texture_height);
    621    }
    622}
    623
    624static SDL_Surface *
    625SDLTest_LoadIcon(const char *file)
    626{
    627    SDL_Surface *icon;
    628
    629    /* Load the icon surface */
    630    icon = SDL_LoadBMP(file);
    631    if (icon == NULL) {
    632        fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
    633        return (NULL);
    634    }
    635
    636    if (icon->format->palette) {
    637        /* Set the colorkey */
    638        SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels));
    639    }
    640
    641    return (icon);
    642}
    643
    644SDL_bool
    645SDLTest_CommonInit(SDLTest_CommonState * state)
    646{
    647    int i, j, m, n, w, h;
    648    SDL_DisplayMode fullscreen_mode;
    649
    650    if (state->flags & SDL_INIT_VIDEO) {
    651        if (state->verbose & VERBOSE_VIDEO) {
    652            n = SDL_GetNumVideoDrivers();
    653            if (n == 0) {
    654                fprintf(stderr, "No built-in video drivers\n");
    655            } else {
    656                fprintf(stderr, "Built-in video drivers:");
    657                for (i = 0; i < n; ++i) {
    658                    if (i > 0) {
    659                        fprintf(stderr, ",");
    660                    }
    661                    fprintf(stderr, " %s", SDL_GetVideoDriver(i));
    662                }
    663                fprintf(stderr, "\n");
    664            }
    665        }
    666        if (SDL_VideoInit(state->videodriver) < 0) {
    667            fprintf(stderr, "Couldn't initialize video driver: %s\n",
    668                    SDL_GetError());
    669            return SDL_FALSE;
    670        }
    671        if (state->verbose & VERBOSE_VIDEO) {
    672            fprintf(stderr, "Video driver: %s\n",
    673                    SDL_GetCurrentVideoDriver());
    674        }
    675
    676        /* Upload GL settings */
    677        SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size);
    678        SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size);
    679        SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size);
    680        SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size);
    681        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer);
    682        SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size);
    683        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size);
    684        SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size);
    685        SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size);
    686        SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size);
    687        SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size);
    688        SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size);
    689        SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo);
    690        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers);
    691        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples);
    692        if (state->gl_accelerated >= 0) {
    693            SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
    694                                state->gl_accelerated);
    695        }
    696        SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing);
    697        if (state->gl_major_version) {
    698            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version);
    699            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version);
    700        }
    701        if (state->gl_debug) {
    702            SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
    703        }
    704        if (state->gl_profile_mask) {
    705            SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, state->gl_profile_mask);
    706        }
    707
    708        if (state->verbose & VERBOSE_MODES) {
    709            SDL_Rect bounds;
    710            SDL_DisplayMode mode;
    711            int bpp;
    712            Uint32 Rmask, Gmask, Bmask, Amask;
    713#if SDL_VIDEO_DRIVER_WINDOWS
    714			int adapterIndex = 0;
    715			int outputIndex = 0;
    716#endif
    717            n = SDL_GetNumVideoDisplays();
    718            fprintf(stderr, "Number of displays: %d\n", n);
    719            for (i = 0; i < n; ++i) {
    720                fprintf(stderr, "Display %d: %s\n", i, SDL_GetDisplayName(i));
    721
    722                SDL_zero(bounds);
    723                SDL_GetDisplayBounds(i, &bounds);
    724                fprintf(stderr, "Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y);
    725
    726                SDL_GetDesktopDisplayMode(i, &mode);
    727                SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask,
    728                                           &Bmask, &Amask);
    729                fprintf(stderr,
    730                        "  Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
    731                        mode.w, mode.h, mode.refresh_rate, bpp,
    732                        SDL_GetPixelFormatName(mode.format));
    733                if (Rmask || Gmask || Bmask) {
    734                    fprintf(stderr, "      Red Mask   = 0x%.8x\n", Rmask);
    735                    fprintf(stderr, "      Green Mask = 0x%.8x\n", Gmask);
    736                    fprintf(stderr, "      Blue Mask  = 0x%.8x\n", Bmask);
    737                    if (Amask)
    738                        fprintf(stderr, "      Alpha Mask = 0x%.8x\n", Amask);
    739                }
    740
    741                /* Print available fullscreen video modes */
    742                m = SDL_GetNumDisplayModes(i);
    743                if (m == 0) {
    744                    fprintf(stderr, "No available fullscreen video modes\n");
    745                } else {
    746                    fprintf(stderr, "  Fullscreen video modes:\n");
    747                    for (j = 0; j < m; ++j) {
    748                        SDL_GetDisplayMode(i, j, &mode);
    749                        SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask,
    750                                                   &Gmask, &Bmask, &Amask);
    751                        fprintf(stderr,
    752                                "    Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
    753                                j, mode.w, mode.h, mode.refresh_rate, bpp,
    754                                SDL_GetPixelFormatName(mode.format));
    755                        if (Rmask || Gmask || Bmask) {
    756                            fprintf(stderr, "        Red Mask   = 0x%.8x\n",
    757                                    Rmask);
    758                            fprintf(stderr, "        Green Mask = 0x%.8x\n",
    759                                    Gmask);
    760                            fprintf(stderr, "        Blue Mask  = 0x%.8x\n",
    761                                    Bmask);
    762                            if (Amask)
    763                                fprintf(stderr,
    764                                        "        Alpha Mask = 0x%.8x\n",
    765                                        Amask);
    766                        }
    767                    }
    768                }
    769
    770#if SDL_VIDEO_DRIVER_WINDOWS
    771				/* Print the D3D9 adapter index */
    772				adapterIndex = SDL_Direct3D9GetAdapterIndex( i );
    773				fprintf( stderr, "D3D9 Adapter Index: %d", adapterIndex );
    774
    775				/* Print the DXGI adapter and output indices */
    776				SDL_DXGIGetOutputInfo(i, &adapterIndex, &outputIndex);
    777				fprintf( stderr, "DXGI Adapter Index: %d  Output Index: %d", adapterIndex, outputIndex );
    778#endif
    779            }
    780        }
    781
    782        if (state->verbose & VERBOSE_RENDER) {
    783            SDL_RendererInfo info;
    784
    785            n = SDL_GetNumRenderDrivers();
    786            if (n == 0) {
    787                fprintf(stderr, "No built-in render drivers\n");
    788            } else {
    789                fprintf(stderr, "Built-in render drivers:\n");
    790                for (i = 0; i < n; ++i) {
    791                    SDL_GetRenderDriverInfo(i, &info);
    792                    SDLTest_PrintRenderer(&info);
    793                }
    794            }
    795        }
    796
    797        SDL_zero(fullscreen_mode);
    798        switch (state->depth) {
    799        case 8:
    800            fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8;
    801            break;
    802        case 15:
    803            fullscreen_mode.format = SDL_PIXELFORMAT_RGB555;
    804            break;
    805        case 16:
    806            fullscreen_mode.format = SDL_PIXELFORMAT_RGB565;
    807            break;
    808        case 24:
    809            fullscreen_mode.format = SDL_PIXELFORMAT_RGB24;
    810            break;
    811        default:
    812            fullscreen_mode.format = SDL_PIXELFORMAT_RGB888;
    813            break;
    814        }
    815        fullscreen_mode.refresh_rate = state->refresh_rate;
    816
    817        state->windows =
    818            (SDL_Window **) SDL_malloc(state->num_windows *
    819                                        sizeof(*state->windows));
    820        state->renderers =
    821            (SDL_Renderer **) SDL_malloc(state->num_windows *
    822                                        sizeof(*state->renderers));
    823        state->targets =
    824            (SDL_Texture **) SDL_malloc(state->num_windows *
    825                                        sizeof(*state->targets));
    826        if (!state->windows || !state->renderers) {
    827            fprintf(stderr, "Out of memory!\n");
    828            return SDL_FALSE;
    829        }
    830        for (i = 0; i < state->num_windows; ++i) {
    831            char title[1024];
    832
    833            if (state->num_windows > 1) {
    834                SDL_snprintf(title, SDL_arraysize(title), "%s %d",
    835                             state->window_title, i + 1);
    836            } else {
    837                SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
    838            }
    839            state->windows[i] =
    840                SDL_CreateWindow(title, state->window_x, state->window_y,
    841                                 state->window_w, state->window_h,
    842                                 state->window_flags);
    843            if (!state->windows[i]) {
    844                fprintf(stderr, "Couldn't create window: %s\n",
    845                        SDL_GetError());
    846                return SDL_FALSE;
    847            }
    848            if (state->window_minW || state->window_minH) {
    849                SDL_SetWindowMinimumSize(state->windows[i], state->window_minW, state->window_minH);
    850            }
    851            if (state->window_maxW || state->window_maxH) {
    852                SDL_SetWindowMaximumSize(state->windows[i], state->window_maxW, state->window_maxH);
    853            }
    854            SDL_GetWindowSize(state->windows[i], &w, &h);
    855            if (!(state->window_flags & SDL_WINDOW_RESIZABLE) &&
    856                (w != state->window_w || h != state->window_h)) {
    857                printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h);
    858                state->window_w = w;
    859                state->window_h = h;
    860            }
    861            if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) {
    862                fprintf(stderr, "Can't set up fullscreen display mode: %s\n",
    863                        SDL_GetError());
    864                return SDL_FALSE;
    865            }
    866
    867            if (state->window_icon) {
    868                SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon);
    869                if (icon) {
    870                    SDL_SetWindowIcon(state->windows[i], icon);
    871                    SDL_FreeSurface(icon);
    872                }
    873            }
    874
    875            SDL_ShowWindow(state->windows[i]);
    876
    877            state->renderers[i] = NULL;
    878            state->targets[i] = NULL;
    879
    880            if (!state->skip_renderer
    881                && (state->renderdriver
    882                    || !(state->window_flags & SDL_WINDOW_OPENGL))) {
    883                m = -1;
    884                if (state->renderdriver) {
    885                    SDL_RendererInfo info;
    886                    n = SDL_GetNumRenderDrivers();
    887                    for (j = 0; j < n; ++j) {
    888                        SDL_GetRenderDriverInfo(j, &info);
    889                        if (SDL_strcasecmp(info.name, state->renderdriver) ==
    890                            0) {
    891                            m = j;
    892                            break;
    893                        }
    894                    }
    895                    if (m == -1) {
    896                        fprintf(stderr,
    897                                "Couldn't find render driver named %s",
    898                                state->renderdriver);
    899                        return SDL_FALSE;
    900                    }
    901                }
    902                state->renderers[i] = SDL_CreateRenderer(state->windows[i],
    903                                            m, state->render_flags);
    904                if (!state->renderers[i]) {
    905                    fprintf(stderr, "Couldn't create renderer: %s\n",
    906                            SDL_GetError());
    907                    return SDL_FALSE;
    908                }
    909                if (state->logical_w && state->logical_h) {
    910                    SDL_RenderSetLogicalSize(state->renderers[i], state->logical_w, state->logical_h);
    911                } else if (state->scale) {
    912                    SDL_RenderSetScale(state->renderers[i], state->scale, state->scale);
    913                }
    914                if (state->verbose & VERBOSE_RENDER) {
    915                    SDL_RendererInfo info;
    916
    917                    fprintf(stderr, "Current renderer:\n");
    918                    SDL_GetRendererInfo(state->renderers[i], &info);
    919                    SDLTest_PrintRenderer(&info);
    920                }
    921            }
    922        }
    923    }
    924
    925    if (state->flags & SDL_INIT_AUDIO) {
    926        if (state->verbose & VERBOSE_AUDIO) {
    927            n = SDL_GetNumAudioDrivers();
    928            if (n == 0) {
    929                fprintf(stderr, "No built-in audio drivers\n");
    930            } else {
    931                fprintf(stderr, "Built-in audio drivers:");
    932                for (i = 0; i < n; ++i) {
    933                    if (i > 0) {
    934                        fprintf(stderr, ",");
    935                    }
    936                    fprintf(stderr, " %s", SDL_GetAudioDriver(i));
    937                }
    938                fprintf(stderr, "\n");
    939            }
    940        }
    941        if (SDL_AudioInit(state->audiodriver) < 0) {
    942            fprintf(stderr, "Couldn't initialize audio driver: %s\n",
    943                    SDL_GetError());
    944            return SDL_FALSE;
    945        }
    946        if (state->verbose & VERBOSE_VIDEO) {
    947            fprintf(stderr, "Audio driver: %s\n",
    948                    SDL_GetCurrentAudioDriver());
    949        }
    950
    951        if (SDL_OpenAudio(&state->audiospec, NULL) < 0) {
    952            fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
    953            return SDL_FALSE;
    954        }
    955    }
    956
    957    return SDL_TRUE;
    958}
    959
    960static const char *
    961ControllerAxisName(const SDL_GameControllerAxis axis)
    962{
    963    switch (axis)
    964    {
    965#define AXIS_CASE(ax) case SDL_CONTROLLER_AXIS_##ax: return #ax
    966        AXIS_CASE(INVALID);
    967        AXIS_CASE(LEFTX);
    968        AXIS_CASE(LEFTY);
    969        AXIS_CASE(RIGHTX);
    970        AXIS_CASE(RIGHTY);
    971        AXIS_CASE(TRIGGERLEFT);
    972        AXIS_CASE(TRIGGERRIGHT);
    973#undef AXIS_CASE
    974default: return "???";
    975    }
    976}
    977
    978static const char *
    979ControllerButtonName(const SDL_GameControllerButton button)
    980{
    981    switch (button)
    982    {
    983#define BUTTON_CASE(btn) case SDL_CONTROLLER_BUTTON_##btn: return #btn
    984        BUTTON_CASE(INVALID);
    985        BUTTON_CASE(A);
    986        BUTTON_CASE(B);
    987        BUTTON_CASE(X);
    988        BUTTON_CASE(Y);
    989        BUTTON_CASE(BACK);
    990        BUTTON_CASE(GUIDE);
    991        BUTTON_CASE(START);
    992        BUTTON_CASE(LEFTSTICK);
    993        BUTTON_CASE(RIGHTSTICK);
    994        BUTTON_CASE(LEFTSHOULDER);
    995        BUTTON_CASE(RIGHTSHOULDER);
    996        BUTTON_CASE(DPAD_UP);
    997        BUTTON_CASE(DPAD_DOWN);
    998        BUTTON_CASE(DPAD_LEFT);
    999        BUTTON_CASE(DPAD_RIGHT);
   1000#undef BUTTON_CASE
   1001default: return "???";
   1002    }
   1003}
   1004
   1005static void
   1006SDLTest_PrintEvent(SDL_Event * event)
   1007{
   1008    if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) {
   1009        /* Mouse and finger motion are really spammy */
   1010        return;
   1011    }
   1012
   1013    switch (event->type) {
   1014    case SDL_WINDOWEVENT:
   1015        switch (event->window.event) {
   1016        case SDL_WINDOWEVENT_SHOWN:
   1017            SDL_Log("SDL EVENT: Window %d shown", event->window.windowID);
   1018            break;
   1019        case SDL_WINDOWEVENT_HIDDEN:
   1020            SDL_Log("SDL EVENT: Window %d hidden", event->window.windowID);
   1021            break;
   1022        case SDL_WINDOWEVENT_EXPOSED:
   1023            SDL_Log("SDL EVENT: Window %d exposed", event->window.windowID);
   1024            break;
   1025        case SDL_WINDOWEVENT_MOVED:
   1026            SDL_Log("SDL EVENT: Window %d moved to %d,%d",
   1027                    event->window.windowID, event->window.data1,
   1028                    event->window.data2);
   1029            break;
   1030        case SDL_WINDOWEVENT_RESIZED:
   1031            SDL_Log("SDL EVENT: Window %d resized to %dx%d",
   1032                    event->window.windowID, event->window.data1,
   1033                    event->window.data2);
   1034            break;
   1035        case SDL_WINDOWEVENT_SIZE_CHANGED:
   1036            SDL_Log("SDL EVENT: Window %d changed size to %dx%d",
   1037                    event->window.windowID, event->window.data1,
   1038                    event->window.data2);
   1039            break;
   1040        case SDL_WINDOWEVENT_MINIMIZED:
   1041            SDL_Log("SDL EVENT: Window %d minimized", event->window.windowID);
   1042            break;
   1043        case SDL_WINDOWEVENT_MAXIMIZED:
   1044            SDL_Log("SDL EVENT: Window %d maximized", event->window.windowID);
   1045            break;
   1046        case SDL_WINDOWEVENT_RESTORED:
   1047            SDL_Log("SDL EVENT: Window %d restored", event->window.windowID);
   1048            break;
   1049        case SDL_WINDOWEVENT_ENTER:
   1050            SDL_Log("SDL EVENT: Mouse entered window %d",
   1051                    event->window.windowID);
   1052            break;
   1053        case SDL_WINDOWEVENT_LEAVE:
   1054            SDL_Log("SDL EVENT: Mouse left window %d", event->window.windowID);
   1055            break;
   1056        case SDL_WINDOWEVENT_FOCUS_GAINED:
   1057            SDL_Log("SDL EVENT: Window %d gained keyboard focus",
   1058                    event->window.windowID);
   1059            break;
   1060        case SDL_WINDOWEVENT_FOCUS_LOST:
   1061            SDL_Log("SDL EVENT: Window %d lost keyboard focus",
   1062                    event->window.windowID);
   1063            break;
   1064        case SDL_WINDOWEVENT_CLOSE:
   1065            SDL_Log("SDL EVENT: Window %d closed", event->window.windowID);
   1066            break;
   1067        default:
   1068            SDL_Log("SDL EVENT: Window %d got unknown event %d",
   1069                    event->window.windowID, event->window.event);
   1070            break;
   1071        }
   1072        break;
   1073    case SDL_KEYDOWN:
   1074        SDL_Log("SDL EVENT: Keyboard: key pressed  in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
   1075                event->key.windowID,
   1076                event->key.keysym.scancode,
   1077                SDL_GetScancodeName(event->key.keysym.scancode),
   1078                event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
   1079        break;
   1080    case SDL_KEYUP:
   1081        SDL_Log("SDL EVENT: Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
   1082                event->key.windowID,
   1083                event->key.keysym.scancode,
   1084                SDL_GetScancodeName(event->key.keysym.scancode),
   1085                event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
   1086        break;
   1087    case SDL_TEXTINPUT:
   1088        SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %d",
   1089                event->text.text, event->text.windowID);
   1090        break;
   1091    case SDL_MOUSEMOTION:
   1092        SDL_Log("SDL EVENT: Mouse: moved to %d,%d (%d,%d) in window %d",
   1093                event->motion.x, event->motion.y,
   1094                event->motion.xrel, event->motion.yrel,
   1095                event->motion.windowID);
   1096        break;
   1097    case SDL_MOUSEBUTTONDOWN:
   1098        SDL_Log("SDL EVENT: Mouse: button %d pressed at %d,%d with click count %d in window %d",
   1099                event->button.button, event->button.x, event->button.y, event->button.clicks,
   1100                event->button.windowID);
   1101        break;
   1102    case SDL_MOUSEBUTTONUP:
   1103        SDL_Log("SDL EVENT: Mouse: button %d released at %d,%d with click count %d in window %d",
   1104                event->button.button, event->button.x, event->button.y, event->button.clicks,
   1105                event->button.windowID);
   1106        break;
   1107    case SDL_MOUSEWHEEL:
   1108        SDL_Log("SDL EVENT: Mouse: wheel scrolled %d in x and %d in y in window %d",
   1109                event->wheel.x, event->wheel.y, event->wheel.windowID);
   1110        break;
   1111    case SDL_JOYDEVICEADDED:
   1112        SDL_Log("SDL EVENT: Joystick index %d attached",
   1113            event->jdevice.which);
   1114        break;
   1115    case SDL_JOYDEVICEREMOVED:
   1116        SDL_Log("SDL EVENT: Joystick %d removed",
   1117            event->jdevice.which);
   1118        break;
   1119    case SDL_JOYBALLMOTION:
   1120        SDL_Log("SDL EVENT: Joystick %d: ball %d moved by %d,%d",
   1121                event->jball.which, event->jball.ball, event->jball.xrel,
   1122                event->jball.yrel);
   1123        break;
   1124    case SDL_JOYHATMOTION:
   1125        {
   1126            const char *position = "UNKNOWN";
   1127            switch (event->jhat.value) {
   1128            case SDL_HAT_CENTERED:
   1129                position = "CENTER";
   1130                break;
   1131            case SDL_HAT_UP:
   1132                position = "UP";
   1133                break;
   1134            case SDL_HAT_RIGHTUP:
   1135                position = "RIGHTUP";
   1136                break;
   1137            case SDL_HAT_RIGHT:
   1138                position = "RIGHT";
   1139                break;
   1140            case SDL_HAT_RIGHTDOWN:
   1141                position = "RIGHTDOWN";
   1142                break;
   1143            case SDL_HAT_DOWN:
   1144                position = "DOWN";
   1145                break;
   1146            case SDL_HAT_LEFTDOWN:
   1147                position = "LEFTDOWN";
   1148                break;
   1149            case SDL_HAT_LEFT:
   1150                position = "LEFT";
   1151                break;
   1152            case SDL_HAT_LEFTUP:
   1153                position = "LEFTUP";
   1154                break;
   1155            }
   1156            SDL_Log("SDL EVENT: Joystick %d: hat %d moved to %s", event->jhat.which,
   1157                event->jhat.hat, position);
   1158        }
   1159        break;
   1160    case SDL_JOYBUTTONDOWN:
   1161        SDL_Log("SDL EVENT: Joystick %d: button %d pressed",
   1162                event->jbutton.which, event->jbutton.button);
   1163        break;
   1164    case SDL_JOYBUTTONUP:
   1165        SDL_Log("SDL EVENT: Joystick %d: button %d released",
   1166                event->jbutton.which, event->jbutton.button);
   1167        break;
   1168    case SDL_CONTROLLERDEVICEADDED:
   1169        SDL_Log("SDL EVENT: Controller index %d attached",
   1170            event->cdevice.which);
   1171        break;
   1172    case SDL_CONTROLLERDEVICEREMOVED:
   1173        SDL_Log("SDL EVENT: Controller %d removed",
   1174            event->cdevice.which);
   1175        break;
   1176    case SDL_CONTROLLERAXISMOTION:
   1177        SDL_Log("SDL EVENT: Controller %d axis %d ('%s') value: %d",
   1178            event->caxis.which,
   1179            event->caxis.axis,
   1180            ControllerAxisName((SDL_GameControllerAxis)event->caxis.axis),
   1181            event->caxis.value);
   1182        break;
   1183    case SDL_CONTROLLERBUTTONDOWN:
   1184        SDL_Log("SDL EVENT: Controller %d button %d ('%s') down",
   1185            event->cbutton.which, event->cbutton.button,
   1186            ControllerButtonName((SDL_GameControllerButton)event->cbutton.button));
   1187        break;
   1188    case SDL_CONTROLLERBUTTONUP:
   1189        SDL_Log("SDL EVENT: Controller %d button %d ('%s') up",
   1190            event->cbutton.which, event->cbutton.button,
   1191            ControllerButtonName((SDL_GameControllerButton)event->cbutton.button));
   1192        break;
   1193    case SDL_CLIPBOARDUPDATE:
   1194        SDL_Log("SDL EVENT: Clipboard updated");
   1195        break;
   1196
   1197    case SDL_FINGERDOWN:
   1198    case SDL_FINGERUP:
   1199        SDL_Log("SDL EVENT: Finger: %s touch=%ld, finger=%ld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
   1200                (event->type == SDL_FINGERDOWN) ? "down" : "up",
   1201                (long) event->tfinger.touchId,
   1202                (long) event->tfinger.fingerId,
   1203                event->tfinger.x, event->tfinger.y,
   1204                event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
   1205        break;
   1206
   1207    case SDL_RENDER_DEVICE_RESET:
   1208        SDL_Log("SDL EVENT: render device reset");
   1209        break;
   1210    case SDL_RENDER_TARGETS_RESET:
   1211        SDL_Log("SDL EVENT: render targets reset");
   1212        break;
   1213
   1214    case SDL_QUIT:
   1215        SDL_Log("SDL EVENT: Quit requested");
   1216        break;
   1217    case SDL_USEREVENT:
   1218        SDL_Log("SDL EVENT: User event %d", event->user.code);
   1219        break;
   1220    default:
   1221        SDL_Log("Unknown event %d", event->type);
   1222        break;
   1223    }
   1224}
   1225
   1226static void
   1227SDLTest_ScreenShot(SDL_Renderer *renderer)
   1228{
   1229    SDL_Rect viewport;
   1230    SDL_Surface *surface;
   1231
   1232    if (!renderer) {
   1233        return;
   1234    }
   1235
   1236    SDL_RenderGetViewport(renderer, &viewport);
   1237    surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24,
   1238#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1239                    0x00FF0000, 0x0000FF00, 0x000000FF,
   1240#else
   1241                    0x000000FF, 0x0000FF00, 0x00FF0000,
   1242#endif
   1243                    0x00000000);
   1244    if (!surface) {
   1245        fprintf(stderr, "Couldn't create surface: %s\n", SDL_GetError());
   1246        return;
   1247    }
   1248
   1249    if (SDL_RenderReadPixels(renderer, NULL, surface->format->format,
   1250                             surface->pixels, surface->pitch) < 0) {
   1251        fprintf(stderr, "Couldn't read screen: %s\n", SDL_GetError());
   1252        SDL_free(surface);
   1253        return;
   1254    }
   1255
   1256    if (SDL_SaveBMP(surface, "screenshot.bmp") < 0) {
   1257        fprintf(stderr, "Couldn't save screenshot.bmp: %s\n", SDL_GetError());
   1258        SDL_free(surface);
   1259        return;
   1260    }
   1261}
   1262
   1263static void
   1264FullscreenTo(int index, int windowId)
   1265{
   1266    Uint32 flags;
   1267    struct SDL_Rect rect = { 0, 0, 0, 0 };
   1268    SDL_Window *window = SDL_GetWindowFromID(windowId);
   1269    if (!window) {
   1270        return;
   1271    }
   1272
   1273    SDL_GetDisplayBounds( index, &rect );
   1274
   1275    flags = SDL_GetWindowFlags(window);
   1276    if (flags & SDL_WINDOW_FULLSCREEN) {
   1277        SDL_SetWindowFullscreen( window, SDL_FALSE );
   1278        SDL_Delay( 15 );
   1279    }
   1280
   1281    SDL_SetWindowPosition( window, rect.x, rect.y );
   1282    SDL_SetWindowFullscreen( window, SDL_TRUE );
   1283}
   1284
   1285void
   1286SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
   1287{
   1288    int i;
   1289    static SDL_MouseMotionEvent lastEvent;
   1290
   1291    if (state->verbose & VERBOSE_EVENT) {
   1292        SDLTest_PrintEvent(event);
   1293    }
   1294
   1295    switch (event->type) {
   1296    case SDL_WINDOWEVENT:
   1297        switch (event->window.event) {
   1298        case SDL_WINDOWEVENT_CLOSE:
   1299            {
   1300                SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
   1301                if (window) {
   1302                    for (i = 0; i < state->num_windows; ++i) {
   1303                        if (window == state->windows[i]) {
   1304                            if (state->targets[i]) {
   1305                                SDL_DestroyTexture(state->targets[i]);
   1306                                state->targets[i] = NULL;
   1307                            }
   1308                            if (state->renderers[i]) {
   1309                                SDL_DestroyRenderer(state->renderers[i]);
   1310                                state->renderers[i] = NULL;
   1311                            }
   1312                            SDL_DestroyWindow(state->windows[i]);
   1313                            state->windows[i] = NULL;
   1314                            break;
   1315                        }
   1316                    }
   1317                }
   1318            }
   1319            break;
   1320        }
   1321        break;
   1322    case SDL_KEYDOWN: {
   1323        SDL_bool withControl = !!(event->key.keysym.mod & KMOD_CTRL);
   1324        SDL_bool withShift = !!(event->key.keysym.mod & KMOD_SHIFT);
   1325        SDL_bool withAlt = !!(event->key.keysym.mod & KMOD_ALT);
   1326
   1327        switch (event->key.keysym.sym) {
   1328            /* Add hotkeys here */
   1329        case SDLK_PRINTSCREEN: {
   1330                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1331                if (window) {
   1332                    for (i = 0; i < state->num_windows; ++i) {
   1333                        if (window == state->windows[i]) {
   1334                            SDLTest_ScreenShot(state->renderers[i]);
   1335                        }
   1336                    }
   1337                }
   1338            }
   1339            break;
   1340        case SDLK_EQUALS:
   1341            if (withControl) {
   1342                /* Ctrl-+ double the size of the window */
   1343                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1344                if (window) {
   1345                    int w, h;
   1346                    SDL_GetWindowSize(window, &w, &h);
   1347                    SDL_SetWindowSize(window, w*2, h*2);
   1348                }
   1349            }
   1350            break;
   1351        case SDLK_MINUS:
   1352            if (withControl) {
   1353                /* Ctrl-- half the size of the window */
   1354                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1355                if (window) {
   1356                    int w, h;
   1357                    SDL_GetWindowSize(window, &w, &h);
   1358                    SDL_SetWindowSize(window, w/2, h/2);
   1359                }
   1360            }
   1361            break;
   1362        case SDLK_c:
   1363            if (withControl) {
   1364                /* Ctrl-C copy awesome text! */
   1365                SDL_SetClipboardText("SDL rocks!\nYou know it!");
   1366                printf("Copied text to clipboard\n");
   1367            }
   1368            if (withAlt) {
   1369                /* Alt-C toggle a render clip rectangle */
   1370                for (i = 0; i < state->num_windows; ++i) {
   1371                    int w, h;
   1372                    if (state->renderers[i]) {
   1373                        SDL_Rect clip;
   1374                        SDL_GetWindowSize(state->windows[i], &w, &h);
   1375                        SDL_RenderGetClipRect(state->renderers[i], &clip);
   1376                        if (SDL_RectEmpty(&clip)) {
   1377                            clip.x = w/4;
   1378                            clip.y = h/4;
   1379                            clip.w = w/2;
   1380                            clip.h = h/2;
   1381                            SDL_RenderSetClipRect(state->renderers[i], &clip);
   1382                        } else {
   1383                            SDL_RenderSetClipRect(state->renderers[i], NULL);
   1384                        }
   1385                    }
   1386                }
   1387            }
   1388            if (withShift) {
   1389                SDL_Window *current_win = SDL_GetKeyboardFocus();
   1390                if (current_win) {
   1391                    const SDL_bool shouldCapture = (SDL_GetWindowFlags(current_win) & SDL_WINDOW_MOUSE_CAPTURE) == 0;
   1392                    const int rc = SDL_CaptureMouse(shouldCapture);
   1393                    SDL_Log("%sapturing mouse %s!\n", shouldCapture ? "C" : "Unc", (rc == 0) ? "succeeded" : "failed");
   1394                }
   1395            }
   1396            break;
   1397        case SDLK_v:
   1398            if (withControl) {
   1399                /* Ctrl-V paste awesome text! */
   1400                char *text = SDL_GetClipboardText();
   1401                if (*text) {
   1402                    printf("Clipboard: %s\n", text);
   1403                } else {
   1404                    printf("Clipboard is empty\n");
   1405                }
   1406                SDL_free(text);
   1407            }
   1408            break;
   1409        case SDLK_g:
   1410            if (withControl) {
   1411                /* Ctrl-G toggle grab */
   1412                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1413                if (window) {
   1414                    SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window) ? SDL_TRUE : SDL_FALSE);
   1415                }
   1416            }
   1417            break;
   1418        case SDLK_m:
   1419            if (withControl) {
   1420                /* Ctrl-M maximize */
   1421                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1422                if (window) {
   1423                    Uint32 flags = SDL_GetWindowFlags(window);
   1424                    if (flags & SDL_WINDOW_MAXIMIZED) {
   1425                        SDL_RestoreWindow(window);
   1426                    } else {
   1427                        SDL_MaximizeWindow(window);
   1428                    }
   1429                }
   1430            }
   1431            break;
   1432        case SDLK_r:
   1433            if (withControl) {
   1434                /* Ctrl-R toggle mouse relative mode */
   1435                SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode() ? SDL_TRUE : SDL_FALSE);
   1436            }
   1437            break;
   1438        case SDLK_z:
   1439            if (withControl) {
   1440                /* Ctrl-Z minimize */
   1441                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1442                if (window) {
   1443                    SDL_MinimizeWindow(window);
   1444                }
   1445            }
   1446            break;
   1447        case SDLK_RETURN:
   1448            if (withControl) {
   1449                /* Ctrl-Enter toggle fullscreen */
   1450                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1451                if (window) {
   1452                    Uint32 flags = SDL_GetWindowFlags(window);
   1453                    if (flags & SDL_WINDOW_FULLSCREEN) {
   1454                        SDL_SetWindowFullscreen(window, SDL_FALSE);
   1455                    } else {
   1456                        SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
   1457                    }
   1458                }
   1459            } else if (withAlt) {
   1460                /* Alt-Enter toggle fullscreen desktop */
   1461                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1462                if (window) {
   1463                    Uint32 flags = SDL_GetWindowFlags(window);
   1464                    if (flags & SDL_WINDOW_FULLSCREEN) {
   1465                        SDL_SetWindowFullscreen(window, SDL_FALSE);
   1466                    } else {
   1467                        SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
   1468                    }
   1469                }
   1470            } else if (withShift) {
   1471                /* Shift-Enter toggle fullscreen desktop / fullscreen */
   1472                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1473                if (window) {
   1474                    Uint32 flags = SDL_GetWindowFlags(window);
   1475                    if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
   1476                        SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
   1477                    } else {
   1478                        SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
   1479                    }
   1480                }
   1481            }
   1482
   1483            break;
   1484        case SDLK_b:
   1485            if (withControl) {
   1486                /* Ctrl-B toggle window border */
   1487                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1488                if (window) {
   1489                    const Uint32 flags = SDL_GetWindowFlags(window);
   1490                    const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0) ? SDL_TRUE : SDL_FALSE;
   1491                    SDL_SetWindowBordered(window, b);
   1492                }
   1493            }
   1494            break;
   1495        case SDLK_a:
   1496            if (withControl) {
   1497                /* Ctrl-A reports absolute mouse position. */
   1498                int x, y;
   1499                const Uint32 mask = SDL_GetGlobalMouseState(&x, &y);
   1500                SDL_Log("ABSOLUTE MOUSE: (%d, %d)%s%s%s%s%s\n", x, y,
   1501                        (mask & SDL_BUTTON_LMASK) ? " [LBUTTON]" : "",
   1502                        (mask & SDL_BUTTON_MMASK) ? " [MBUTTON]" : "",
   1503                        (mask & SDL_BUTTON_RMASK) ? " [RBUTTON]" : "",
   1504                        (mask & SDL_BUTTON_X1MASK) ? " [X2BUTTON]" : "",
   1505                        (mask & SDL_BUTTON_X2MASK) ? " [X2BUTTON]" : "");
   1506            }
   1507            break;
   1508        case SDLK_0:
   1509            if (withControl) {
   1510                SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1511                SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Test Message", "You're awesome!", window);
   1512            }
   1513            break;
   1514        case SDLK_1:
   1515            if (withControl) {
   1516                FullscreenTo(0, event->key.windowID);
   1517            }
   1518            break;
   1519        case SDLK_2:
   1520            if (withControl) {
   1521                FullscreenTo(1, event->key.windowID);
   1522            }
   1523            break;
   1524        case SDLK_ESCAPE:
   1525            *done = 1;
   1526            break;
   1527        case SDLK_SPACE:
   1528        {
   1529            char message[256];
   1530            SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
   1531
   1532            SDL_snprintf(message, sizeof(message), "(%i, %i), rel (%i, %i)\n", lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel);
   1533            SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Last mouse position", message, window);
   1534            break;
   1535        }
   1536        default:
   1537            break;
   1538        }
   1539        break;
   1540    }
   1541    case SDL_QUIT:
   1542        *done = 1;
   1543        break;
   1544    case SDL_MOUSEMOTION:
   1545        lastEvent = event->motion;
   1546        break;
   1547    }
   1548}
   1549
   1550void
   1551SDLTest_CommonQuit(SDLTest_CommonState * state)
   1552{
   1553    int i;
   1554
   1555    SDL_free(state->windows);
   1556    if (state->targets) {
   1557        for (i = 0; i < state->num_windows; ++i) {
   1558            if (state->targets[i]) {
   1559                SDL_DestroyTexture(state->targets[i]);
   1560            }
   1561        }
   1562        SDL_free(state->targets);
   1563    }
   1564    if (state->renderers) {
   1565        for (i = 0; i < state->num_windows; ++i) {
   1566            if (state->renderers[i]) {
   1567                SDL_DestroyRenderer(state->renderers[i]);
   1568            }
   1569        }
   1570        SDL_free(state->renderers);
   1571    }
   1572    if (state->flags & SDL_INIT_VIDEO) {
   1573        SDL_VideoQuit();
   1574    }
   1575    if (state->flags & SDL_INIT_AUDIO) {
   1576        SDL_AudioQuit();
   1577    }
   1578    SDL_free(state);
   1579    SDL_Quit();
   1580}
   1581
   1582/* vi: set ts=4 sw=4 expandtab: */