SDL_test_common.c (54882B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org> 4 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. 8 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: 12 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. 20*/ 21 22/* Ported from original test\common.c file. */ 23 24#include "SDL_config.h" 25#include "SDL_test.h" 26 27#include <stdio.h> 28 29#define VIDEO_USAGE \ 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]" 31 32#define AUDIO_USAGE \ 33"[--rate N] [--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE] [--channels N] [--samples N]" 34 35SDLTest_CommonState * 36SDLTest_CommonCreateState(char **argv, Uint32 flags) 37{ 38 SDLTest_CommonState *state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state)); 39 if (!state) { 40 SDL_OutOfMemory(); 41 return NULL; 42 } 43 44 /* Initialize some defaults */ 45 state->argv = argv; 46 state->flags = flags; 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; 58 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; 72 state->gl_stereo = 0; 73 state->gl_multisamplebuffers = 0; 74 state->gl_multisamplesamples = 0; 75 state->gl_retained_backing = 1; 76 state->gl_accelerated = -1; 77 state->gl_debug = 0; 78 79 return state; 80} 81 82int 83SDLTest_CommonArg(SDLTest_CommonState * state, int index) 84{ 85 char **argv = state->argv; 86 87 if (SDL_strcasecmp(argv[index], "--video") == 0) { 88 ++index; 89 if (!argv[index]) { 90 return -1; 91 } 92 state->videodriver = argv[index]; 93 return 2; 94 } 95 if (SDL_strcasecmp(argv[index], "--renderer") == 0) { 96 ++index; 97 if (!argv[index]) { 98 return -1; 99 } 100 state->renderdriver = argv[index]; 101 return 2; 102 } 103 if (SDL_strcasecmp(argv[index], "--gldebug") == 0) { 104 state->gl_debug = 1; 105 return 1; 106 } 107 if (SDL_strcasecmp(argv[index], "--info") == 0) { 108 ++index; 109 if (!argv[index]) { 110 return -1; 111 } 112 if (SDL_strcasecmp(argv[index], "all") == 0) { 113 state->verbose |= 114 (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER | 115 VERBOSE_EVENT); 116 return 2; 117 } 118 if (SDL_strcasecmp(argv[index], "video") == 0) { 119 state->verbose |= VERBOSE_VIDEO; 120 return 2; 121 } 122 if (SDL_strcasecmp(argv[index], "modes") == 0) { 123 state->verbose |= VERBOSE_MODES; 124 return 2; 125 } 126 if (SDL_strcasecmp(argv[index], "render") == 0) { 127 state->verbose |= VERBOSE_RENDER; 128 return 2; 129 } 130 if (SDL_strcasecmp(argv[index], "event") == 0) { 131 state->verbose |= VERBOSE_EVENT; 132 return 2; 133 } 134 return -1; 135 } 136 if (SDL_strcasecmp(argv[index], "--log") == 0) { 137 ++index; 138 if (!argv[index]) { 139 return -1; 140 } 141 if (SDL_strcasecmp(argv[index], "all") == 0) { 142 SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); 143 return 2; 144 } 145 if (SDL_strcasecmp(argv[index], "error") == 0) { 146 SDL_LogSetPriority(SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_VERBOSE); 147 return 2; 148 } 149 if (SDL_strcasecmp(argv[index], "system") == 0) { 150 SDL_LogSetPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE); 151 return 2; 152 } 153 if (SDL_strcasecmp(argv[index], "audio") == 0) { 154 SDL_LogSetPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE); 155 return 2; 156 } 157 if (SDL_strcasecmp(argv[index], "video") == 0) { 158 SDL_LogSetPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE); 159 return 2; 160 } 161 if (SDL_strcasecmp(argv[index], "render") == 0) { 162 SDL_LogSetPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE); 163 return 2; 164 } 165 if (SDL_strcasecmp(argv[index], "input") == 0) { 166 SDL_LogSetPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE); 167 return 2; 168 } 169 return -1; 170 } 171 if (SDL_strcasecmp(argv[index], "--display") == 0) { 172 ++index; 173 if (!argv[index]) { 174 return -1; 175 } 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); 180 } 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); 184 } 185 return 2; 186 } 187 if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) { 188 state->window_flags |= SDL_WINDOW_FULLSCREEN; 189 state->num_windows = 1; 190 return 1; 191 } 192 if (SDL_strcasecmp(argv[index], "--fullscreen-desktop") == 0) { 193 state->window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; 194 state->num_windows = 1; 195 return 1; 196 } 197 if (SDL_strcasecmp(argv[index], "--allow-highdpi") == 0) { 198 state->window_flags |= SDL_WINDOW_ALLOW_HIGHDPI; 199 return 1; 200 } 201 if (SDL_strcasecmp(argv[index], "--windows") == 0) { 202 ++index; 203 if (!argv[index] || !SDL_isdigit(*argv[index])) { 204 return -1; 205 } 206 if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) { 207 state->num_windows = SDL_atoi(argv[index]); 208 } 209 return 2; 210 } 211 if (SDL_strcasecmp(argv[index], "--title") == 0) { 212 ++index; 213 if (!argv[index]) { 214 return -1; 215 } 216 state->window_title = argv[index]; 217 return 2; 218 } 219 if (SDL_strcasecmp(argv[index], "--icon") == 0) { 220 ++index; 221 if (!argv[index]) { 222 return -1; 223 } 224 state->window_icon = argv[index]; 225 return 2; 226 } 227 if (SDL_strcasecmp(argv[index], "--center") == 0) { 228 state->window_x = SDL_WINDOWPOS_CENTERED; 229 state->window_y = SDL_WINDOWPOS_CENTERED; 230 return 1; 231 } 232 if (SDL_strcasecmp(argv[index], "--position") == 0) { 233 char *x, *y; 234 ++index; 235 if (!argv[index]) { 236 return -1; 237 } 238 x = argv[index]; 239 y = argv[index]; 240 while (*y && *y != ',') { 241 ++y; 242 } 243 if (!*y) { 244 return -1; 245 } 246 *y++ = '\0'; 247 state->window_x = SDL_atoi(x); 248 state->window_y = SDL_atoi(y); 249 return 2; 250 } 251 if (SDL_strcasecmp(argv[index], "--geometry") == 0) { 252 char *w, *h; 253 ++index; 254 if (!argv[index]) { 255 return -1; 256 } 257 w = argv[index]; 258 h = argv[index]; 259 while (*h && *h != 'x') { 260 ++h; 261 } 262 if (!*h) { 263 return -1; 264 } 265 *h++ = '\0'; 266 state->window_w = SDL_atoi(w); 267 state->window_h = SDL_atoi(h); 268 return 2; 269 } 270 if (SDL_strcasecmp(argv[index], "--min-geometry") == 0) { 271 char *w, *h; 272 ++index; 273 if (!argv[index]) { 274 return -1; 275 } 276 w = argv[index]; 277 h = argv[index]; 278 while (*h && *h != 'x') { 279 ++h; 280 } 281 if (!*h) { 282 return -1; 283 } 284 *h++ = '\0'; 285 state->window_minW = SDL_atoi(w); 286 state->window_minH = SDL_atoi(h); 287 return 2; 288 } 289 if (SDL_strcasecmp(argv[index], "--max-geometry") == 0) { 290 char *w, *h; 291 ++index; 292 if (!argv[index]) { 293 return -1; 294 } 295 w = argv[index]; 296 h = argv[index]; 297 while (*h && *h != 'x') { 298 ++h; 299 } 300 if (!*h) { 301 return -1; 302 } 303 *h++ = '\0'; 304 state->window_maxW = SDL_atoi(w); 305 state->window_maxH = SDL_atoi(h); 306 return 2; 307 } 308 if (SDL_strcasecmp(argv[index], "--logical") == 0) { 309 char *w, *h; 310 ++index; 311 if (!argv[index]) { 312 return -1; 313 } 314 w = argv[index]; 315 h = argv[index]; 316 while (*h && *h != 'x') { 317 ++h; 318 } 319 if (!*h) { 320 return -1; 321 } 322 *h++ = '\0'; 323 state->logical_w = SDL_atoi(w); 324 state->logical_h = SDL_atoi(h); 325 return 2; 326 } 327 if (SDL_strcasecmp(argv[index], "--scale") == 0) { 328 ++index; 329 if (!argv[index]) { 330 return -1; 331 } 332 state->scale = (float)SDL_atof(argv[index]); 333 return 2; 334 } 335 if (SDL_strcasecmp(argv[index], "--depth") == 0) { 336 ++index; 337 if (!argv[index]) { 338 return -1; 339 } 340 state->depth = SDL_atoi(argv[index]); 341 return 2; 342 } 343 if (SDL_strcasecmp(argv[index], "--refresh") == 0) { 344 ++index; 345 if (!argv[index]) { 346 return -1; 347 } 348 state->refresh_rate = SDL_atoi(argv[index]); 349 return 2; 350 } 351 if (SDL_strcasecmp(argv[index], "--vsync") == 0) { 352 state->render_flags |= SDL_RENDERER_PRESENTVSYNC; 353 return 1; 354 } 355 if (SDL_strcasecmp(argv[index], "--noframe") == 0) { 356 state->window_flags |= SDL_WINDOW_BORDERLESS; 357 return 1; 358 } 359 if (SDL_strcasecmp(argv[index], "--resize") == 0) { 360 state->window_flags |= SDL_WINDOW_RESIZABLE; 361 return 1; 362 } 363 if (SDL_strcasecmp(argv[index], "--minimize") == 0) { 364 state->window_flags |= SDL_WINDOW_MINIMIZED; 365 return 1; 366 } 367 if (SDL_strcasecmp(argv[index], "--maximize") == 0) { 368 state->window_flags |= SDL_WINDOW_MAXIMIZED; 369 return 1; 370 } 371 if (SDL_strcasecmp(argv[index], "--grab") == 0) { 372 state->window_flags |= SDL_WINDOW_INPUT_GRABBED; 373 return 1; 374 } 375 if (SDL_strcasecmp(argv[index], "--rate") == 0) { 376 ++index; 377 if (!argv[index]) { 378 return -1; 379 } 380 state->audiospec.freq = SDL_atoi(argv[index]); 381 return 2; 382 } 383 if (SDL_strcasecmp(argv[index], "--format") == 0) { 384 ++index; 385 if (!argv[index]) { 386 return -1; 387 } 388 if (SDL_strcasecmp(argv[index], "U8") == 0) { 389 state->audiospec.format = AUDIO_U8; 390 return 2; 391 } 392 if (SDL_strcasecmp(argv[index], "S8") == 0) { 393 state->audiospec.format = AUDIO_S8; 394 return 2; 395 } 396 if (SDL_strcasecmp(argv[index], "U16") == 0) { 397 state->audiospec.format = AUDIO_U16; 398 return 2; 399 } 400 if (SDL_strcasecmp(argv[index], "U16LE") == 0) { 401 state->audiospec.format = AUDIO_U16LSB; 402 return 2; 403 } 404 if (SDL_strcasecmp(argv[index], "U16BE") == 0) { 405 state->audiospec.format = AUDIO_U16MSB; 406 return 2; 407 } 408 if (SDL_strcasecmp(argv[index], "S16") == 0) { 409 state->audiospec.format = AUDIO_S16; 410 return 2; 411 } 412 if (SDL_strcasecmp(argv[index], "S16LE") == 0) { 413 state->audiospec.format = AUDIO_S16LSB; 414 return 2; 415 } 416 if (SDL_strcasecmp(argv[index], "S16BE") == 0) { 417 state->audiospec.format = AUDIO_S16MSB; 418 return 2; 419 } 420 return -1; 421 } 422 if (SDL_strcasecmp(argv[index], "--channels") == 0) { 423 ++index; 424 if (!argv[index]) { 425 return -1; 426 } 427 state->audiospec.channels = (Uint8) SDL_atoi(argv[index]); 428 return 2; 429 } 430 if (SDL_strcasecmp(argv[index], "--samples") == 0) { 431 ++index; 432 if (!argv[index]) { 433 return -1; 434 } 435 state->audiospec.samples = (Uint16) SDL_atoi(argv[index]); 436 return 2; 437 } 438 if ((SDL_strcasecmp(argv[index], "-h") == 0) 439 || (SDL_strcasecmp(argv[index], "--help") == 0)) { 440 /* Print the usage message */ 441 return -1; 442 } 443 if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) { 444 /* Debug flag sent by Xcode */ 445 return 2; 446 } 447 return 0; 448} 449 450const char * 451SDLTest_CommonUsage(SDLTest_CommonState * state) 452{ 453 switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { 454 case SDL_INIT_VIDEO: 455 return VIDEO_USAGE; 456 case SDL_INIT_AUDIO: 457 return AUDIO_USAGE; 458 case (SDL_INIT_VIDEO | SDL_INIT_AUDIO): 459 return VIDEO_USAGE " " AUDIO_USAGE; 460 default: 461 return ""; 462 } 463} 464 465static void 466SDLTest_PrintRendererFlag(Uint32 flag) 467{ 468 switch (flag) { 469 case SDL_RENDERER_PRESENTVSYNC: 470 fprintf(stderr, "PresentVSync"); 471 break; 472 case SDL_RENDERER_ACCELERATED: 473 fprintf(stderr, "Accelerated"); 474 break; 475 default: 476 fprintf(stderr, "0x%8.8x", flag); 477 break; 478 } 479} 480 481static void 482SDLTest_PrintPixelFormat(Uint32 format) 483{ 484 switch (format) { 485 case SDL_PIXELFORMAT_UNKNOWN: 486 fprintf(stderr, "Unknwon"); 487 break; 488 case SDL_PIXELFORMAT_INDEX1LSB: 489 fprintf(stderr, "Index1LSB"); 490 break; 491 case SDL_PIXELFORMAT_INDEX1MSB: 492 fprintf(stderr, "Index1MSB"); 493 break; 494 case SDL_PIXELFORMAT_INDEX4LSB: 495 fprintf(stderr, "Index4LSB"); 496 break; 497 case SDL_PIXELFORMAT_INDEX4MSB: 498 fprintf(stderr, "Index4MSB"); 499 break; 500 case SDL_PIXELFORMAT_INDEX8: 501 fprintf(stderr, "Index8"); 502 break; 503 case SDL_PIXELFORMAT_RGB332: 504 fprintf(stderr, "RGB332"); 505 break; 506 case SDL_PIXELFORMAT_RGB444: 507 fprintf(stderr, "RGB444"); 508 break; 509 case SDL_PIXELFORMAT_RGB555: 510 fprintf(stderr, "RGB555"); 511 break; 512 case SDL_PIXELFORMAT_BGR555: 513 fprintf(stderr, "BGR555"); 514 break; 515 case SDL_PIXELFORMAT_ARGB4444: 516 fprintf(stderr, "ARGB4444"); 517 break; 518 case SDL_PIXELFORMAT_ABGR4444: 519 fprintf(stderr, "ABGR4444"); 520 break; 521 case SDL_PIXELFORMAT_ARGB1555: 522 fprintf(stderr, "ARGB1555"); 523 break; 524 case SDL_PIXELFORMAT_ABGR1555: 525 fprintf(stderr, "ABGR1555"); 526 break; 527 case SDL_PIXELFORMAT_RGB565: 528 fprintf(stderr, "RGB565"); 529 break; 530 case SDL_PIXELFORMAT_BGR565: 531 fprintf(stderr, "BGR565"); 532 break; 533 case SDL_PIXELFORMAT_RGB24: 534 fprintf(stderr, "RGB24"); 535 break; 536 case SDL_PIXELFORMAT_BGR24: 537 fprintf(stderr, "BGR24"); 538 break; 539 case SDL_PIXELFORMAT_RGB888: 540 fprintf(stderr, "RGB888"); 541 break; 542 case SDL_PIXELFORMAT_BGR888: 543 fprintf(stderr, "BGR888"); 544 break; 545 case SDL_PIXELFORMAT_ARGB8888: 546 fprintf(stderr, "ARGB8888"); 547 break; 548 case SDL_PIXELFORMAT_RGBA8888: 549 fprintf(stderr, "RGBA8888"); 550 break; 551 case SDL_PIXELFORMAT_ABGR8888: 552 fprintf(stderr, "ABGR8888"); 553 break; 554 case SDL_PIXELFORMAT_BGRA8888: 555 fprintf(stderr, "BGRA8888"); 556 break; 557 case SDL_PIXELFORMAT_ARGB2101010: 558 fprintf(stderr, "ARGB2101010"); 559 break; 560 case SDL_PIXELFORMAT_YV12: 561 fprintf(stderr, "YV12"); 562 break; 563 case SDL_PIXELFORMAT_IYUV: 564 fprintf(stderr, "IYUV"); 565 break; 566 case SDL_PIXELFORMAT_YUY2: 567 fprintf(stderr, "YUY2"); 568 break; 569 case SDL_PIXELFORMAT_UYVY: 570 fprintf(stderr, "UYVY"); 571 break; 572 case SDL_PIXELFORMAT_YVYU: 573 fprintf(stderr, "YVYU"); 574 break; 575 case SDL_PIXELFORMAT_NV12: 576 fprintf(stderr, "NV12"); 577 break; 578 case SDL_PIXELFORMAT_NV21: 579 fprintf(stderr, "NV21"); 580 break; 581 default: 582 fprintf(stderr, "0x%8.8x", format); 583 break; 584 } 585} 586 587static void 588SDLTest_PrintRenderer(SDL_RendererInfo * info) 589{ 590 int i, count; 591 592 fprintf(stderr, " Renderer %s:\n", info->name); 593 594 fprintf(stderr, " Flags: 0x%8.8X", info->flags); 595 fprintf(stderr, " ("); 596 count = 0; 597 for (i = 0; i < sizeof(info->flags) * 8; ++i) { 598 Uint32 flag = (1 << i); 599 if (info->flags & flag) { 600 if (count > 0) { 601 fprintf(stderr, " | "); 602 } 603 SDLTest_PrintRendererFlag(flag); 604 ++count; 605 } 606 } 607 fprintf(stderr, ")\n"); 608 609 fprintf(stderr, " Texture formats (%d): ", info->num_texture_formats); 610 for (i = 0; i < (int) info->num_texture_formats; ++i) { 611 if (i > 0) { 612 fprintf(stderr, ", "); 613 } 614 SDLTest_PrintPixelFormat(info->texture_formats[i]); 615 } 616 fprintf(stderr, "\n"); 617 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); 621 } 622} 623 624static SDL_Surface * 625SDLTest_LoadIcon(const char *file) 626{ 627 SDL_Surface *icon; 628 629 /* Load the icon surface */ 630 icon = SDL_LoadBMP(file); 631 if (icon == NULL) { 632 fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); 633 return (NULL); 634 } 635 636 if (icon->format->palette) { 637 /* Set the colorkey */ 638 SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels)); 639 } 640 641 return (icon); 642} 643 644SDL_bool 645SDLTest_CommonInit(SDLTest_CommonState * state) 646{ 647 int i, j, m, n, w, h; 648 SDL_DisplayMode fullscreen_mode; 649 650 if (state->flags & SDL_INIT_VIDEO) { 651 if (state->verbose & VERBOSE_VIDEO) { 652 n = SDL_GetNumVideoDrivers(); 653 if (n == 0) { 654 fprintf(stderr, "No built-in video drivers\n"); 655 } else { 656 fprintf(stderr, "Built-in video drivers:"); 657 for (i = 0; i < n; ++i) { 658 if (i > 0) { 659 fprintf(stderr, ","); 660 } 661 fprintf(stderr, " %s", SDL_GetVideoDriver(i)); 662 } 663 fprintf(stderr, "\n"); 664 } 665 } 666 if (SDL_VideoInit(state->videodriver) < 0) { 667 fprintf(stderr, "Couldn't initialize video driver: %s\n", 668 SDL_GetError()); 669 return SDL_FALSE; 670 } 671 if (state->verbose & VERBOSE_VIDEO) { 672 fprintf(stderr, "Video driver: %s\n", 673 SDL_GetCurrentVideoDriver()); 674 } 675 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); 695 } 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); 700 } 701 if (state->gl_debug) { 702 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); 703 } 704 if (state->gl_profile_mask) { 705 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, state->gl_profile_mask); 706 } 707 708 if (state->verbose & VERBOSE_MODES) { 709 SDL_Rect bounds; 710 SDL_DisplayMode mode; 711 int bpp; 712 Uint32 Rmask, Gmask, Bmask, Amask; 713#if SDL_VIDEO_DRIVER_WINDOWS 714 int adapterIndex = 0; 715 int outputIndex = 0; 716#endif 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)); 721 722 SDL_zero(bounds); 723 SDL_GetDisplayBounds(i, &bounds); 724 fprintf(stderr, "Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y); 725 726 SDL_GetDesktopDisplayMode(i, &mode); 727 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, 728 &Bmask, &Amask); 729 fprintf(stderr, 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); 737 if (Amask) 738 fprintf(stderr, " Alpha Mask = 0x%.8x\n", Amask); 739 } 740 741 /* Print available fullscreen video modes */ 742 m = SDL_GetNumDisplayModes(i); 743 if (m == 0) { 744 fprintf(stderr, "No available fullscreen video modes\n"); 745 } else { 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); 751 fprintf(stderr, 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", 757 Rmask); 758 fprintf(stderr, " Green Mask = 0x%.8x\n", 759 Gmask); 760 fprintf(stderr, " Blue Mask = 0x%.8x\n", 761 Bmask); 762 if (Amask) 763 fprintf(stderr, 764 " Alpha Mask = 0x%.8x\n", 765 Amask); 766 } 767 } 768 } 769 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 ); 774 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 ); 778#endif 779 } 780 } 781 782 if (state->verbose & VERBOSE_RENDER) { 783 SDL_RendererInfo info; 784 785 n = SDL_GetNumRenderDrivers(); 786 if (n == 0) { 787 fprintf(stderr, "No built-in render drivers\n"); 788 } else { 789 fprintf(stderr, "Built-in render drivers:\n"); 790 for (i = 0; i < n; ++i) { 791 SDL_GetRenderDriverInfo(i, &info); 792 SDLTest_PrintRenderer(&info); 793 } 794 } 795 } 796 797 SDL_zero(fullscreen_mode); 798 switch (state->depth) { 799 case 8: 800 fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8; 801 break; 802 case 15: 803 fullscreen_mode.format = SDL_PIXELFORMAT_RGB555; 804 break; 805 case 16: 806 fullscreen_mode.format = SDL_PIXELFORMAT_RGB565; 807 break; 808 case 24: 809 fullscreen_mode.format = SDL_PIXELFORMAT_RGB24; 810 break; 811 default: 812 fullscreen_mode.format = SDL_PIXELFORMAT_RGB888; 813 break; 814 } 815 fullscreen_mode.refresh_rate = state->refresh_rate; 816 817 state->windows = 818 (SDL_Window **) SDL_malloc(state->num_windows * 819 sizeof(*state->windows)); 820 state->renderers = 821 (SDL_Renderer **) SDL_malloc(state->num_windows * 822 sizeof(*state->renderers)); 823 state->targets = 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"); 828 return SDL_FALSE; 829 } 830 for (i = 0; i < state->num_windows; ++i) { 831 char title[1024]; 832 833 if (state->num_windows > 1) { 834 SDL_snprintf(title, SDL_arraysize(title), "%s %d", 835 state->window_title, i + 1); 836 } else { 837 SDL_strlcpy(title, state->window_title, SDL_arraysize(title)); 838 } 839 state->windows[i] = 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", 845 SDL_GetError()); 846 return SDL_FALSE; 847 } 848 if (state->window_minW || state->window_minH) { 849 SDL_SetWindowMinimumSize(state->windows[i], state->window_minW, state->window_minH); 850 } 851 if (state->window_maxW || state->window_maxH) { 852 SDL_SetWindowMaximumSize(state->windows[i], state->window_maxW, state->window_maxH); 853 } 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); 858 state->window_w = w; 859 state->window_h = h; 860 } 861 if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) { 862 fprintf(stderr, "Can't set up fullscreen display mode: %s\n", 863 SDL_GetError()); 864 return SDL_FALSE; 865 } 866 867 if (state->window_icon) { 868 SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon); 869 if (icon) { 870 SDL_SetWindowIcon(state->windows[i], icon); 871 SDL_FreeSurface(icon); 872 } 873 } 874 875 SDL_ShowWindow(state->windows[i]); 876 877 state->renderers[i] = NULL; 878 state->targets[i] = NULL; 879 880 if (!state->skip_renderer 881 && (state->renderdriver 882 || !(state->window_flags & SDL_WINDOW_OPENGL))) { 883 m = -1; 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) == 890 0) { 891 m = j; 892 break; 893 } 894 } 895 if (m == -1) { 896 fprintf(stderr, 897 "Couldn't find render driver named %s", 898 state->renderdriver); 899 return SDL_FALSE; 900 } 901 } 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", 906 SDL_GetError()); 907 return SDL_FALSE; 908 } 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); 913 } 914 if (state->verbose & VERBOSE_RENDER) { 915 SDL_RendererInfo info; 916 917 fprintf(stderr, "Current renderer:\n"); 918 SDL_GetRendererInfo(state->renderers[i], &info); 919 SDLTest_PrintRenderer(&info); 920 } 921 } 922 } 923 } 924 925 if (state->flags & SDL_INIT_AUDIO) { 926 if (state->verbose & VERBOSE_AUDIO) { 927 n = SDL_GetNumAudioDrivers(); 928 if (n == 0) { 929 fprintf(stderr, "No built-in audio drivers\n"); 930 } else { 931 fprintf(stderr, "Built-in audio drivers:"); 932 for (i = 0; i < n; ++i) { 933 if (i > 0) { 934 fprintf(stderr, ","); 935 } 936 fprintf(stderr, " %s", SDL_GetAudioDriver(i)); 937 } 938 fprintf(stderr, "\n"); 939 } 940 } 941 if (SDL_AudioInit(state->audiodriver) < 0) { 942 fprintf(stderr, "Couldn't initialize audio driver: %s\n", 943 SDL_GetError()); 944 return SDL_FALSE; 945 } 946 if (state->verbose & VERBOSE_VIDEO) { 947 fprintf(stderr, "Audio driver: %s\n", 948 SDL_GetCurrentAudioDriver()); 949 } 950 951 if (SDL_OpenAudio(&state->audiospec, NULL) < 0) { 952 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); 953 return SDL_FALSE; 954 } 955 } 956 957 return SDL_TRUE; 958} 959 960static const char * 961ControllerAxisName(const SDL_GameControllerAxis axis) 962{ 963 switch (axis) 964 { 965#define AXIS_CASE(ax) case SDL_CONTROLLER_AXIS_##ax: return #ax 966 AXIS_CASE(INVALID); 967 AXIS_CASE(LEFTX); 968 AXIS_CASE(LEFTY); 969 AXIS_CASE(RIGHTX); 970 AXIS_CASE(RIGHTY); 971 AXIS_CASE(TRIGGERLEFT); 972 AXIS_CASE(TRIGGERRIGHT); 973#undef AXIS_CASE 974default: return "???"; 975 } 976} 977 978static const char * 979ControllerButtonName(const SDL_GameControllerButton button) 980{ 981 switch (button) 982 { 983#define BUTTON_CASE(btn) case SDL_CONTROLLER_BUTTON_##btn: return #btn 984 BUTTON_CASE(INVALID); 985 BUTTON_CASE(A); 986 BUTTON_CASE(B); 987 BUTTON_CASE(X); 988 BUTTON_CASE(Y); 989 BUTTON_CASE(BACK); 990 BUTTON_CASE(GUIDE); 991 BUTTON_CASE(START); 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); 1000#undef BUTTON_CASE 1001default: return "???"; 1002 } 1003} 1004 1005static void 1006SDLTest_PrintEvent(SDL_Event * event) 1007{ 1008 if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) { 1009 /* Mouse and finger motion are really spammy */ 1010 return; 1011 } 1012 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); 1018 break; 1019 case SDL_WINDOWEVENT_HIDDEN: 1020 SDL_Log("SDL EVENT: Window %d hidden", event->window.windowID); 1021 break; 1022 case SDL_WINDOWEVENT_EXPOSED: 1023 SDL_Log("SDL EVENT: Window %d exposed", event->window.windowID); 1024 break; 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); 1029 break; 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); 1034 break; 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); 1039 break; 1040 case SDL_WINDOWEVENT_MINIMIZED: 1041 SDL_Log("SDL EVENT: Window %d minimized", event->window.windowID); 1042 break; 1043 case SDL_WINDOWEVENT_MAXIMIZED: 1044 SDL_Log("SDL EVENT: Window %d maximized", event->window.windowID); 1045 break; 1046 case SDL_WINDOWEVENT_RESTORED: 1047 SDL_Log("SDL EVENT: Window %d restored", event->window.windowID); 1048 break; 1049 case SDL_WINDOWEVENT_ENTER: 1050 SDL_Log("SDL EVENT: Mouse entered window %d", 1051 event->window.windowID); 1052 break; 1053 case SDL_WINDOWEVENT_LEAVE: 1054 SDL_Log("SDL EVENT: Mouse left window %d", event->window.windowID); 1055 break; 1056 case SDL_WINDOWEVENT_FOCUS_GAINED: 1057 SDL_Log("SDL EVENT: Window %d gained keyboard focus", 1058 event->window.windowID); 1059 break; 1060 case SDL_WINDOWEVENT_FOCUS_LOST: 1061 SDL_Log("SDL EVENT: Window %d lost keyboard focus", 1062 event->window.windowID); 1063 break; 1064 case SDL_WINDOWEVENT_CLOSE: 1065 SDL_Log("SDL EVENT: Window %d closed", event->window.windowID); 1066 break; 1067 default: 1068 SDL_Log("SDL EVENT: Window %d got unknown event %d", 1069 event->window.windowID, event->window.event); 1070 break; 1071 } 1072 break; 1073 case SDL_KEYDOWN: 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)); 1079 break; 1080 case SDL_KEYUP: 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)); 1086 break; 1087 case SDL_TEXTINPUT: 1088 SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %d", 1089 event->text.text, event->text.windowID); 1090 break; 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); 1096 break; 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); 1101 break; 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); 1106 break; 1107 case SDL_MOUSEWHEEL: 1108 SDL_Log("SDL EVENT: Mouse: wheel scrolled %d in x and %d in y in window %d", 1109 event->wheel.x, event->wheel.y, event->wheel.windowID); 1110 break; 1111 case SDL_JOYDEVICEADDED: 1112 SDL_Log("SDL EVENT: Joystick index %d attached", 1113 event->jdevice.which); 1114 break; 1115 case SDL_JOYDEVICEREMOVED: 1116 SDL_Log("SDL EVENT: Joystick %d removed", 1117 event->jdevice.which); 1118 break; 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, 1122 event->jball.yrel); 1123 break; 1124 case SDL_JOYHATMOTION: 1125 { 1126 const char *position = "UNKNOWN"; 1127 switch (event->jhat.value) { 1128 case SDL_HAT_CENTERED: 1129 position = "CENTER"; 1130 break; 1131 case SDL_HAT_UP: 1132 position = "UP"; 1133 break; 1134 case SDL_HAT_RIGHTUP: 1135 position = "RIGHTUP"; 1136 break; 1137 case SDL_HAT_RIGHT: 1138 position = "RIGHT"; 1139 break; 1140 case SDL_HAT_RIGHTDOWN: 1141 position = "RIGHTDOWN"; 1142 break; 1143 case SDL_HAT_DOWN: 1144 position = "DOWN"; 1145 break; 1146 case SDL_HAT_LEFTDOWN: 1147 position = "LEFTDOWN"; 1148 break; 1149 case SDL_HAT_LEFT: 1150 position = "LEFT"; 1151 break; 1152 case SDL_HAT_LEFTUP: 1153 position = "LEFTUP"; 1154 break; 1155 } 1156 SDL_Log("SDL EVENT: Joystick %d: hat %d moved to %s", event->jhat.which, 1157 event->jhat.hat, position); 1158 } 1159 break; 1160 case SDL_JOYBUTTONDOWN: 1161 SDL_Log("SDL EVENT: Joystick %d: button %d pressed", 1162 event->jbutton.which, event->jbutton.button); 1163 break; 1164 case SDL_JOYBUTTONUP: 1165 SDL_Log("SDL EVENT: Joystick %d: button %d released", 1166 event->jbutton.which, event->jbutton.button); 1167 break; 1168 case SDL_CONTROLLERDEVICEADDED: 1169 SDL_Log("SDL EVENT: Controller index %d attached", 1170 event->cdevice.which); 1171 break; 1172 case SDL_CONTROLLERDEVICEREMOVED: 1173 SDL_Log("SDL EVENT: Controller %d removed", 1174 event->cdevice.which); 1175 break; 1176 case SDL_CONTROLLERAXISMOTION: 1177 SDL_Log("SDL EVENT: Controller %d axis %d ('%s') value: %d", 1178 event->caxis.which, 1179 event->caxis.axis, 1180 ControllerAxisName((SDL_GameControllerAxis)event->caxis.axis), 1181 event->caxis.value); 1182 break; 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)); 1187 break; 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)); 1192 break; 1193 case SDL_CLIPBOARDUPDATE: 1194 SDL_Log("SDL EVENT: Clipboard updated"); 1195 break; 1196 1197 case SDL_FINGERDOWN: 1198 case SDL_FINGERUP: 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); 1205 break; 1206 1207 case SDL_RENDER_DEVICE_RESET: 1208 SDL_Log("SDL EVENT: render device reset"); 1209 break; 1210 case SDL_RENDER_TARGETS_RESET: 1211 SDL_Log("SDL EVENT: render targets reset"); 1212 break; 1213 1214 case SDL_QUIT: 1215 SDL_Log("SDL EVENT: Quit requested"); 1216 break; 1217 case SDL_USEREVENT: 1218 SDL_Log("SDL EVENT: User event %d", event->user.code); 1219 break; 1220 default: 1221 SDL_Log("Unknown event %d", event->type); 1222 break; 1223 } 1224} 1225 1226static void 1227SDLTest_ScreenShot(SDL_Renderer *renderer) 1228{ 1229 SDL_Rect viewport; 1230 SDL_Surface *surface; 1231 1232 if (!renderer) { 1233 return; 1234 } 1235 1236 SDL_RenderGetViewport(renderer, &viewport); 1237 surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24, 1238#if SDL_BYTEORDER == SDL_LIL_ENDIAN 1239 0x00FF0000, 0x0000FF00, 0x000000FF, 1240#else 1241 0x000000FF, 0x0000FF00, 0x00FF0000, 1242#endif 1243 0x00000000); 1244 if (!surface) { 1245 fprintf(stderr, "Couldn't create surface: %s\n", SDL_GetError()); 1246 return; 1247 } 1248 1249 if (SDL_RenderReadPixels(renderer, NULL, surface->format->format, 1250 surface->pixels, surface->pitch) < 0) { 1251 fprintf(stderr, "Couldn't read screen: %s\n", SDL_GetError()); 1252 SDL_free(surface); 1253 return; 1254 } 1255 1256 if (SDL_SaveBMP(surface, "screenshot.bmp") < 0) { 1257 fprintf(stderr, "Couldn't save screenshot.bmp: %s\n", SDL_GetError()); 1258 SDL_free(surface); 1259 return; 1260 } 1261} 1262 1263static void 1264FullscreenTo(int index, int windowId) 1265{ 1266 Uint32 flags; 1267 struct SDL_Rect rect = { 0, 0, 0, 0 }; 1268 SDL_Window *window = SDL_GetWindowFromID(windowId); 1269 if (!window) { 1270 return; 1271 } 1272 1273 SDL_GetDisplayBounds( index, &rect ); 1274 1275 flags = SDL_GetWindowFlags(window); 1276 if (flags & SDL_WINDOW_FULLSCREEN) { 1277 SDL_SetWindowFullscreen( window, SDL_FALSE ); 1278 SDL_Delay( 15 ); 1279 } 1280 1281 SDL_SetWindowPosition( window, rect.x, rect.y ); 1282 SDL_SetWindowFullscreen( window, SDL_TRUE ); 1283} 1284 1285void 1286SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) 1287{ 1288 int i; 1289 static SDL_MouseMotionEvent lastEvent; 1290 1291 if (state->verbose & VERBOSE_EVENT) { 1292 SDLTest_PrintEvent(event); 1293 } 1294 1295 switch (event->type) { 1296 case SDL_WINDOWEVENT: 1297 switch (event->window.event) { 1298 case SDL_WINDOWEVENT_CLOSE: 1299 { 1300 SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); 1301 if (window) { 1302 for (i = 0; i < state->num_windows; ++i) { 1303 if (window == state->windows[i]) { 1304 if (state->targets[i]) { 1305 SDL_DestroyTexture(state->targets[i]); 1306 state->targets[i] = NULL; 1307 } 1308 if (state->renderers[i]) { 1309 SDL_DestroyRenderer(state->renderers[i]); 1310 state->renderers[i] = NULL; 1311 } 1312 SDL_DestroyWindow(state->windows[i]); 1313 state->windows[i] = NULL; 1314 break; 1315 } 1316 } 1317 } 1318 } 1319 break; 1320 } 1321 break; 1322 case SDL_KEYDOWN: { 1323 SDL_bool withControl = !!(event->key.keysym.mod & KMOD_CTRL); 1324 SDL_bool withShift = !!(event->key.keysym.mod & KMOD_SHIFT); 1325 SDL_bool withAlt = !!(event->key.keysym.mod & KMOD_ALT); 1326 1327 switch (event->key.keysym.sym) { 1328 /* Add hotkeys here */ 1329 case SDLK_PRINTSCREEN: { 1330 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1331 if (window) { 1332 for (i = 0; i < state->num_windows; ++i) { 1333 if (window == state->windows[i]) { 1334 SDLTest_ScreenShot(state->renderers[i]); 1335 } 1336 } 1337 } 1338 } 1339 break; 1340 case SDLK_EQUALS: 1341 if (withControl) { 1342 /* Ctrl-+ double the size of the window */ 1343 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1344 if (window) { 1345 int w, h; 1346 SDL_GetWindowSize(window, &w, &h); 1347 SDL_SetWindowSize(window, w*2, h*2); 1348 } 1349 } 1350 break; 1351 case SDLK_MINUS: 1352 if (withControl) { 1353 /* Ctrl-- half the size of the window */ 1354 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1355 if (window) { 1356 int w, h; 1357 SDL_GetWindowSize(window, &w, &h); 1358 SDL_SetWindowSize(window, w/2, h/2); 1359 } 1360 } 1361 break; 1362 case SDLK_c: 1363 if (withControl) { 1364 /* Ctrl-C copy awesome text! */ 1365 SDL_SetClipboardText("SDL rocks!\nYou know it!"); 1366 printf("Copied text to clipboard\n"); 1367 } 1368 if (withAlt) { 1369 /* Alt-C toggle a render clip rectangle */ 1370 for (i = 0; i < state->num_windows; ++i) { 1371 int w, h; 1372 if (state->renderers[i]) { 1373 SDL_Rect clip; 1374 SDL_GetWindowSize(state->windows[i], &w, &h); 1375 SDL_RenderGetClipRect(state->renderers[i], &clip); 1376 if (SDL_RectEmpty(&clip)) { 1377 clip.x = w/4; 1378 clip.y = h/4; 1379 clip.w = w/2; 1380 clip.h = h/2; 1381 SDL_RenderSetClipRect(state->renderers[i], &clip); 1382 } else { 1383 SDL_RenderSetClipRect(state->renderers[i], NULL); 1384 } 1385 } 1386 } 1387 } 1388 if (withShift) { 1389 SDL_Window *current_win = SDL_GetKeyboardFocus(); 1390 if (current_win) { 1391 const SDL_bool shouldCapture = (SDL_GetWindowFlags(current_win) & SDL_WINDOW_MOUSE_CAPTURE) == 0; 1392 const int rc = SDL_CaptureMouse(shouldCapture); 1393 SDL_Log("%sapturing mouse %s!\n", shouldCapture ? "C" : "Unc", (rc == 0) ? "succeeded" : "failed"); 1394 } 1395 } 1396 break; 1397 case SDLK_v: 1398 if (withControl) { 1399 /* Ctrl-V paste awesome text! */ 1400 char *text = SDL_GetClipboardText(); 1401 if (*text) { 1402 printf("Clipboard: %s\n", text); 1403 } else { 1404 printf("Clipboard is empty\n"); 1405 } 1406 SDL_free(text); 1407 } 1408 break; 1409 case SDLK_g: 1410 if (withControl) { 1411 /* Ctrl-G toggle grab */ 1412 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1413 if (window) { 1414 SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window) ? SDL_TRUE : SDL_FALSE); 1415 } 1416 } 1417 break; 1418 case SDLK_m: 1419 if (withControl) { 1420 /* Ctrl-M maximize */ 1421 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1422 if (window) { 1423 Uint32 flags = SDL_GetWindowFlags(window); 1424 if (flags & SDL_WINDOW_MAXIMIZED) { 1425 SDL_RestoreWindow(window); 1426 } else { 1427 SDL_MaximizeWindow(window); 1428 } 1429 } 1430 } 1431 break; 1432 case SDLK_r: 1433 if (withControl) { 1434 /* Ctrl-R toggle mouse relative mode */ 1435 SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode() ? SDL_TRUE : SDL_FALSE); 1436 } 1437 break; 1438 case SDLK_z: 1439 if (withControl) { 1440 /* Ctrl-Z minimize */ 1441 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1442 if (window) { 1443 SDL_MinimizeWindow(window); 1444 } 1445 } 1446 break; 1447 case SDLK_RETURN: 1448 if (withControl) { 1449 /* Ctrl-Enter toggle fullscreen */ 1450 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1451 if (window) { 1452 Uint32 flags = SDL_GetWindowFlags(window); 1453 if (flags & SDL_WINDOW_FULLSCREEN) { 1454 SDL_SetWindowFullscreen(window, SDL_FALSE); 1455 } else { 1456 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); 1457 } 1458 } 1459 } else if (withAlt) { 1460 /* Alt-Enter toggle fullscreen desktop */ 1461 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1462 if (window) { 1463 Uint32 flags = SDL_GetWindowFlags(window); 1464 if (flags & SDL_WINDOW_FULLSCREEN) { 1465 SDL_SetWindowFullscreen(window, SDL_FALSE); 1466 } else { 1467 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); 1468 } 1469 } 1470 } else if (withShift) { 1471 /* Shift-Enter toggle fullscreen desktop / fullscreen */ 1472 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1473 if (window) { 1474 Uint32 flags = SDL_GetWindowFlags(window); 1475 if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { 1476 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); 1477 } else { 1478 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); 1479 } 1480 } 1481 } 1482 1483 break; 1484 case SDLK_b: 1485 if (withControl) { 1486 /* Ctrl-B toggle window border */ 1487 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1488 if (window) { 1489 const Uint32 flags = SDL_GetWindowFlags(window); 1490 const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0) ? SDL_TRUE : SDL_FALSE; 1491 SDL_SetWindowBordered(window, b); 1492 } 1493 } 1494 break; 1495 case SDLK_a: 1496 if (withControl) { 1497 /* Ctrl-A reports absolute mouse position. */ 1498 int x, y; 1499 const Uint32 mask = SDL_GetGlobalMouseState(&x, &y); 1500 SDL_Log("ABSOLUTE MOUSE: (%d, %d)%s%s%s%s%s\n", x, y, 1501 (mask & SDL_BUTTON_LMASK) ? " [LBUTTON]" : "", 1502 (mask & SDL_BUTTON_MMASK) ? " [MBUTTON]" : "", 1503 (mask & SDL_BUTTON_RMASK) ? " [RBUTTON]" : "", 1504 (mask & SDL_BUTTON_X1MASK) ? " [X2BUTTON]" : "", 1505 (mask & SDL_BUTTON_X2MASK) ? " [X2BUTTON]" : ""); 1506 } 1507 break; 1508 case SDLK_0: 1509 if (withControl) { 1510 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1511 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Test Message", "You're awesome!", window); 1512 } 1513 break; 1514 case SDLK_1: 1515 if (withControl) { 1516 FullscreenTo(0, event->key.windowID); 1517 } 1518 break; 1519 case SDLK_2: 1520 if (withControl) { 1521 FullscreenTo(1, event->key.windowID); 1522 } 1523 break; 1524 case SDLK_ESCAPE: 1525 *done = 1; 1526 break; 1527 case SDLK_SPACE: 1528 { 1529 char message[256]; 1530 SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); 1531 1532 SDL_snprintf(message, sizeof(message), "(%i, %i), rel (%i, %i)\n", lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel); 1533 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Last mouse position", message, window); 1534 break; 1535 } 1536 default: 1537 break; 1538 } 1539 break; 1540 } 1541 case SDL_QUIT: 1542 *done = 1; 1543 break; 1544 case SDL_MOUSEMOTION: 1545 lastEvent = event->motion; 1546 break; 1547 } 1548} 1549 1550void 1551SDLTest_CommonQuit(SDLTest_CommonState * state) 1552{ 1553 int i; 1554 1555 SDL_free(state->windows); 1556 if (state->targets) { 1557 for (i = 0; i < state->num_windows; ++i) { 1558 if (state->targets[i]) { 1559 SDL_DestroyTexture(state->targets[i]); 1560 } 1561 } 1562 SDL_free(state->targets); 1563 } 1564 if (state->renderers) { 1565 for (i = 0; i < state->num_windows; ++i) { 1566 if (state->renderers[i]) { 1567 SDL_DestroyRenderer(state->renderers[i]); 1568 } 1569 } 1570 SDL_free(state->renderers); 1571 } 1572 if (state->flags & SDL_INIT_VIDEO) { 1573 SDL_VideoQuit(); 1574 } 1575 if (state->flags & SDL_INIT_AUDIO) { 1576 SDL_AudioQuit(); 1577 } 1578 SDL_free(state); 1579 SDL_Quit(); 1580} 1581 1582/* vi: set ts=4 sw=4 expandtab: */