Imported Upstream version 2.0.8
[platform/upstream/SDL.git] / test / testrendercopyex.c
1 /*
2   Copyright (C) 1997-2018 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:  Move N sprites around on the screen as fast as possible */
13
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <time.h>
17
18 #ifdef __EMSCRIPTEN__
19 #include <emscripten/emscripten.h>
20 #endif
21
22 #include "SDL_test_common.h"
23
24
25 static SDLTest_CommonState *state;
26
27 typedef struct {
28     SDL_Window *window;
29     SDL_Renderer *renderer;
30     SDL_Texture *background;
31     SDL_Texture *sprite;
32     SDL_Rect sprite_rect;
33     int scale_direction;
34 } DrawState;
35
36 DrawState *drawstates;
37 int done;
38
39 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
40 static void
41 quit(int rc)
42 {
43     SDLTest_CommonQuit(state);
44     exit(rc);
45 }
46
47 SDL_Texture *
48 LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
49 {
50     SDL_Surface *temp;
51     SDL_Texture *texture;
52
53     /* Load the sprite image */
54     temp = SDL_LoadBMP(file);
55     if (temp == NULL) {
56         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
57         return NULL;
58     }
59
60     /* Set transparent pixel as the pixel at (0,0) */
61     if (transparent) {
62         if (temp->format->palette) {
63             SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
64         } else {
65             switch (temp->format->BitsPerPixel) {
66             case 15:
67                 SDL_SetColorKey(temp, SDL_TRUE,
68                                 (*(Uint16 *) temp->pixels) & 0x00007FFF);
69                 break;
70             case 16:
71                 SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
72                 break;
73             case 24:
74                 SDL_SetColorKey(temp, SDL_TRUE,
75                                 (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
76                 break;
77             case 32:
78                 SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
79                 break;
80             }
81         }
82     }
83
84     /* Create textures from the image */
85     texture = SDL_CreateTextureFromSurface(renderer, temp);
86     if (!texture) {
87         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
88         SDL_FreeSurface(temp);
89         return NULL;
90     }
91     SDL_FreeSurface(temp);
92
93     /* We're ready to roll. :) */
94     return texture;
95 }
96
97 void
98 Draw(DrawState *s)
99 {
100     SDL_Rect viewport;
101     SDL_Texture *target;
102     SDL_Point *center=NULL;
103     SDL_Point origin = {0,0};
104
105     SDL_RenderGetViewport(s->renderer, &viewport);
106
107     target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h);
108     SDL_SetRenderTarget(s->renderer, target);
109
110     /* Draw the background */
111     SDL_RenderCopy(s->renderer, s->background, NULL, NULL);
112
113     /* Scale and draw the sprite */
114     s->sprite_rect.w += s->scale_direction;
115     s->sprite_rect.h += s->scale_direction;
116     if (s->scale_direction > 0) {
117         center = &origin;
118         if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
119             s->scale_direction = -1;
120         }
121     } else {
122         if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
123             s->scale_direction = 1;
124         }
125     }
126     s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
127     s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
128
129     SDL_RenderCopyEx(s->renderer, s->sprite, NULL, &s->sprite_rect, (double)s->sprite_rect.w, center, (SDL_RendererFlip)s->scale_direction);
130
131     SDL_SetRenderTarget(s->renderer, NULL);
132     SDL_RenderCopy(s->renderer, target, NULL, NULL);
133     SDL_DestroyTexture(target);
134
135     /* Update the screen! */
136     SDL_RenderPresent(s->renderer);
137     /* SDL_Delay(10); */
138 }
139
140 void loop()
141 {
142     int i;
143     SDL_Event event;
144
145     /* Check for events */
146
147     while (SDL_PollEvent(&event)) {
148         SDLTest_CommonEvent(state, &event, &done);
149     }
150     for (i = 0; i < state->num_windows; ++i) {
151         if (state->windows[i] == NULL)
152             continue;
153         Draw(&drawstates[i]);
154     }
155 #ifdef __EMSCRIPTEN__
156     if (done) {
157         emscripten_cancel_main_loop();
158     }
159 #endif
160 }
161
162 int
163 main(int argc, char *argv[])
164 {
165     int i;
166     int frames;
167     Uint32 then, now;
168
169     /* Enable standard application logging */
170     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
171
172     /* Initialize test framework */
173     state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
174     if (!state) {
175         return 1;
176     }
177     for (i = 1; i < argc;) {
178         int consumed;
179
180         consumed = SDLTest_CommonArg(state, i);
181         if (consumed == 0) {
182             SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state));
183             return 1;
184         }
185         i += consumed;
186     }
187     if (!SDLTest_CommonInit(state)) {
188         quit(2);
189     }
190
191     drawstates = SDL_stack_alloc(DrawState, state->num_windows);
192     for (i = 0; i < state->num_windows; ++i) {
193         DrawState *drawstate = &drawstates[i];
194
195         drawstate->window = state->windows[i];
196         drawstate->renderer = state->renderers[i];
197         drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
198         drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
199         if (!drawstate->sprite || !drawstate->background) {
200             quit(2);
201         }
202         SDL_QueryTexture(drawstate->sprite, NULL, NULL,
203                          &drawstate->sprite_rect.w, &drawstate->sprite_rect.h);
204         drawstate->scale_direction = 1;
205     }
206
207     /* Main render loop */
208     frames = 0;
209     then = SDL_GetTicks();
210     done = 0;
211
212 #ifdef __EMSCRIPTEN__
213     emscripten_set_main_loop(loop, 0, 1);
214 #else
215     while (!done) {
216         ++frames;
217         loop();
218         }
219 #endif
220     /* Print out some timing information */
221     now = SDL_GetTicks();
222     if (now > then) {
223         double fps = ((double) frames * 1000) / (now - then);
224         SDL_Log("%2.2f frames per second\n", fps);
225     }
226
227     SDL_stack_free(drawstates);
228
229     quit(0);
230     return 0;
231 }
232
233 /* vi: set ts=4 sw=4 expandtab: */