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