test/testnative.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Dec 2017 16:08:09 -0800
changeset 11730 ac6c607e065c
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Enable building the Metal renderer by default, and weak link the Metal framework so the SDL library is safe to use on older Macs
Also generate iOS versions of the Metal shaders
slouken@5535
     1
/*
slouken@10737
     2
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@3057
    12
/* Simple program:  Create a native window and attach an SDL renderer */
slouken@3057
    13
slouken@3601
    14
#include <stdio.h>
philipp@7442
    15
#include <stdlib.h> /* for srand() */
philipp@7442
    16
#include <time.h> /* for time() */
slouken@3601
    17
slouken@3057
    18
#include "testnative.h"
slouken@3057
    19
slouken@3057
    20
#define WINDOW_W    640
slouken@3057
    21
#define WINDOW_H    480
slouken@3057
    22
#define NUM_SPRITES 100
slouken@7191
    23
#define MAX_SPEED   1
slouken@3057
    24
slouken@3057
    25
static NativeWindowFactory *factories[] = {
slouken@5062
    26
#ifdef TEST_NATIVE_WINDOWS
slouken@5062
    27
    &WindowsWindowFactory,
slouken@3057
    28
#endif
slouken@3057
    29
#ifdef TEST_NATIVE_X11
slouken@3057
    30
    &X11WindowFactory,
slouken@3057
    31
#endif
slouken@3057
    32
#ifdef TEST_NATIVE_COCOA
slouken@3057
    33
    &CocoaWindowFactory,
slouken@3057
    34
#endif
slouken@3057
    35
    NULL
slouken@3057
    36
};
slouken@3057
    37
static NativeWindowFactory *factory = NULL;
slouken@3057
    38
static void *native_window;
slouken@3057
    39
static SDL_Rect *positions, *velocities;
slouken@3057
    40
slouken@3057
    41
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
slouken@3057
    42
static void
slouken@3057
    43
quit(int rc)
slouken@3057
    44
{
slouken@3057
    45
    SDL_VideoQuit();
slouken@3057
    46
    if (native_window) {
slouken@3060
    47
        factory->DestroyNativeWindow(native_window);
slouken@3057
    48
    }
slouken@3057
    49
    exit(rc);
slouken@3057
    50
}
slouken@3057
    51
slouken@3685
    52
SDL_Texture *
slouken@6175
    53
LoadSprite(SDL_Renderer *renderer, char *file)
slouken@3057
    54
{
slouken@3057
    55
    SDL_Surface *temp;
slouken@3685
    56
    SDL_Texture *sprite;
slouken@3057
    57
slouken@3057
    58
    /* Load the sprite image */
slouken@3057
    59
    temp = SDL_LoadBMP(file);
slouken@3057
    60
    if (temp == NULL) {
aschiffler@7639
    61
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
slouken@3057
    62
        return 0;
slouken@3057
    63
    }
slouken@3057
    64
slouken@3057
    65
    /* Set transparent pixel as the pixel at (0,0) */
slouken@3057
    66
    if (temp->format->palette) {
slouken@6256
    67
        SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels);
slouken@3057
    68
    }
slouken@3057
    69
slouken@3057
    70
    /* Create textures from the image */
slouken@6175
    71
    sprite = SDL_CreateTextureFromSurface(renderer, temp);
slouken@3057
    72
    if (!sprite) {
aschiffler@7639
    73
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
slouken@3057
    74
        SDL_FreeSurface(temp);
slouken@3057
    75
        return 0;
slouken@3057
    76
    }
slouken@3057
    77
    SDL_FreeSurface(temp);
slouken@3057
    78
slouken@3057
    79
    /* We're ready to roll. :) */
slouken@3057
    80
    return sprite;
slouken@3057
    81
}
slouken@3057
    82
slouken@3057
    83
void
slouken@6175
    84
MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
slouken@3057
    85
{
slouken@3057
    86
    int sprite_w, sprite_h;
slouken@6175
    87
    int i;
slouken@6175
    88
    SDL_Rect viewport;
slouken@3057
    89
    SDL_Rect *position, *velocity;
slouken@3057
    90
slouken@3057
    91
    /* Query the sizes */
slouken@6175
    92
    SDL_RenderGetViewport(renderer, &viewport);
slouken@3057
    93
    SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);
slouken@3057
    94
slouken@6175
    95
    /* Draw a gray background */
slouken@6175
    96
    SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
slouken@6175
    97
    SDL_RenderClear(renderer);
slouken@6175
    98
slouken@3057
    99
    /* Move the sprite, bounce at the wall, and draw */
slouken@3057
   100
    for (i = 0; i < NUM_SPRITES; ++i) {
slouken@3057
   101
        position = &positions[i];
slouken@3057
   102
        velocity = &velocities[i];
slouken@3057
   103
        position->x += velocity->x;
slouken@6175
   104
        if ((position->x < 0) || (position->x >= (viewport.w - sprite_w))) {
slouken@3057
   105
            velocity->x = -velocity->x;
slouken@3057
   106
            position->x += velocity->x;
slouken@3057
   107
        }
slouken@3057
   108
        position->y += velocity->y;
slouken@6175
   109
        if ((position->y < 0) || (position->y >= (viewport.h - sprite_h))) {
slouken@3057
   110
            velocity->y = -velocity->y;
slouken@3057
   111
            position->y += velocity->y;
slouken@3057
   112
        }
slouken@3057
   113
slouken@3057
   114
        /* Blit the sprite onto the screen */
slouken@6175
   115
        SDL_RenderCopy(renderer, sprite, NULL, position);
slouken@3057
   116
    }
slouken@3057
   117
slouken@3057
   118
    /* Update the screen! */
slouken@6175
   119
    SDL_RenderPresent(renderer);
slouken@3057
   120
}
slouken@3057
   121
slouken@3057
   122
int
slouken@3057
   123
main(int argc, char *argv[])
slouken@3057
   124
{
slouken@3057
   125
    int i, done;
slouken@3057
   126
    const char *driver;
slouken@3685
   127
    SDL_Window *window;
slouken@6175
   128
    SDL_Renderer *renderer;
slouken@3685
   129
    SDL_Texture *sprite;
slouken@3057
   130
    int window_w, window_h;
slouken@3057
   131
    int sprite_w, sprite_h;
slouken@3057
   132
    SDL_Event event;
slouken@3057
   133
philipp@9922
   134
    /* Enable standard application logging */
aschiffler@7639
   135
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   136
slouken@6175
   137
    if (SDL_VideoInit(NULL) < 0) {
aschiffler@7639
   138
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL video: %s\n",
slouken@3057
   139
                SDL_GetError());
slouken@3057
   140
        exit(1);
slouken@3057
   141
    }
slouken@3057
   142
    driver = SDL_GetCurrentVideoDriver();
slouken@3057
   143
slouken@3057
   144
    /* Find a native window driver and create a native window */
slouken@3057
   145
    for (i = 0; factories[i]; ++i) {
slouken@3057
   146
        if (SDL_strcmp(driver, factories[i]->tag) == 0) {
slouken@3057
   147
            factory = factories[i];
slouken@3057
   148
            break;
slouken@3057
   149
        }
slouken@3057
   150
    }
slouken@3057
   151
    if (!factory) {
aschiffler@7639
   152
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find native window code for %s driver\n",
slouken@3057
   153
                driver);
slouken@3057
   154
        quit(2);
slouken@3057
   155
    }
aschiffler@7639
   156
    SDL_Log("Creating native window for %s driver\n", driver);
slouken@3060
   157
    native_window = factory->CreateNativeWindow(WINDOW_W, WINDOW_H);
slouken@3057
   158
    if (!native_window) {
aschiffler@7639
   159
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create native window\n");
slouken@3057
   160
        quit(3);
slouken@3057
   161
    }
