summaryrefslogtreecommitdiff
path: root/src/contrib/SDL-3.2.20/test/testoverlay.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/contrib/SDL-3.2.20/test/testoverlay.c')
-rw-r--r--src/contrib/SDL-3.2.20/test/testoverlay.c546
1 files changed, 546 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/test/testoverlay.c b/src/contrib/SDL-3.2.20/test/testoverlay.c
new file mode 100644
index 0000000..ac568ee
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/test/testoverlay.c
@@ -0,0 +1,546 @@
1/*
2 Copyright (C) 1997-2025 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 * *
14 * Test of the overlay used for moved pictures, test more closed to real life. *
15 * Running trojan moose :) Coded by Mike Gorchak. *
16 * *
17 ********************************************************************************/
18
19#include <SDL3/SDL_test.h>
20#include <SDL3/SDL_test_common.h>
21#include <SDL3/SDL_main.h>
22#include "testutils.h"
23
24#ifdef SDL_PLATFORM_EMSCRIPTEN
25#include <emscripten/emscripten.h>
26#endif
27
28#include <stdlib.h>
29
30#define MOOSEPIC_W 64
31#define MOOSEPIC_H 88
32
33#define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H)
34#define MOOSEFRAMES_COUNT 10
35
36/* *INDENT-OFF* */ /* clang-format off */
37static SDL_Color MooseColors[84] = {
38 {49, 49, 49, SDL_ALPHA_OPAQUE}
39 , {66, 24, 0, SDL_ALPHA_OPAQUE}
40 , {66, 33, 0, SDL_ALPHA_OPAQUE}
41 , {66, 66, 66, SDL_ALPHA_OPAQUE}
42 ,
43 {66, 115, 49, SDL_ALPHA_OPAQUE}
44 , {74, 33, 0, SDL_ALPHA_OPAQUE}
45 , {74, 41, 16, SDL_ALPHA_OPAQUE}
46 , {82, 33, 8, SDL_ALPHA_OPAQUE}
47 ,
48 {82, 41, 8, SDL_ALPHA_OPAQUE}
49 , {82, 49, 16, SDL_ALPHA_OPAQUE}
50 , {82, 82, 82, SDL_ALPHA_OPAQUE}
51 , {90, 41, 8, SDL_ALPHA_OPAQUE}
52 ,
53 {90, 41, 16, SDL_ALPHA_OPAQUE}
54 , {90, 57, 24, SDL_ALPHA_OPAQUE}
55 , {99, 49, 16, SDL_ALPHA_OPAQUE}
56 , {99, 66, 24, SDL_ALPHA_OPAQUE}
57 ,
58 {99, 66, 33, SDL_ALPHA_OPAQUE}
59 , {99, 74, 33, SDL_ALPHA_OPAQUE}
60 , {107, 57, 24, SDL_ALPHA_OPAQUE}
61 , {107, 82, 41, SDL_ALPHA_OPAQUE}
62 ,
63 {115, 57, 33, SDL_ALPHA_OPAQUE}
64 , {115, 66, 33, SDL_ALPHA_OPAQUE}
65 , {115, 66, 41, SDL_ALPHA_OPAQUE}
66 , {115, 74, 0, SDL_ALPHA_OPAQUE}
67 ,
68 {115, 90, 49, SDL_ALPHA_OPAQUE}
69 , {115, 115, 115, SDL_ALPHA_OPAQUE}
70 , {123, 82, 0, SDL_ALPHA_OPAQUE}
71 , {123, 99, 57, SDL_ALPHA_OPAQUE}
72 ,
73 {132, 66, 41, SDL_ALPHA_OPAQUE}
74 , {132, 74, 41, SDL_ALPHA_OPAQUE}
75 , {132, 90, 8, SDL_ALPHA_OPAQUE}
76 , {132, 99, 33, SDL_ALPHA_OPAQUE}
77 ,
78 {132, 99, 66, SDL_ALPHA_OPAQUE}
79 , {132, 107, 66, SDL_ALPHA_OPAQUE}
80 , {140, 74, 49, SDL_ALPHA_OPAQUE}
81 , {140, 99, 16, SDL_ALPHA_OPAQUE}
82 ,
83 {140, 107, 74, SDL_ALPHA_OPAQUE}
84 , {140, 115, 74, SDL_ALPHA_OPAQUE}
85 , {148, 107, 24, SDL_ALPHA_OPAQUE}
86 , {148, 115, 82, SDL_ALPHA_OPAQUE}
87 ,
88 {148, 123, 74, SDL_ALPHA_OPAQUE}
89 , {148, 123, 90, SDL_ALPHA_OPAQUE}
90 , {156, 115, 33, SDL_ALPHA_OPAQUE}
91 , {156, 115, 90, SDL_ALPHA_OPAQUE}
92 ,
93 {156, 123, 82, SDL_ALPHA_OPAQUE}
94 , {156, 132, 82, SDL_ALPHA_OPAQUE}
95 , {156, 132, 99, SDL_ALPHA_OPAQUE}
96 , {156, 156, 156, SDL_ALPHA_OPAQUE}
97 ,
98 {165, 123, 49, SDL_ALPHA_OPAQUE}
99 , {165, 123, 90, SDL_ALPHA_OPAQUE}
100 , {165, 132, 82, SDL_ALPHA_OPAQUE}
101 , {165, 132, 90, SDL_ALPHA_OPAQUE}
102 ,
103 {165, 132, 99, SDL_ALPHA_OPAQUE}
104 , {165, 140, 90, SDL_ALPHA_OPAQUE}
105 , {173, 132, 57, SDL_ALPHA_OPAQUE}
106 , {173, 132, 99, SDL_ALPHA_OPAQUE}
107 ,
108 {173, 140, 107, SDL_ALPHA_OPAQUE}
109 , {173, 140, 115, SDL_ALPHA_OPAQUE}
110 , {173, 148, 99, SDL_ALPHA_OPAQUE}
111 , {173, 173, 173, SDL_ALPHA_OPAQUE}
112 ,
113 {181, 140, 74, SDL_ALPHA_OPAQUE}
114 , {181, 148, 115, SDL_ALPHA_OPAQUE}
115 , {181, 148, 123, SDL_ALPHA_OPAQUE}
116 , {181, 156, 107, SDL_ALPHA_OPAQUE}
117 ,
118 {189, 148, 123, SDL_ALPHA_OPAQUE}
119 , {189, 156, 82, SDL_ALPHA_OPAQUE}
120 , {189, 156, 123, SDL_ALPHA_OPAQUE}
121 , {189, 156, 132, SDL_ALPHA_OPAQUE}
122 ,
123 {189, 189, 189, SDL_ALPHA_OPAQUE}
124 , {198, 156, 123, SDL_ALPHA_OPAQUE}
125 , {198, 165, 132, SDL_ALPHA_OPAQUE}
126 , {206, 165, 99, SDL_ALPHA_OPAQUE}
127 ,
128 {206, 165, 132, SDL_ALPHA_OPAQUE}
129 , {206, 173, 140, SDL_ALPHA_OPAQUE}
130 , {206, 206, 206, SDL_ALPHA_OPAQUE}
131 , {214, 173, 115, SDL_ALPHA_OPAQUE}
132 ,
133 {214, 173, 140, SDL_ALPHA_OPAQUE}
134 , {222, 181, 148, SDL_ALPHA_OPAQUE}
135 , {222, 189, 132, SDL_ALPHA_OPAQUE}
136 , {222, 189, 156, SDL_ALPHA_OPAQUE}
137 ,
138 {222, 222, 222, SDL_ALPHA_OPAQUE}
139 , {231, 198, 165, SDL_ALPHA_OPAQUE}
140 , {231, 231, 231, SDL_ALPHA_OPAQUE}
141 , {239, 206, 173, SDL_ALPHA_OPAQUE}
142};
143/* *INDENT-ON* */ /* clang-format on */
144
145static SDLTest_CommonState *state;
146static Uint64 next_fps_check;
147static Uint32 frames;
148static const Uint32 fps_check_delay = 5000;
149
150static Uint32 yuv_format = SDL_PIXELFORMAT_YV12;
151static SDL_Surface *MooseYUVSurfaces[MOOSEFRAMES_COUNT];
152static SDL_Texture *MooseTexture = NULL;
153static SDL_FRect displayrect;
154static int window_w;
155static int window_h;
156static int paused = 0;
157static int done = 0;
158static int fpsdelay;
159static bool streaming = true;
160static Uint8 *RawMooseData = NULL;
161
162/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
163static void
164quit(int rc)
165{
166 int i;
167
168 /* If rc is 0, just let main return normally rather than calling exit.
169 * This allows testing of platforms where SDL_main is required and does meaningful cleanup.
170 */
171
172 SDL_free(RawMooseData);
173
174 for (i = 0; i < MOOSEFRAMES_COUNT; i++) {
175 SDL_DestroySurface(MooseYUVSurfaces[i]);
176 }
177
178 SDLTest_CommonQuit(state);
179
180 /* Let 'main()' return normally */
181 if (rc != 0) {
182 exit(rc);
183 }
184}
185
186static void MoveSprites(SDL_Renderer *renderer)
187{
188 static int i = 0;
189
190 if (streaming) {
191 if (!paused) {
192 i = (i + 1) % MOOSEFRAMES_COUNT;
193 /* Test both upload paths for NV12/NV21 formats */
194 if ((yuv_format == SDL_PIXELFORMAT_NV12 || yuv_format == SDL_PIXELFORMAT_NV21) &&
195 (i % 2) == 0) {
196#ifdef TEST_RECT_UPDATE
197 SDL_Rect rect;
198
199 if (i == 0) {
200 rect.x = 0;
201 rect.y = 0;
202 rect.w = MOOSEPIC_W;
203 rect.h = MOOSEPIC_H;
204 } else {
205 rect.x = MOOSEPIC_W / 4;
206 rect.y = MOOSEPIC_H / 4;
207 rect.w = MOOSEPIC_W / 2;
208 rect.h = MOOSEPIC_H / 2;
209 }
210 SDL_UpdateNVTexture(MooseTexture, &rect,
211 (Uint8 *)MooseYUVSurfaces[i]->pixels + rect.y * MooseYUVSurfaces[i]->pitch + rect.x, MooseYUVSurfaces[i]->pitch,
212 (Uint8 *)MooseYUVSurfaces[i]->pixels + MOOSEFRAME_SIZE + (rect.y + 1) / 2 * MooseYUVSurfaces[i]->pitch + (rect.x + 1) / 2, MooseYUVSurfaces[i]->pitch);
213#else
214 SDL_UpdateNVTexture(MooseTexture, NULL,
215 MooseYUVSurfaces[i]->pixels, MooseYUVSurfaces[i]->pitch,
216 (Uint8 *)MooseYUVSurfaces[i]->pixels + MOOSEFRAME_SIZE, MooseYUVSurfaces[i]->pitch);
217#endif
218 } else {
219 SDL_UpdateTexture(MooseTexture, NULL, MooseYUVSurfaces[i]->pixels, MooseYUVSurfaces[i]->pitch);
220 }
221 }
222 SDL_RenderClear(renderer);
223 SDL_RenderTexture(renderer, MooseTexture, NULL, &displayrect);
224 SDL_RenderPresent(renderer);
225 } else {
226 SDL_Texture *tmp;
227
228 /* Test SDL_CreateTextureFromSurface */
229 if (!paused) {
230 i = (i + 1) % MOOSEFRAMES_COUNT;
231 }
232
233 tmp = SDL_CreateTextureFromSurface(renderer, MooseYUVSurfaces[i]);
234 if (!tmp) {
235 SDL_Log("Error %s", SDL_GetError());
236 quit(7);
237 }
238
239 SDL_RenderClear(renderer);
240 SDL_RenderTexture(renderer, tmp, NULL, &displayrect);
241 SDL_RenderPresent(renderer);
242 SDL_DestroyTexture(tmp);
243 }
244}
245
246
247static void loop(void)
248{
249 Uint64 now;
250 int i;
251 SDL_Event event;
252
253 SDL_Renderer *renderer = state->renderers[0]; /* only 1 window */
254
255 /* Check for events */
256 while (SDL_PollEvent(&event)) {
257 SDLTest_CommonEvent(state, &event, &done);
258 SDL_ConvertEventToRenderCoordinates(SDL_GetRenderer(SDL_GetWindowFromEvent(&event)), &event);
259
260 switch (event.type) {
261 case SDL_EVENT_WINDOW_RESIZED:
262 SDL_SetRenderViewport(renderer, NULL);
263 window_w = event.window.data1;
264 window_h = event.window.data2;
265 displayrect.w = (float)window_w;
266 displayrect.h = (float)window_h;
267 break;
268 case SDL_EVENT_MOUSE_BUTTON_DOWN:
269 displayrect.x = event.button.x - window_w / 2;
270 displayrect.y = event.button.y - window_h / 2;
271 break;
272 case SDL_EVENT_MOUSE_MOTION:
273 if (event.motion.state) {
274 displayrect.x = event.motion.x - window_w / 2;
275 displayrect.y = event.motion.y - window_h / 2;
276 }
277 break;
278 case SDL_EVENT_KEY_DOWN:
279 if (event.key.key == SDLK_SPACE) {
280 paused = !paused;
281 break;
282 }
283 if (event.key.key != SDLK_ESCAPE) {
284 break;
285 }
286 break;
287 default:
288 break;
289 }
290 }
291
292#ifndef SDL_PLATFORM_EMSCRIPTEN
293 SDL_Delay(fpsdelay);
294#endif
295
296 for (i = 0; i < state->num_windows; ++i) {
297 if (state->windows[i] == NULL) {
298 continue;
299 }
300 MoveSprites(state->renderers[i]);
301 }
302#ifdef SDL_PLATFORM_EMSCRIPTEN
303 if (done) {
304 emscripten_cancel_main_loop();
305 }
306#endif
307
308 frames++;
309 now = SDL_GetTicks();
310 if (now >= next_fps_check) {
311 /* Print out some timing information */
312 const Uint64 then = next_fps_check - fps_check_delay;
313 const double fps = ((double)frames * 1000) / (now - then);
314 SDL_Log("%2.2f frames per second", fps);
315 next_fps_check = now + fps_check_delay;
316 frames = 0;
317 }
318}
319
320
321int main(int argc, char **argv)
322{
323 SDL_IOStream *handle;
324 int i;
325 int j;
326 int fps = 12;
327 int nodelay = 0;
328 int scale = 5;
329 char *filename = NULL;
330
331 /* Initialize test framework */
332 state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
333 if (!state) {
334 return 1;
335 }
336
337 SDL_zeroa(MooseYUVSurfaces);
338
339 for (i = 1; i < argc;) {
340 int consumed;
341
342 consumed = SDLTest_CommonArg(state, i);
343 if (consumed == 0) {
344 consumed = -1;
345 if (SDL_strcmp(argv[i], "--fps") == 0) {
346 if (argv[i + 1]) {
347 consumed = 2;
348 fps = SDL_atoi(argv[i + 1]);
349 if (fps == 0) {
350 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The --fps option requires an argument [from 1 to 1000], default is 12.");
351 quit(10);
352 }
353 if ((fps < 0) || (fps > 1000)) {
354 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The --fps option must be in range from 1 to 1000, default is 12.");
355 quit(10);
356 }
357 } else {
358 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The --fps option requires an argument [from 1 to 1000], default is 12.");
359 quit(10);
360 }
361 } else if (SDL_strcmp(argv[i], "--nodelay") == 0) {
362 consumed = 1;
363 nodelay = 1;
364 } else if (SDL_strcmp(argv[i], "--nostreaming") == 0) {
365 consumed = 1;
366 streaming = false;
367 } else if (SDL_strcmp(argv[i], "--scale") == 0) {
368 consumed = 2;
369 if (argv[i + 1]) {
370 scale = SDL_atoi(argv[i + 1]);
371 if (scale == 0) {
372 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The --scale option requires an argument [from 1 to 50], default is 5.");
373 quit(10);
374 }
375 if ((scale < 0) || (scale > 50)) {
376 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The --scale option must be in range from 1 to 50, default is 5.");
377 quit(10);
378 }
379 } else {
380 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The --fps option requires an argument [from 1 to 1000], default is 12.");
381 quit(10);
382 }
383 } else if (SDL_strcmp(argv[i], "--yuvformat") == 0) {
384 consumed = 2;
385 if (argv[i + 1]) {
386 char *fmt = argv[i + 1];
387
388 if (SDL_strcmp(fmt, "YV12") == 0) {
389 yuv_format = SDL_PIXELFORMAT_YV12;
390 } else if (SDL_strcmp(fmt, "IYUV") == 0) {
391 yuv_format = SDL_PIXELFORMAT_IYUV;
392 } else if (SDL_strcmp(fmt, "YUY2") == 0) {
393 yuv_format = SDL_PIXELFORMAT_YUY2;
394 } else if (SDL_strcmp(fmt, "UYVY") == 0) {
395 yuv_format = SDL_PIXELFORMAT_UYVY;
396 } else if (SDL_strcmp(fmt, "YVYU") == 0) {
397 yuv_format = SDL_PIXELFORMAT_YVYU;
398 } else if (SDL_strcmp(fmt, "NV12") == 0) {
399 yuv_format = SDL_PIXELFORMAT_NV12;
400 } else if (SDL_strcmp(fmt, "NV21") == 0) {
401 yuv_format = SDL_PIXELFORMAT_NV21;
402 } else {
403 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The --yuvformat option requires one of the: YV12 (default), IYUV, YUY2, UYVY, YVYU, NV12, NV21)");
404 quit(10);
405 }
406 } else {
407 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The --yuvformat option requires one of the: YV12 (default), IYUV, YUY2, UYVY, YVYU, NV12, NV21)");
408 quit(10);
409 }
410 }
411
412 }
413 if (consumed < 0) {
414 static const char *options[] = {
415 "[--fps <frames per second>]",
416 "[--nodelay]",
417 "[--yuvformat <fmt>] (one of the: YV12 (default), IYUV, YUY2, UYVY, YVYU, NV12, NV21)",
418 "[--scale <scale factor>] (initial scale of the overlay)",
419 "[--nostreaming] path that use SDL_CreateTextureFromSurface() not STREAMING texture",
420 NULL
421 };
422 SDLTest_CommonLogUsage(state, argv[0], options);
423 quit(1);
424 }
425 i += consumed;
426 }
427
428 /* Force window size */
429 state->window_w = MOOSEPIC_W * scale;
430 state->window_h = MOOSEPIC_H * scale;
431
432 if (!SDLTest_CommonInit(state)) {
433 quit(2);
434 }
435
436 RawMooseData = (Uint8 *)SDL_malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT);
437 if (!RawMooseData) {
438 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't allocate memory for movie !");
439 quit(1);
440 }
441
442 /* load the trojan moose images */
443 filename = GetResourceFilename(NULL, "moose.dat");
444 if (!filename) {
445 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory");
446 quit(2);
447 }
448 handle = SDL_IOFromFile(filename, "rb");
449 SDL_free(filename);
450 if (!handle) {
451 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !");
452 quit(2);
453 }
454
455 SDL_ReadIO(handle, RawMooseData, MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT);
456
457 SDL_CloseIO(handle);
458
459 /* Create the window and renderer */
460 window_w = MOOSEPIC_W * scale;
461 window_h = MOOSEPIC_H * scale;
462
463 if (state->num_windows != 1) {
464 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Only one window allowed");
465 quit(1);
466 }
467
468 for (i = 0; i < state->num_windows; ++i) {
469 SDL_Renderer *renderer = state->renderers[i];
470
471 if (streaming) {
472 MooseTexture = SDL_CreateTexture(renderer, yuv_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
473 if (!MooseTexture) {
474 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s", SDL_GetError());
475 quit(5);
476 }
477 }
478 }
479
480 /* Uncomment this to check vertex color with a YUV texture */
481 /* SDL_SetTextureColorMod(MooseTexture, 0xff, 0x80, 0x80); */
482
483 for (i = 0; i < MOOSEFRAMES_COUNT; i++) {
484 /* Create RGB SDL_Surface */
485 SDL_Surface *mooseRGBSurface = SDL_CreateSurface(MOOSEPIC_W, MOOSEPIC_H, SDL_PIXELFORMAT_RGB24);
486 if (!mooseRGBSurface) {
487 quit(6);
488 }
489
490 /* Load Moose into a RGB SDL_Surface */
491 {
492 Uint8 *rgb = mooseRGBSurface->pixels;
493 Uint8 *frame = RawMooseData + i * MOOSEFRAME_SIZE;
494 for (j = 0; j < MOOSEFRAME_SIZE; ++j) {
495 rgb[0] = MooseColors[frame[j]].r;
496 rgb[1] = MooseColors[frame[j]].g;
497 rgb[2] = MooseColors[frame[j]].b;
498 rgb += 3;
499 }
500 }
501
502 /* Convert to YUV SDL_Surface */
503 MooseYUVSurfaces[i] = SDL_ConvertSurface(mooseRGBSurface, yuv_format);
504 if (MooseYUVSurfaces[i] == NULL) {
505 quit(7);
506 }
507
508 SDL_DestroySurface(mooseRGBSurface);
509 }
510
511 SDL_free(RawMooseData);
512 RawMooseData = NULL;
513
514 /* set the start frame */
515 i = 0;
516 if (nodelay) {
517 fpsdelay = 0;
518 } else {
519 fpsdelay = 1000 / fps;
520 }
521
522 displayrect.x = 0;
523 displayrect.y = 0;
524 displayrect.w = (float)window_w;
525 displayrect.h = (float)window_h;
526
527 /* Ignore key up events, they don't even get filtered */
528 SDL_SetEventEnabled(SDL_EVENT_KEY_UP, false);
529
530 /* Main render loop */
531 frames = 0;
532 next_fps_check = SDL_GetTicks() + fps_check_delay;
533 done = 0;
534
535 /* Loop, waiting for QUIT or RESIZE */
536#ifdef SDL_PLATFORM_EMSCRIPTEN
537 emscripten_set_main_loop(loop, nodelay ? 0 : fps, 1);
538#else
539 while (!done) {
540 loop();
541 }
542#endif
543
544 quit(0);
545 return 0;
546}