1 /*
2   Copyright (C) 1997-2021 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 
13 /* Simple program:  draw as many random objects on the screen as possible */
14 
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <time.h>
18 
19 #ifdef __EMSCRIPTEN__
20 #include <emscripten/emscripten.h>
21 #endif
22 
23 #include "SDL_test_common.h"
24 
25 #define NUM_OBJECTS 100
26 
27 static SDLTest_CommonState *state;
28 static int num_objects;
29 static SDL_bool cycle_color;
30 static SDL_bool cycle_alpha;
31 static int cycle_direction = 1;
32 static int current_alpha = 255;
33 static int current_color = 255;
34 static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
35 static Uint32 next_fps_check, frames;
36 static const Uint32 fps_check_delay = 5000;
37 
38 int done;
39 
40 void
DrawPoints(SDL_Renderer * renderer)41 DrawPoints(SDL_Renderer * renderer)
42 {
43     int i;
44     int x, y;
45     SDL_Rect viewport;
46 
47     /* Query the sizes */
48     SDL_RenderGetViewport(renderer, &viewport);
49 
50     for (i = 0; i < num_objects * 4; ++i) {
51         /* Cycle the color and alpha, if desired */
52         if (cycle_color) {
53             current_color += cycle_direction;
54             if (current_color < 0) {
55                 current_color = 0;
56                 cycle_direction = -cycle_direction;
57             }
58             if (current_color > 255) {
59                 current_color = 255;
60                 cycle_direction = -cycle_direction;
61             }
62         }
63         if (cycle_alpha) {
64             current_alpha += cycle_direction;
65             if (current_alpha < 0) {
66                 current_alpha = 0;
67                 cycle_direction = -cycle_direction;
68             }
69             if (current_alpha > 255) {
70                 current_alpha = 255;
71                 cycle_direction = -cycle_direction;
72             }
73         }
74         SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color,
75                                (Uint8) current_color, (Uint8) current_alpha);
76 
77         x = rand() % viewport.w;
78         y = rand() % viewport.h;
79         SDL_RenderDrawPoint(renderer, x, y);
80     }
81 }
82 
83 void
DrawLines(SDL_Renderer * renderer)84 DrawLines(SDL_Renderer * renderer)
85 {
86     int i;
87     int x1, y1, x2, y2;
88     SDL_Rect viewport;
89 
90     /* Query the sizes */
91     SDL_RenderGetViewport(renderer, &viewport);
92 
93     for (i = 0; i < num_objects; ++i) {
94         /* Cycle the color and alpha, if desired */
95         if (cycle_color) {
96             current_color += cycle_direction;
97             if (current_color < 0) {
98                 current_color = 0;
99                 cycle_direction = -cycle_direction;
100             }
101             if (current_color > 255) {
102                 current_color = 255;
103                 cycle_direction = -cycle_direction;
104             }
105         }
106         if (cycle_alpha) {
107             current_alpha += cycle_direction;
108             if (current_alpha < 0) {
109                 current_alpha = 0;
110                 cycle_direction = -cycle_direction;
111             }
112             if (current_alpha > 255) {
113                 current_alpha = 255;
114                 cycle_direction = -cycle_direction;
115             }
116         }
117         SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color,
118                                (Uint8) current_color, (Uint8) current_alpha);
119 
120         if (i == 0) {
121             SDL_RenderDrawLine(renderer, 0, 0, viewport.w - 1, viewport.h - 1);
122             SDL_RenderDrawLine(renderer, 0, viewport.h - 1, viewport.w - 1, 0);
123             SDL_RenderDrawLine(renderer, 0, viewport.h / 2, viewport.w - 1, viewport.h / 2);
124             SDL_RenderDrawLine(renderer, viewport.w / 2, 0, viewport.w / 2, viewport.h - 1);
125         } else {
126             x1 = (rand() % (viewport.w*2)) - viewport.w;
127             x2 = (rand() % (viewport.w*2)) - viewport.w;
128             y1 = (rand() % (viewport.h*2)) - viewport.h;
129             y2 = (rand() % (viewport.h*2)) - viewport.h;
130             SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
131         }
132     }
133 }
134 
135 void
DrawRects(SDL_Renderer * renderer)136 DrawRects(SDL_Renderer * renderer)
137 {
138     int i;
139     SDL_Rect rect;
140     SDL_Rect viewport;
141 
142     /* Query the sizes */
143     SDL_RenderGetViewport(renderer, &viewport);
144 
145     for (i = 0; i < num_objects / 4; ++i) {
146         /* Cycle the color and alpha, if desired */
147         if (cycle_color) {
148             current_color += cycle_direction;
149             if (current_color < 0) {
150                 current_color = 0;
151                 cycle_direction = -cycle_direction;
152             }
153             if (current_color > 255) {
154                 current_color = 255;
155                 cycle_direction = -cycle_direction;
156             }
157         }
158         if (cycle_alpha) {
159             current_alpha += cycle_direction;
160             if (current_alpha < 0) {
161                 current_alpha = 0;
162                 cycle_direction = -cycle_direction;
163             }
164             if (current_alpha > 255) {
165                 current_alpha = 255;
166                 cycle_direction = -cycle_direction;
167             }
168         }
169         SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color,
170                                (Uint8) current_color, (Uint8) current_alpha);
171 
172         rect.w = rand() % (viewport.h / 2);
173         rect.h = rand() % (viewport.h / 2);
174         rect.x = (rand() % (viewport.w*2) - viewport.w) - (rect.w / 2);
175         rect.y = (rand() % (viewport.h*2) - viewport.h) - (rect.h / 2);
176         SDL_RenderFillRect(renderer, &rect);
177     }
178 }
179 
180 void
loop()181 loop()
182 {
183     Uint32 now;
184     int i;
185     SDL_Event event;
186 
187     /* Check for events */
188     while (SDL_PollEvent(&event)) {
189         SDLTest_CommonEvent(state, &event, &done);
190     }
191     for (i = 0; i < state->num_windows; ++i) {
192         SDL_Renderer *renderer = state->renderers[i];
193         if (state->windows[i] == NULL)
194             continue;
195         SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
196         SDL_RenderClear(renderer);
197 
198         DrawRects(renderer);
199         DrawLines(renderer);
200         DrawPoints(renderer);
201 
202         SDL_RenderPresent(renderer);
203     }
204 #ifdef __EMSCRIPTEN__
205     if (done) {
206         emscripten_cancel_main_loop();
207     }
208 #endif
209     frames++;
210     now = SDL_GetTicks();
211     if (SDL_TICKS_PASSED(now, next_fps_check)) {
212         /* Print out some timing information */
213         const Uint32 then = next_fps_check - fps_check_delay;
214         const double fps = ((double) frames * 1000) / (now - then);
215         SDL_Log("%2.2f frames per second\n", fps);
216         next_fps_check = now + fps_check_delay;
217         frames = 0;
218     }
219 
220 }
221 
222 int
main(int argc,char * argv[])223 main(int argc, char *argv[])
224 {
225     int i;
226 
227     /* Enable standard application logging */
228     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
229 
230     /* Initialize parameters */
231     num_objects = NUM_OBJECTS;
232 
233     /* Initialize test framework */
234     state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
235     if (!state) {
236         return 1;
237     }
238     for (i = 1; i < argc;) {
239         int consumed;
240 
241         consumed = SDLTest_CommonArg(state, i);
242         if (consumed == 0) {
243             consumed = -1;
244             if (SDL_strcasecmp(argv[i], "--blend") == 0) {
245                 if (argv[i + 1]) {
246                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
247                         blendMode = SDL_BLENDMODE_NONE;
248                         consumed = 2;
249                     } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
250                         blendMode = SDL_BLENDMODE_BLEND;
251                         consumed = 2;
252                     } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
253                         blendMode = SDL_BLENDMODE_ADD;
254                         consumed = 2;
255                     } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
256                         blendMode = SDL_BLENDMODE_MOD;
257                         consumed = 2;
258                     }
259                 }
260             } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
261                 cycle_color = SDL_TRUE;
262                 consumed = 1;
263             } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
264                 cycle_alpha = SDL_TRUE;
265                 consumed = 1;
266             } else if (SDL_isdigit(*argv[i])) {
267                 num_objects = SDL_atoi(argv[i]);
268                 consumed = 1;
269             }
270         }
271         if (consumed < 0) {
272             static const char *options[] = {
273                 "[--blend none|blend|add|mod]",
274                 "[--cyclecolor]",
275                 "[--cyclealpha]",
276                 "[num_objects]",
277                 NULL };
278             SDLTest_CommonLogUsage(state, argv[0], options);
279             return 1;
280         }
281         i += consumed;
282     }
283     if (!SDLTest_CommonInit(state)) {
284         return 2;
285     }
286 
287     /* Create the windows and initialize the renderers */
288     for (i = 0; i < state->num_windows; ++i) {
289         SDL_Renderer *renderer = state->renderers[i];
290         SDL_SetRenderDrawBlendMode(renderer, blendMode);
291         SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
292         SDL_RenderClear(renderer);
293     }
294 
295     srand((unsigned int)time(NULL));
296 
297     /* Main render loop */
298     frames = 0;
299     next_fps_check = SDL_GetTicks() + fps_check_delay;
300     done = 0;
301 
302 #ifdef __EMSCRIPTEN__
303     emscripten_set_main_loop(loop, 0, 1);
304 #else
305     while (!done) {
306         loop();
307     }
308 #endif
309 
310 
311     SDLTest_CommonQuit(state);
312 
313     return 0;
314 }
315 
316 /* vi: set ts=4 sw=4 expandtab: */
317