slouken@3057
   162
    window = SDL_CreateWindowFrom(native_window);
slouken@3057
   163
    if (!window) {
aschiffler@7639
   164
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create SDL window: %s\n", SDL_GetError());
slouken@3057
   165
        quit(4);
slouken@3057
   166
    }
slouken@3057
   167
    SDL_SetWindowTitle(window, "SDL Native Window Test");
slouken@3057
   168
slouken@3057
   169
    /* Create the renderer */
slouken@6175
   170
    renderer = SDL_CreateRenderer(window, -1, 0);
slouken@6175
   171
    if (!renderer) {
aschiffler@7639
   172
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
slouken@3057
   173
        quit(5);
slouken@3057
   174
    }
slouken@3057
   175
slouken@3057
   176
    /* Clear the window, load the sprite and go! */
slouken@6175
   177
    SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
slouken@6175
   178
    SDL_RenderClear(renderer);
slouken@3057
   179
slouken@6175
   180
    sprite = LoadSprite(renderer, "icon.bmp");
slouken@3057
   181
    if (!sprite) {
slouken@3057
   182
        quit(6);
slouken@3057
   183
    }
slouken@3057
   184
slouken@3057
   185
    /* Allocate memory for the sprite info */
slouken@3057
   186
    SDL_GetWindowSize(window, &window_w, &window_h);
slouken@3057
   187
    SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);
slouken@3057
   188
    positions = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));
slouken@3057
   189
    velocities = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));
slouken@3057
   190
    if (!positions || !velocities) {
aschiffler@7639
   191
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n");
slouken@3057
   192
        quit(2);
slouken@3057
   193
    }
slouken@3057
   194
    srand(time(NULL));
slouken@3057
   195
    for (i = 0; i < NUM_SPRITES; ++i) {
slouken@3057
   196
        positions[i].x = rand() % (window_w - sprite_w);
slouken@3057
   197
        positions[i].y = rand() % (window_h - sprite_h);
slouken@3057
   198
        positions[i].w = sprite_w;
slouken@3057
   199
        positions[i].h = sprite_h;
slouken@3057
   200
        velocities[i].x = 0;
slouken@3057
   201
        velocities[i].y = 0;
slouken@3057
   202
        while (!velocities[i].x && !velocities[i].y) {
slouken@3057
   203
            velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
slouken@3057
   204
            velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
slouken@3057
   205
        }
slouken@3057
   206
    }
slouken@3057
   207
slouken@3057
   208
    /* Main render loop */
slouken@3057
   209
    done = 0;
slouken@3057
   210
    while (!done) {
slouken@3057
   211
        /* Check for events */
slouken@3057
   212
        while (SDL_PollEvent(&event)) {
slouken@3057
   213
            switch (event.type) {
slouken@3057
   214
            case SDL_WINDOWEVENT:
slouken@3057
   215
                switch (event.window.event) {
slouken@3057
   216
                case SDL_WINDOWEVENT_EXPOSED:
slouken@6175
   217
                    SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
slouken@6175
   218
                    SDL_RenderClear(renderer);
slouken@3057
   219
                    break;
slouken@3057
   220
                }
slouken@3057
   221
                break;
slouken@3057
   222
            case SDL_QUIT:
slouken@3057
   223
                done = 1;
slouken@3057
   224
                break;
slouken@3057
   225
            default:
slouken@3057
   226
                break;
slouken@3057
   227
            }
slouken@3057
   228
        }
slouken@6175
   229
        MoveSprites(renderer, sprite);
slouken@3057
   230
    }
slouken@3057
   231
slouken@3057
   232
    quit(0);
philipp@7443
   233
philipp@7443
   234
    return 0; /* to prevent compiler warning */
slouken@3057
   235
}
slouken@3057
   236
slouken@3057
   237
/* vi: set ts=4 sw=4 expandtab: */