test/testnative.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 24 Dec 2009 21:00:42 +0000
changeset 3601 240a7700a271
parent 3596 f638ded38b8a
child 3685 64ce267332c6
permissions -rw-r--r--
Added missing include for stdio
     1 /* Simple program:  Create a native window and attach an SDL renderer */
     2 
     3 #include <stdio.h>
     4 
     5 #include "testnative.h"
     6 
     7 #define WINDOW_W    640
     8 #define WINDOW_H    480
     9 #define NUM_SPRITES 100
    10 #define MAX_SPEED 	1
    11 
    12 static NativeWindowFactory *factories[] = {
    13 #ifdef TEST_NATIVE_WIN32
    14     &Win32WindowFactory,
    15 #endif
    16 #ifdef TEST_NATIVE_X11
    17     &X11WindowFactory,
    18 #endif
    19 #ifdef TEST_NATIVE_COCOA
    20     &CocoaWindowFactory,
    21 #endif
    22     NULL
    23 };
    24 static NativeWindowFactory *factory = NULL;
    25 static void *native_window;
    26 static SDL_Rect *positions, *velocities;
    27 
    28 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    29 static void
    30 quit(int rc)
    31 {
    32     SDL_VideoQuit();
    33     if (native_window) {
    34         factory->DestroyNativeWindow(native_window);
    35     }
    36     exit(rc);
    37 }
    38 
    39 SDL_TextureID
    40 LoadSprite(SDL_WindowID window, char *file)
    41 {
    42     SDL_Surface *temp;
    43     SDL_TextureID sprite;
    44 
    45     /* Load the sprite image */
    46     temp = SDL_LoadBMP(file);
    47     if (temp == NULL) {
    48         fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
    49         return 0;
    50     }
    51 
    52     /* Set transparent pixel as the pixel at (0,0) */
    53     if (temp->format->palette) {
    54         SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels);
    55     }
    56 
    57     /* Create textures from the image */
    58     SDL_SelectRenderer(window);
    59     sprite = SDL_CreateTextureFromSurface(0, temp);
    60     if (!sprite) {
    61         fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
    62         SDL_FreeSurface(temp);
    63         return 0;
    64     }
    65     SDL_FreeSurface(temp);
    66 
    67     /* We're ready to roll. :) */
    68     return sprite;
    69 }
    70 
    71 void
    72 MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
    73 {
    74     int i, n;
    75     int window_w, window_h;
    76     int sprite_w, sprite_h;
    77     SDL_Rect *position, *velocity;
    78 
    79     SDL_SelectRenderer(window);
    80 
    81     /* Query the sizes */
    82     SDL_GetWindowSize(window, &window_w, &window_h);
    83     SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);
    84 
    85     /* Move the sprite, bounce at the wall, and draw */
    86     n = 0;
    87     SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
    88     SDL_RenderClear();
    89     for (i = 0; i < NUM_SPRITES; ++i) {
    90         position = &positions[i];
    91         velocity = &velocities[i];
    92         position->x += velocity->x;
    93         if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
    94             velocity->x = -velocity->x;
    95             position->x += velocity->x;
    96         }
    97         position->y += velocity->y;
    98         if ((position->y < 0) || (position->y >= (window_h - sprite_h))) {
    99             velocity->y = -velocity->y;
   100             position->y += velocity->y;
   101         }
   102 
   103         /* Blit the sprite onto the screen */
   104         SDL_RenderCopy(sprite, NULL, position);
   105     }
   106 
   107     /* Update the screen! */
   108     SDL_RenderPresent();
   109 }
   110 
   111 int
   112 main(int argc, char *argv[])
   113 {
   114     int i, done;
   115     const char *driver;
   116     SDL_WindowID window;
   117     SDL_TextureID sprite;
   118     int window_w, window_h;
   119     int sprite_w, sprite_h;
   120     SDL_Event event;
   121 
   122     if (SDL_VideoInit(NULL, 0) < 0) {
   123         fprintf(stderr, "Couldn't initialize SDL video: %s\n",
   124                 SDL_GetError());
   125         exit(1);
   126     }
   127     driver = SDL_GetCurrentVideoDriver();
   128 
   129     /* Find a native window driver and create a native window */
   130     for (i = 0; factories[i]; ++i) {
   131         if (SDL_strcmp(driver, factories[i]->tag) == 0) {
   132             factory = factories[i];
   133             break;
   134         }
   135     }
   136     if (!factory) {
   137         fprintf(stderr, "Couldn't find native window code for %s driver\n",
   138                 driver);
   139         quit(2);
   140     }
   141     printf("Creating native window for %s driver\n", driver);
   142     native_window = factory->CreateNativeWindow(WINDOW_W, WINDOW_H);
   143     if (!native_window) {
   144         fprintf(stderr, "Couldn't create native window\n");
   145         quit(3);
   146     }
   147     window = SDL_CreateWindowFrom(native_window);
   148     if (!window) {
   149         fprintf(stderr, "Couldn't create SDL window: %s\n", SDL_GetError());
   150         quit(4);
   151     }
   152     SDL_SetWindowTitle(window, "SDL Native Window Test");
   153 
   154     /* Create the renderer */
   155     if (SDL_CreateRenderer(window, -1, 0) < 0) {
   156         fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
   157         quit(5);
   158     }
   159 
   160     /* Clear the window, load the sprite and go! */
   161     SDL_SelectRenderer(window);
   162     SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   163     SDL_RenderClear();
   164 
   165     sprite = LoadSprite(window, "icon.bmp");
   166     if (!sprite) {
   167         quit(6);
   168     }
   169 
   170     /* Allocate memory for the sprite info */
   171     SDL_GetWindowSize(window, &window_w, &window_h);
   172     SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h);
   173     positions = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));
   174     velocities = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect));
   175     if (!positions || !velocities) {
   176         fprintf(stderr, "Out of memory!\n");
   177         quit(2);
   178     }
   179     srand(time(NULL));
   180     for (i = 0; i < NUM_SPRITES; ++i) {
   181         positions[i].x = rand() % (window_w - sprite_w);
   182         positions[i].y = rand() % (window_h - sprite_h);
   183         positions[i].w = sprite_w;
   184         positions[i].h = sprite_h;
   185         velocities[i].x = 0;
   186         velocities[i].y = 0;
   187         while (!velocities[i].x && !velocities[i].y) {
   188             velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   189             velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   190         }
   191     }
   192 
   193     /* Main render loop */
   194     done = 0;
   195     while (!done) {
   196         /* Check for events */
   197         while (SDL_PollEvent(&event)) {
   198             switch (event.type) {
   199             case SDL_WINDOWEVENT:
   200                 switch (event.window.event) {
   201                 case SDL_WINDOWEVENT_EXPOSED:
   202                     SDL_SelectRenderer(event.window.windowID);
   203                     SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   204                     SDL_RenderClear();
   205                     break;
   206                 }
   207                 break;
   208             case SDL_QUIT:
   209                 done = 1;
   210                 break;
   211             default:
   212                 break;
   213             }
   214         }
   215         MoveSprites(window, sprite);
   216     }
   217 
   218     quit(0);
   219 }
   220 
   221 /* vi: set ts=4 sw=4 expandtab: */