2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
22 /* Ported from original test\common.c file. */
24 #include "SDL_config.h"
30 "[--video driver] [--renderer driver] [--gldebug] [--info all|video|modes|render|event] [--log all|error|system|audio|video|render|input] [--display N] [--fullscreen | --fullscreen-desktop | --windows N] [--title title] [--icon icon.bmp] [--center | --position X,Y] [--geometry WxH] [--min-geometry WxH] [--max-geometry WxH] [--logical WxH] [--scale N] [--depth N] [--refresh R] [--vsync] [--noframe] [--resize] [--minimize] [--maximize] [--grab] [--allow-highdpi]"
33 "[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]"
36 SDLTest_CommonCreateState(char **argv, Uint32 flags)
38 SDLTest_CommonState *state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state));
44 /* Initialize some defaults */
47 state->window_title = argv[0];
48 state->window_flags = 0;
49 state->window_x = SDL_WINDOWPOS_UNDEFINED;
50 state->window_y = SDL_WINDOWPOS_UNDEFINED;
51 state->window_w = DEFAULT_WINDOW_WIDTH;
52 state->window_h = DEFAULT_WINDOW_HEIGHT;
53 state->num_windows = 1;
54 state->audiospec.freq = 22050;
55 state->audiospec.format = AUDIO_S16;
56 state->audiospec.channels = 2;
57 state->audiospec.samples = 2048;
59 /* Set some very sane GL defaults */
60 state->gl_red_size = 3;
61 state->gl_green_size = 3;
62 state->gl_blue_size = 2;
63 state->gl_alpha_size = 0;
64 state->gl_buffer_size = 0;
65 state->gl_depth_size = 16;
66 state->gl_stencil_size = 0;
67 state->gl_double_buffer = 1;
68 state->gl_accum_red_size = 0;
69 state->gl_accum_green_size = 0;
70 state->gl_accum_blue_size = 0;
71 state->gl_accum_alpha_size = 0;
73 state->gl_multisamplebuffers = 0;
74 state->gl_multisamplesamples = 0;
75 state->gl_retained_backing = 1;
76 state->gl_accelerated = -1;
83 SDLTest_CommonArg(SDLTest_CommonState * state, int index)
85 char **argv = state->argv;
87 if (SDL_strcasecmp(argv[index], "--video") == 0) {
92 state->videodriver = argv[index];
95 if (SDL_strcasecmp(argv[index], "--renderer") == 0) {
100 state->renderdriver = argv[index];
103 if (SDL_strcasecmp(argv[index], "--gldebug") == 0) {
107 if (SDL_strcasecmp(argv[index], "--info") == 0) {
112 if (SDL_strcasecmp(argv[index], "all") == 0) {
114 (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER |
118 if (SDL_strcasecmp(argv[index], "video") == 0) {
119 state->verbose |= VERBOSE_VIDEO;
122 if (SDL_strcasecmp(argv[index], "modes") == 0) {
123 state->verbose |= VERBOSE_MODES;
126 if (SDL_strcasecmp(argv[index], "render") == 0) {
127 state->verbose |= VERBOSE_RENDER;
130 if (SDL_strcasecmp(argv[index], "event") == 0) {
131 state->verbose |= VERBOSE_EVENT;
136 if (SDL_strcasecmp(argv[index], "--log") == 0) {
141 if (SDL_strcasecmp(argv[index], "all") == 0) {
142 SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
145 if (SDL_strcasecmp(argv[index], "error") == 0) {
146 SDL_LogSetPriority(SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_VERBOSE);
149 if (SDL_strcasecmp(argv[index], "system") == 0) {
150 SDL_LogSetPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE);
153 if (SDL_strcasecmp(argv[index], "audio") == 0) {
154 SDL_LogSetPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE);
157 if (SDL_strcasecmp(argv[index], "video") == 0) {
158 SDL_LogSetPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE);
161 if (SDL_strcasecmp(argv[index], "render") == 0) {
162 SDL_LogSetPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE);
165 if (SDL_strcasecmp(argv[index], "input") == 0) {
166 SDL_LogSetPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE);
171 if (SDL_strcasecmp(argv[index], "--display") == 0) {
176 state->display = SDL_atoi(argv[index]);
177 if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) {
178 state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
179 state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
181 if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) {
182 state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
183 state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
187 if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) {
188 state->window_flags |= SDL_WINDOW_FULLSCREEN;
189 state->num_windows = 1;
192 if (SDL_strcasecmp(argv[index], "--fullscreen-desktop") == 0) {
193 state->window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
194 state->num_windows = 1;
197 if (SDL_strcasecmp(argv[index], "--allow-highdpi") == 0) {
198 state->window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
201 if (SDL_strcasecmp(argv[index], "--windows") == 0) {
203 if (!argv[index] || !SDL_isdigit(*argv[index])) {
206 if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) {
207 state->num_windows = SDL_atoi(argv[index]);
211 if (SDL_strcasecmp(argv[index], "--title") == 0) {
216 state->window_title = argv[index];
219 if (SDL_strcasecmp(argv[index], "--icon") == 0) {
224 state->window_icon = argv[index];
227 if (SDL_strcasecmp(argv[index], "--center") == 0) {
228 state->window_x = SDL_WINDOWPOS_CENTERED;
229 state->window_y = SDL_WINDOWPOS_CENTERED;
232 if (SDL_strcasecmp(argv[index], "--position") == 0) {
240 while (*y && *y != ',') {
247 state->window_x = SDL_atoi(x);
248 state->window_y = SDL_atoi(y);
251 if (SDL_strcasecmp(argv[index], "--geometry") == 0) {
259 while (*h && *h != 'x') {
266 state->window_w = SDL_atoi(w);
267 state->window_h = SDL_atoi(h);
270 if (SDL_strcasecmp(argv[index], "--min-geometry") == 0) {
278 while (*h && *h != 'x') {
285 state->window_minW = SDL_atoi(w);
286 state->window_minH = SDL_atoi(h);
289 if (SDL_strcasecmp(argv[index], "--max-geometry") == 0) {
297 while (*h && *h != 'x') {
304 state->window_maxW = SDL_atoi(w);
305 state->window_maxH = SDL_atoi(h);
308 if (SDL_strcasecmp(argv[index], "--logical") == 0) {
316 while (*h && *h != 'x') {
323 state->logical_w = SDL_atoi(w);
324 state->logical_h = SDL_atoi(h);
327 if (SDL_strcasecmp(argv[index], "--scale") == 0) {
332 state->scale = (float)SDL_atof(argv[index]);
335 if (SDL_strcasecmp(argv[index], "--depth") == 0) {
340 state->depth = SDL_atoi(argv[index]);
343 if (SDL_strcasecmp(argv[index], "--refresh") == 0) {
348 state->refresh_rate = SDL_atoi(argv[index]);
351 if (SDL_strcasecmp(argv[index], "--vsync") == 0) {
352 state->render_flags |= SDL_RENDERER_PRESENTVSYNC;
355 if (SDL_strcasecmp(argv[index], "--noframe") == 0) {
356 state->window_flags |= SDL_WINDOW_BORDERLESS;
359 if (SDL_strcasecmp(argv[index], "--resize") == 0) {
360 state->window_flags |= SDL_WINDOW_RESIZABLE;
363 if (SDL_strcasecmp(argv[index], "--minimize") == 0) {
364 state->window_flags |= SDL_WINDOW_MINIMIZED;
367 if (SDL_strcasecmp(argv[index], "--maximize") == 0) {
368 state->window_flags |= SDL_WINDOW_MAXIMIZED;
371 if (SDL_strcasecmp(argv[index], "--grab") == 0) {
372 state->window_flags |= SDL_WINDOW_INPUT_GRABBED;
375 if (SDL_strcasecmp(argv[index], "--rate") == 0) {
380 state->audiospec.freq = SDL_atoi(argv[index]);
383 if (SDL_strcasecmp(argv[index], "--format") == 0) {
388 if (SDL_strcasecmp(argv[index], "U8") == 0) {
389 state->audiospec.format = AUDIO_U8;
392 if (SDL_strcasecmp(argv[index], "S8") == 0) {
393 state->audiospec.format = AUDIO_S8;
396 if (SDL_strcasecmp(argv[index], "U16") == 0) {
397 state->audiospec.format = AUDIO_U16;
400 if (SDL_strcasecmp(argv[index], "U16LE") == 0) {
401 state->audiospec.format = AUDIO_U16LSB;
404 if (SDL_strcasecmp(argv[index], "U16BE") == 0) {
405 state->audiospec.format = AUDIO_U16MSB;
408 if (SDL_strcasecmp(argv[index], "S16") == 0) {
409 state->audiospec.format = AUDIO_S16;
412 if (SDL_strcasecmp(argv[index], "S16LE") == 0) {
413 state->audiospec.format = AUDIO_S16LSB;
416 if (SDL_strcasecmp(argv[index], "S16BE") == 0) {
417 state->audiospec.format = AUDIO_S16MSB;
422 if (SDL_strcasecmp(argv[index], "--channels") == 0) {
427 state->audiospec.channels = (Uint8) SDL_atoi(argv[index]);
430 if (SDL_strcasecmp(argv[index], "--samples") == 0) {
435 state->audiospec.samples = (Uint16) SDL_atoi(argv[index]);
438 if ((SDL_strcasecmp(argv[index], "-h") == 0)
439 || (SDL_strcasecmp(argv[index], "--help") == 0)) {
440 /* Print the usage message */
443 if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) {
444 /* Debug flag sent by Xcode */
451 SDLTest_CommonUsage(SDLTest_CommonState * state)
453 switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
458 case (SDL_INIT_VIDEO | SDL_INIT_AUDIO):
459 return VIDEO_USAGE " " AUDIO_USAGE;
466 SDLTest_PrintRendererFlag(Uint32 flag)
469 case SDL_RENDERER_PRESENTVSYNC:
470 fprintf(stderr, "PresentVSync");
472 case SDL_RENDERER_ACCELERATED:
473 fprintf(stderr, "Accelerated");
476 fprintf(stderr, "0x%8.8x", flag);
482 SDLTest_PrintPixelFormat(Uint32 format)
485 case SDL_PIXELFORMAT_UNKNOWN:
486 fprintf(stderr, "Unknwon");
488 case SDL_PIXELFORMAT_INDEX1LSB:
489 fprintf(stderr, "Index1LSB");
491 case SDL_PIXELFORMAT_INDEX1MSB:
492 fprintf(stderr, "Index1MSB");
494 case SDL_PIXELFORMAT_INDEX4LSB:
495 fprintf(stderr, "Index4LSB");
497 case SDL_PIXELFORMAT_INDEX4MSB:
498 fprintf(stderr, "Index4MSB");
500 case SDL_PIXELFORMAT_INDEX8:
501 fprintf(stderr, "Index8");
503 case SDL_PIXELFORMAT_RGB332:
504 fprintf(stderr, "RGB332");
506 case SDL_PIXELFORMAT_RGB444:
507 fprintf(stderr, "RGB444");
509 case SDL_PIXELFORMAT_RGB555:
510 fprintf(stderr, "RGB555");
512 case SDL_PIXELFORMAT_BGR555:
513 fprintf(stderr, "BGR555");
515 case SDL_PIXELFORMAT_ARGB4444:
516 fprintf(stderr, "ARGB4444");
518 case SDL_PIXELFORMAT_ABGR4444:
519 fprintf(stderr, "ABGR4444");
521 case SDL_PIXELFORMAT_ARGB1555:
522 fprintf(stderr, "ARGB1555");
524 case SDL_PIXELFORMAT_ABGR1555:
525 fprintf(stderr, "ABGR1555");
527 case SDL_PIXELFORMAT_RGB565:
528 fprintf(stderr, "RGB565");
530 case SDL_PIXELFORMAT_BGR565:
531 fprintf(stderr, "BGR565");
533 case SDL_PIXELFORMAT_RGB24:
534 fprintf(stderr, "RGB24");
536 case SDL_PIXELFORMAT_BGR24:
537 fprintf(stderr, "BGR24");
539 case SDL_PIXELFORMAT_RGB888:
540 fprintf(stderr, "RGB888");
542 case SDL_PIXELFORMAT_BGR888:
543 fprintf(stderr, "BGR888");
545 case SDL_PIXELFORMAT_ARGB8888:
546 fprintf(stderr, "ARGB8888");
548 case SDL_PIXELFORMAT_RGBA8888:
549 fprintf(stderr, "RGBA8888");
551 case SDL_PIXELFORMAT_ABGR8888:
552 fprintf(stderr, "ABGR8888");
554 case SDL_PIXELFORMAT_BGRA8888:
555 fprintf(stderr, "BGRA8888");
557 case SDL_PIXELFORMAT_ARGB2101010:
558 fprintf(stderr, "ARGB2101010");
560 case SDL_PIXELFORMAT_YV12:
561 fprintf(stderr, "YV12");
563 case SDL_PIXELFORMAT_IYUV:
564 fprintf(stderr, "IYUV");
566 case SDL_PIXELFORMAT_YUY2:
567 fprintf(stderr, "YUY2");
569 case SDL_PIXELFORMAT_UYVY:
570 fprintf(stderr, "UYVY");
572 case SDL_PIXELFORMAT_YVYU:
573 fprintf(stderr, "YVYU");
575 case SDL_PIXELFORMAT_NV12:
576 fprintf(stderr, "NV12");
578 case SDL_PIXELFORMAT_NV21:
579 fprintf(stderr, "NV21");
582 fprintf(stderr, "0x%8.8x", format);
588 SDLTest_PrintRenderer(SDL_RendererInfo * info)
592 fprintf(stderr, " Renderer %s:\n", info->name);
594 fprintf(stderr, " Flags: 0x%8.8X", info->flags);
595 fprintf(stderr, " (");
597 for (i = 0; i < sizeof(info->flags) * 8; ++i) {
598 Uint32 flag = (1 << i);
599 if (info->flags & flag) {
601 fprintf(stderr, " | ");
603 SDLTest_PrintRendererFlag(flag);
607 fprintf(stderr, ")\n");
609 fprintf(stderr, " Texture formats (%d): ", info->num_texture_formats);
610 for (i = 0; i < (int) info->num_texture_formats; ++i) {
612 fprintf(stderr, ", ");
614 SDLTest_PrintPixelFormat(info->texture_formats[i]);
616 fprintf(stderr, "\n");
618 if (info->max_texture_width || info->max_texture_height) {
619 fprintf(stderr, " Max Texture Size: %dx%d\n",
620 info->max_texture_width, info->max_texture_height);
625 SDLTest_LoadIcon(const char *file)
629 /* Load the icon surface */
630 icon = SDL_LoadBMP(file);
632 fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
636 if (icon->format->palette) {
637 /* Set the colorkey */
638 SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels));
645 SDLTest_CommonInit(SDLTest_CommonState * state)
647 int i, j, m, n, w, h;
648 SDL_DisplayMode fullscreen_mode;
650 if (state->flags & SDL_INIT_VIDEO) {
651 if (state->verbose & VERBOSE_VIDEO) {
652 n = SDL_GetNumVideoDrivers();
654 fprintf(stderr, "No built-in video drivers\n");
656 fprintf(stderr, "Built-in video drivers:");
657 for (i = 0; i < n; ++i) {
659 fprintf(stderr, ",");
661 fprintf(stderr, " %s", SDL_GetVideoDriver(i));
663 fprintf(stderr, "\n");
666 if (SDL_VideoInit(state->videodriver) < 0) {
667 fprintf(stderr, "Couldn't initialize video driver: %s\n",
671 if (state->verbose & VERBOSE_VIDEO) {
672 fprintf(stderr, "Video driver: %s\n",
673 SDL_GetCurrentVideoDriver());
676 /* Upload GL settings */
677 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size);
678 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size);
679 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size);
680 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size);
681 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer);
682 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size);
683 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size);
684 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size);
685 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size);
686 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size);
687 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size);
688 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size);
689 SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo);
690 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers);
691 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples);
692 if (state->gl_accelerated >= 0) {
693 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
694 state->gl_accelerated);
696 SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing);
697 if (state->gl_major_version) {
698 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version);
699 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version);
701 if (state->gl_debug) {
702 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
704 if (state->gl_profile_mask) {
705 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, state->gl_profile_mask);
708 if (state->verbose & VERBOSE_MODES) {
710 SDL_DisplayMode mode;
712 Uint32 Rmask, Gmask, Bmask, Amask;
713 #if SDL_VIDEO_DRIVER_WINDOWS
714 int adapterIndex = 0;
717 n = SDL_GetNumVideoDisplays();
718 fprintf(stderr, "Number of displays: %d\n", n);
719 for (i = 0; i < n; ++i) {
720 fprintf(stderr, "Display %d: %s\n", i, SDL_GetDisplayName(i));
723 SDL_GetDisplayBounds(i, &bounds);
724 fprintf(stderr, "Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y);
726 SDL_GetDesktopDisplayMode(i, &mode);
727 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask,
730 " Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
731 mode.w, mode.h, mode.refresh_rate, bpp,
732 SDL_GetPixelFormatName(mode.format));
733 if (Rmask || Gmask || Bmask) {
734 fprintf(stderr, " Red Mask = 0x%.8x\n", Rmask);
735 fprintf(stderr, " Green Mask = 0x%.8x\n", Gmask);
736 fprintf(stderr, " Blue Mask = 0x%.8x\n", Bmask);
738 fprintf(stderr, " Alpha Mask = 0x%.8x\n", Amask);
741 /* Print available fullscreen video modes */
742 m = SDL_GetNumDisplayModes(i);
744 fprintf(stderr, "No available fullscreen video modes\n");
746 fprintf(stderr, " Fullscreen video modes:\n");
747 for (j = 0; j < m; ++j) {
748 SDL_GetDisplayMode(i, j, &mode);
749 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask,
750 &Gmask, &Bmask, &Amask);
752 " Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n",
753 j, mode.w, mode.h, mode.refresh_rate, bpp,
754 SDL_GetPixelFormatName(mode.format));
755 if (Rmask || Gmask || Bmask) {
756 fprintf(stderr, " Red Mask = 0x%.8x\n",
758 fprintf(stderr, " Green Mask = 0x%.8x\n",
760 fprintf(stderr, " Blue Mask = 0x%.8x\n",
764 " Alpha Mask = 0x%.8x\n",
770 #if SDL_VIDEO_DRIVER_WINDOWS
771 /* Print the D3D9 adapter index */
772 adapterIndex = SDL_Direct3D9GetAdapterIndex( i );
773 fprintf( stderr, "D3D9 Adapter Index: %d", adapterIndex );
775 /* Print the DXGI adapter and output indices */
776 SDL_DXGIGetOutputInfo(i, &adapterIndex, &outputIndex);
777 fprintf( stderr, "DXGI Adapter Index: %d Output Index: %d", adapterIndex, outputIndex );
782 if (state->verbose & VERBOSE_RENDER) {
783 SDL_RendererInfo info;
785 n = SDL_GetNumRenderDrivers();
787 fprintf(stderr, "No built-in render drivers\n");
789 fprintf(stderr, "Built-in render drivers:\n");
790 for (i = 0; i < n; ++i) {
791 SDL_GetRenderDriverInfo(i, &info);
792 SDLTest_PrintRenderer(&info);
797 SDL_zero(fullscreen_mode);
798 switch (state->depth) {
800 fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8;
803 fullscreen_mode.format = SDL_PIXELFORMAT_RGB555;
806 fullscreen_mode.format = SDL_PIXELFORMAT_RGB565;
809 fullscreen_mode.format = SDL_PIXELFORMAT_RGB24;
812 fullscreen_mode.format = SDL_PIXELFORMAT_RGB888;
815 fullscreen_mode.refresh_rate = state->refresh_rate;
818 (SDL_Window **) SDL_malloc(state->num_windows *
819 sizeof(*state->windows));
821 (SDL_Renderer **) SDL_malloc(state->num_windows *
822 sizeof(*state->renderers));
824 (SDL_Texture **) SDL_malloc(state->num_windows *
825 sizeof(*state->targets));
826 if (!state->windows || !state->renderers) {
827 fprintf(stderr, "Out of memory!\n");
830 for (i = 0; i < state->num_windows; ++i) {
833 if (state->num_windows > 1) {
834 SDL_snprintf(title, SDL_arraysize(title), "%s %d",
835 state->window_title, i + 1);
837 SDL_strlcpy(title, state->window_title, SDL_arraysize(title));
840 SDL_CreateWindow(title, state->window_x, state->window_y,
841 state->window_w, state->window_h,
842 state->window_flags);
843 if (!state->windows[i]) {
844 fprintf(stderr, "Couldn't create window: %s\n",
848 if (state->window_minW || state->window_minH) {
849 SDL_SetWindowMinimumSize(state->windows[i], state->window_minW, state->window_minH);
851 if (state->window_maxW || state->window_maxH) {
852 SDL_SetWindowMaximumSize(state->windows[i], state->window_maxW, state->window_maxH);
854 SDL_GetWindowSize(state->windows[i], &w, &h);
855 if (!(state->window_flags & SDL_WINDOW_RESIZABLE) &&
856 (w != state->window_w || h != state->window_h)) {
857 printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h);
861 if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) {
862 fprintf(stderr, "Can't set up fullscreen display mode: %s\n",
867 if (state->window_icon) {
868 SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon);
870 SDL_SetWindowIcon(state->windows[i], icon);
871 SDL_FreeSurface(icon);
875 SDL_ShowWindow(state->windows[i]);
877 state->renderers[i] = NULL;
878 state->targets[i] = NULL;
880 if (!state->skip_renderer
881 && (state->renderdriver
882 || !(state->window_flags & SDL_WINDOW_OPENGL))) {
884 if (state->renderdriver) {
885 SDL_RendererInfo info;
886 n = SDL_GetNumRenderDrivers();
887 for (j = 0; j < n; ++j) {
888 SDL_GetRenderDriverInfo(j, &info);
889 if (SDL_strcasecmp(info.name, state->renderdriver) ==
897 "Couldn't find render driver named %s",
898 state->renderdriver);
902 state->renderers[i] = SDL_CreateRenderer(state->windows[i],
903 m, state->render_flags);
904 if (!state->renderers[i]) {
905 fprintf(stderr, "Couldn't create renderer: %s\n",
909 if (state->logical_w && state->logical_h) {
910 SDL_RenderSetLogicalSize(state->renderers[i], state->logical_w, state->logical_h);
911 } else if (state->scale) {
912 SDL_RenderSetScale(state->renderers[i], state->scale, state->scale);
914 if (state->verbose & VERBOSE_RENDER) {
915 SDL_RendererInfo info;
917 fprintf(stderr, "Current renderer:\n");
918 SDL_GetRendererInfo(state->renderers[i], &info);
919 SDLTest_PrintRenderer(&info);
925 if (state->flags & SDL_INIT_AUDIO) {
926 if (state->verbose & VERBOSE_AUDIO) {
927 n = SDL_GetNumAudioDrivers();
929 fprintf(stderr, "No built-in audio drivers\n");
931 fprintf(stderr, "Built-in audio drivers:");
932 for (i = 0; i < n; ++i) {
934 fprintf(stderr, ",");
936 fprintf(stderr, " %s", SDL_GetAudioDriver(i));
938 fprintf(stderr, "\n");
941 if (SDL_AudioInit(state->audiodriver) < 0) {
942 fprintf(stderr, "Couldn't initialize audio driver: %s\n",
946 if (state->verbose & VERBOSE_VIDEO) {
947 fprintf(stderr, "Audio driver: %s\n",
948 SDL_GetCurrentAudioDriver());
951 if (SDL_OpenAudio(&state->audiospec, NULL) < 0) {
952 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
961 ControllerAxisName(const SDL_GameControllerAxis axis)
965 #define AXIS_CASE(ax) case SDL_CONTROLLER_AXIS_##ax: return #ax
971 AXIS_CASE(TRIGGERLEFT);
972 AXIS_CASE(TRIGGERRIGHT);
974 default: return "???";
979 ControllerButtonName(const SDL_GameControllerButton button)
983 #define BUTTON_CASE(btn) case SDL_CONTROLLER_BUTTON_##btn: return #btn
984 BUTTON_CASE(INVALID);
992 BUTTON_CASE(LEFTSTICK);
993 BUTTON_CASE(RIGHTSTICK);
994 BUTTON_CASE(LEFTSHOULDER);
995 BUTTON_CASE(RIGHTSHOULDER);
996 BUTTON_CASE(DPAD_UP);
997 BUTTON_CASE(DPAD_DOWN);
998 BUTTON_CASE(DPAD_LEFT);
999 BUTTON_CASE(DPAD_RIGHT);
1001 default: return "???";
1006 SDLTest_PrintEvent(SDL_Event * event)
1008 if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) {
1009 /* Mouse and finger motion are really spammy */
1013 switch (event->type) {
1014 case SDL_WINDOWEVENT:
1015 switch (event->window.event) {
1016 case SDL_WINDOWEVENT_SHOWN:
1017 SDL_Log("SDL EVENT: Window %d shown", event->window.windowID);
1019 case SDL_WINDOWEVENT_HIDDEN:
1020 SDL_Log("SDL EVENT: Window %d hidden", event->window.windowID);
1022 case SDL_WINDOWEVENT_EXPOSED:
1023 SDL_Log("SDL EVENT: Window %d exposed", event->window.windowID);
1025 case SDL_WINDOWEVENT_MOVED:
1026 SDL_Log("SDL EVENT: Window %d moved to %d,%d",
1027 event->window.windowID, event->window.data1,
1028 event->window.data2);
1030 case SDL_WINDOWEVENT_RESIZED:
1031 SDL_Log("SDL EVENT: Window %d resized to %dx%d",
1032 event->window.windowID, event->window.data1,
1033 event->window.data2);
1035 case SDL_WINDOWEVENT_SIZE_CHANGED:
1036 SDL_Log("SDL EVENT: Window %d changed size to %dx%d",
1037 event->window.windowID, event->window.data1,
1038 event->window.data2);
1040 case SDL_WINDOWEVENT_MINIMIZED:
1041 SDL_Log("SDL EVENT: Window %d minimized", event->window.windowID);
1043 case SDL_WINDOWEVENT_MAXIMIZED:
1044 SDL_Log("SDL EVENT: Window %d maximized", event->window.windowID);
1046 case SDL_WINDOWEVENT_RESTORED:
1047 SDL_Log("SDL EVENT: Window %d restored", event->window.windowID);
1049 case SDL_WINDOWEVENT_ENTER:
1050 SDL_Log("SDL EVENT: Mouse entered window %d",
1051 event->window.windowID);
1053 case SDL_WINDOWEVENT_LEAVE:
1054 SDL_Log("SDL EVENT: Mouse left window %d", event->window.windowID);
1056 case SDL_WINDOWEVENT_FOCUS_GAINED:
1057 SDL_Log("SDL EVENT: Window %d gained keyboard focus",
1058 event->window.windowID);
1060 case SDL_WINDOWEVENT_FOCUS_LOST:
1061 SDL_Log("SDL EVENT: Window %d lost keyboard focus",
1062 event->window.windowID);
1064 case SDL_WINDOWEVENT_CLOSE:
1065 SDL_Log("SDL EVENT: Window %d closed", event->window.windowID);
1068 SDL_Log("SDL EVENT: Window %d got unknown event %d",
1069 event->window.windowID, event->window.event);
1074 SDL_Log("SDL EVENT: Keyboard: key pressed in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
1075 event->key.windowID,
1076 event->key.keysym.scancode,
1077 SDL_GetScancodeName(event->key.keysym.scancode),
1078 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
1081 SDL_Log("SDL EVENT: Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s",
1082 event->key.windowID,
1083 event->key.keysym.scancode,
1084 SDL_GetScancodeName(event->key.keysym.scancode),
1085 event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym));
1088 SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %d",
1089 event->text.text, event->text.windowID);
1091 case SDL_MOUSEMOTION:
1092 SDL_Log("SDL EVENT: Mouse: moved to %d,%d (%d,%d) in window %d",
1093 event->motion.x, event->motion.y,
1094 event->motion.xrel, event->motion.yrel,
1095 event->motion.windowID);
1097 case SDL_MOUSEBUTTONDOWN:
1098 SDL_Log("SDL EVENT: Mouse: button %d pressed at %d,%d with click count %d in window %d",
1099 event->button.button, event->button.x, event->button.y, event->button.clicks,
1100 event->button.windowID);
1102 case SDL_MOUSEBUTTONUP:
1103 SDL_Log("SDL EVENT: Mouse: button %d released at %d,%d with click count %d in window %d",
1104 event->button.button, event->button.x, event->button.y, event->button.clicks,
1105 event->button.windowID);
1107 case SDL_MOUSEWHEEL:
1108 SDL_Log("SDL EVENT: Mouse: wheel scrolled %d in x and %d in y (reversed: %d) in window %d",
1109 event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID);
1111 case SDL_JOYDEVICEADDED:
1112 SDL_Log("SDL EVENT: Joystick index %d attached",
1113 event->jdevice.which);
1115 case SDL_JOYDEVICEREMOVED:
1116 SDL_Log("SDL EVENT: Joystick %d removed",
1117 event->jdevice.which);
1119 case SDL_JOYBALLMOTION:
1120 SDL_Log("SDL EVENT: Joystick %d: ball %d moved by %d,%d",
1121 event->jball.which, event->jball.ball, event->jball.xrel,
1124 case SDL_JOYHATMOTION:
1126 const char *position = "UNKNOWN";
1127 switch (event->jhat.value) {
1128 case SDL_HAT_CENTERED:
1129 position = "CENTER";
1134 case SDL_HAT_RIGHTUP:
1135 position = "RIGHTUP";
1140 case SDL_HAT_RIGHTDOWN:
1141 position = "RIGHTDOWN";
1146 case SDL_HAT_LEFTDOWN:
1147 position = "LEFTDOWN";
1152 case SDL_HAT_LEFTUP:
1153 position = "LEFTUP";
1156 SDL_Log("SDL EVENT: Joystick %d: hat %d moved to %s", event->jhat.which,
1157 event->jhat.hat, position);
1160 case SDL_JOYBUTTONDOWN:
1161 SDL_Log("SDL EVENT: Joystick %d: button %d pressed",
1162 event->jbutton.which, event->jbutton.button);
1164 case SDL_JOYBUTTONUP:
1165 SDL_Log("SDL EVENT: Joystick %d: button %d released",
1166 event->jbutton.which, event->jbutton.button);
1168 case SDL_CONTROLLERDEVICEADDED:
1169 SDL_Log("SDL EVENT: Controller index %d attached",
1170 event->cdevice.which);
1172 case SDL_CONTROLLERDEVICEREMOVED:
1173 SDL_Log("SDL EVENT: Controller %d removed",
1174 event->cdevice.which);
1176 case SDL_CONTROLLERAXISMOTION:
1177 SDL_Log("SDL EVENT: Controller %d axis %d ('%s') value: %d",
1180 ControllerAxisName((SDL_GameControllerAxis)event->caxis.axis),
1181 event->caxis.value);
1183 case SDL_CONTROLLERBUTTONDOWN:
1184 SDL_Log("SDL EVENT: Controller %d button %d ('%s') down",
1185 event->cbutton.which, event->cbutton.button,
1186 ControllerButtonName((SDL_GameControllerButton)event->cbutton.button));
1188 case SDL_CONTROLLERBUTTONUP:
1189 SDL_Log("SDL EVENT: Controller %d button %d ('%s') up",
1190 event->cbutton.which, event->cbutton.button,
1191 ControllerButtonName((SDL_GameControllerButton)event->cbutton.button));
1193 case SDL_CLIPBOARDUPDATE:
1194 SDL_Log("SDL EVENT: Clipboard updated");
1197 case SDL_FINGERDOWN:
1199 SDL_Log("SDL EVENT: Finger: %s touch=%ld, finger=%ld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f",
1200 (event->type == SDL_FINGERDOWN) ? "down" : "up",
1201 (long) event->tfinger.touchId,
1202 (long) event->tfinger.fingerId,
1203 event->tfinger.x, event->tfinger.y,
1204 event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
1206 case SDL_DOLLARGESTURE:
1207 SDL_Log("SDL_EVENT: Dollar gesture detect: %"SDL_PRIs64, (Sint64) event->dgesture.gestureId);
1209 case SDL_DOLLARRECORD:
1210 SDL_Log("SDL_EVENT: Dollar gesture record: %"SDL_PRIs64, (Sint64) event->dgesture.gestureId);
1212 case SDL_MULTIGESTURE:
1213 SDL_Log("SDL_EVENT: Multi gesture fingers: %d", event->mgesture.numFingers);
1216 case SDL_RENDER_DEVICE_RESET:
1217 SDL_Log("SDL EVENT: render device reset");
1219 case SDL_RENDER_TARGETS_RESET:
1220 SDL_Log("SDL EVENT: render targets reset");
1224 SDL_Log("SDL EVENT: Quit requested");
1227 SDL_Log("SDL EVENT: User event %d", event->user.code);
1230 SDL_Log("Unknown event %04x", event->type);
1236 SDLTest_ScreenShot(SDL_Renderer *renderer)
1239 SDL_Surface *surface;
1245 SDL_RenderGetViewport(renderer, &viewport);
1246 surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24,
1247 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
1248 0x00FF0000, 0x0000FF00, 0x000000FF,
1250 0x000000FF, 0x0000FF00, 0x00FF0000,
1254 fprintf(stderr, "Couldn't create surface: %s\n", SDL_GetError());
1258 if (SDL_RenderReadPixels(renderer, NULL, surface->format->format,
1259 surface->pixels, surface->pitch) < 0) {
1260 fprintf(stderr, "Couldn't read screen: %s\n", SDL_GetError());
1265 if (SDL_SaveBMP(surface, "screenshot.bmp") < 0) {
1266 fprintf(stderr, "Couldn't save screenshot.bmp: %s\n", SDL_GetError());
1273 FullscreenTo(int index, int windowId)
1276 struct SDL_Rect rect = { 0, 0, 0, 0 };
1277 SDL_Window *window = SDL_GetWindowFromID(windowId);
1282 SDL_GetDisplayBounds( index, &rect );
1284 flags = SDL_GetWindowFlags(window);
1285 if (flags & SDL_WINDOW_FULLSCREEN) {
1286 SDL_SetWindowFullscreen( window, SDL_FALSE );
1290 SDL_SetWindowPosition( window, rect.x, rect.y );
1291 SDL_SetWindowFullscreen( window, SDL_TRUE );
1295 SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
1298 static SDL_MouseMotionEvent lastEvent;
1300 if (state->verbose & VERBOSE_EVENT) {
1301 SDLTest_PrintEvent(event);
1304 switch (event->type) {
1305 case SDL_WINDOWEVENT:
1306 switch (event->window.event) {
1307 case SDL_WINDOWEVENT_CLOSE:
1309 SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
1311 for (i = 0; i < state->num_windows; ++i) {
1312 if (window == state->windows[i]) {
1313 if (state->targets[i]) {
1314 SDL_DestroyTexture(state->targets[i]);
1315 state->targets[i] = NULL;
1317 if (state->renderers[i]) {
1318 SDL_DestroyRenderer(state->renderers[i]);
1319 state->renderers[i] = NULL;
1321 SDL_DestroyWindow(state->windows[i]);
1322 state->windows[i] = NULL;
1332 SDL_bool withControl = !!(event->key.keysym.mod & KMOD_CTRL);
1333 SDL_bool withShift = !!(event->key.keysym.mod & KMOD_SHIFT);
1334 SDL_bool withAlt = !!(event->key.keysym.mod & KMOD_ALT);
1336 switch (event->key.keysym.sym) {
1337 /* Add hotkeys here */
1338 case SDLK_PRINTSCREEN: {
1339 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1341 for (i = 0; i < state->num_windows; ++i) {
1342 if (window == state->windows[i]) {
1343 SDLTest_ScreenShot(state->renderers[i]);
1351 /* Ctrl-+ double the size of the window */
1352 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1355 SDL_GetWindowSize(window, &w, &h);
1356 SDL_SetWindowSize(window, w*2, h*2);
1362 /* Ctrl-- half the size of the window */
1363 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1366 SDL_GetWindowSize(window, &w, &h);
1367 SDL_SetWindowSize(window, w/2, h/2);
1373 /* Ctrl-C copy awesome text! */
1374 SDL_SetClipboardText("SDL rocks!\nYou know it!");
1375 printf("Copied text to clipboard\n");
1378 /* Alt-C toggle a render clip rectangle */
1379 for (i = 0; i < state->num_windows; ++i) {
1381 if (state->renderers[i]) {
1383 SDL_GetWindowSize(state->windows[i], &w, &h);
1384 SDL_RenderGetClipRect(state->renderers[i], &clip);
1385 if (SDL_RectEmpty(&clip)) {
1390 SDL_RenderSetClipRect(state->renderers[i], &clip);
1392 SDL_RenderSetClipRect(state->renderers[i], NULL);
1398 SDL_Window *current_win = SDL_GetKeyboardFocus();
1400 const SDL_bool shouldCapture = (SDL_GetWindowFlags(current_win) & SDL_WINDOW_MOUSE_CAPTURE) == 0;
1401 const int rc = SDL_CaptureMouse(shouldCapture);
1402 SDL_Log("%sapturing mouse %s!\n", shouldCapture ? "C" : "Unc", (rc == 0) ? "succeeded" : "failed");
1408 /* Ctrl-V paste awesome text! */
1409 char *text = SDL_GetClipboardText();
1411 printf("Clipboard: %s\n", text);
1413 printf("Clipboard is empty\n");
1420 /* Ctrl-G toggle grab */
1421 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1423 SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window) ? SDL_TRUE : SDL_FALSE);
1429 /* Ctrl-M maximize */
1430 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1432 Uint32 flags = SDL_GetWindowFlags(window);
1433 if (flags & SDL_WINDOW_MAXIMIZED) {
1434 SDL_RestoreWindow(window);
1436 SDL_MaximizeWindow(window);
1443 /* Ctrl-R toggle mouse relative mode */
1444 SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode() ? SDL_TRUE : SDL_FALSE);
1449 /* Ctrl-Z minimize */
1450 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1452 SDL_MinimizeWindow(window);
1458 /* Ctrl-Enter toggle fullscreen */
1459 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1461 Uint32 flags = SDL_GetWindowFlags(window);
1462 if (flags & SDL_WINDOW_FULLSCREEN) {
1463 SDL_SetWindowFullscreen(window, SDL_FALSE);
1465 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
1468 } else if (withAlt) {
1469 /* Alt-Enter toggle fullscreen desktop */
1470 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1472 Uint32 flags = SDL_GetWindowFlags(window);
1473 if (flags & SDL_WINDOW_FULLSCREEN) {
1474 SDL_SetWindowFullscreen(window, SDL_FALSE);
1476 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1479 } else if (withShift) {
1480 /* Shift-Enter toggle fullscreen desktop / fullscreen */
1481 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1483 Uint32 flags = SDL_GetWindowFlags(window);
1484 if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
1485 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
1487 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
1495 /* Ctrl-B toggle window border */
1496 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1498 const Uint32 flags = SDL_GetWindowFlags(window);
1499 const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0) ? SDL_TRUE : SDL_FALSE;
1500 SDL_SetWindowBordered(window, b);
1506 /* Ctrl-A reports absolute mouse position. */
1508 const Uint32 mask = SDL_GetGlobalMouseState(&x, &y);
1509 SDL_Log("ABSOLUTE MOUSE: (%d, %d)%s%s%s%s%s\n", x, y,
1510 (mask & SDL_BUTTON_LMASK) ? " [LBUTTON]" : "",
1511 (mask & SDL_BUTTON_MMASK) ? " [MBUTTON]" : "",
1512 (mask & SDL_BUTTON_RMASK) ? " [RBUTTON]" : "",
1513 (mask & SDL_BUTTON_X1MASK) ? " [X2BUTTON]" : "",
1514 (mask & SDL_BUTTON_X2MASK) ? " [X2BUTTON]" : "");
1519 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1520 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Test Message", "You're awesome!", window);
1525 FullscreenTo(0, event->key.windowID);
1530 FullscreenTo(1, event->key.windowID);
1539 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
1541 SDL_snprintf(message, sizeof(message), "(%i, %i), rel (%i, %i)\n", lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel);
1542 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Last mouse position", message, window);
1553 case SDL_MOUSEMOTION:
1554 lastEvent = event->motion;
1560 SDLTest_CommonQuit(SDLTest_CommonState * state)
1564 SDL_free(state->windows);
1565 if (state->targets) {
1566 for (i = 0; i < state->num_windows; ++i) {
1567 if (state->targets[i]) {
1568 SDL_DestroyTexture(state->targets[i]);
1571 SDL_free(state->targets);
1573 if (state->renderers) {
1574 for (i = 0; i < state->num_windows; ++i) {
1575 if (state->renderers[i]) {
1576 SDL_DestroyRenderer(state->renderers[i]);
1579 SDL_free(state->renderers);
1581 if (state->flags & SDL_INIT_VIDEO) {
1584 if (state->flags & SDL_INIT_AUDIO) {
1591 /* vi: set ts=4 sw=4 expandtab: */