test/testintersections.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 05 Oct 2013 19:09:03 -0700
changeset 7787 e6f3e8fc96ea
parent 7639 9406b7dd2f2d
child 8149 681eb46b8ac4
permissions -rw-r--r--
Fixed bug 2132 - Tests may use invalid SDL_window pointers when windows are closed

norfanin

Some of the tests keep using the pointers of a destroyed SDL_Window when the common event handling handled the close event. The event handler itself does not NULL the pointer after the destruction.

The attached patch adds a loop in the handler that will assign NULL to the destroyed window. It also adds checks to some of the tests so they skip those windows by checking for NULL.
slouken@5535
     1
/*
slouken@7517
     2
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@2994
    12
slouken@2994
    13
/* Simple program:  draw as many random objects on the screen as possible */
slouken@2994
    14
slouken@2994
    15
#include <stdlib.h>
slouken@2994
    16
#include <stdio.h>
slouken@2994
    17
#include <time.h>
slouken@2994
    18
slouken@6785
    19
#include "SDL_test_common.h"
slouken@2994
    20
slouken@2994
    21
#define SWAP(typ,a,b) do{typ t=a;a=b;b=t;}while(0)
slouken@7191
    22
#define NUM_OBJECTS 100
slouken@2994
    23
slouken@6785
    24
static SDLTest_CommonState *state;
slouken@2994
    25
static int num_objects;
slouken@2994
    26
static SDL_bool cycle_color;
slouken@2994
    27
static SDL_bool cycle_alpha;
slouken@2994
    28
static int cycle_direction = 1;
slouken@2994
    29
static int current_alpha = 255;
slouken@2994
    30
static int current_color = 255;
slouken@2994
    31
static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE;
slouken@2994
    32
slouken@2994
    33
void
slouken@5297
    34
DrawPoints(SDL_Renderer * renderer)
slouken@2994
    35
{
slouken@2994
    36
    int i;
slouken@2994
    37
    int x, y;
slouken@5297
    38
    SDL_Rect viewport;
slouken@2994
    39
slouken@2994
    40
    /* Query the sizes */
slouken@5297
    41
    SDL_RenderGetViewport(renderer, &viewport);
slouken@2994
    42
slouken@2994
    43
    for (i = 0; i < num_objects * 4; ++i) {
slouken@2994
    44
        /* Cycle the color and alpha, if desired */
slouken@2994
    45
        if (cycle_color) {
slouken@2994
    46
            current_color += cycle_direction;
slouken@2994
    47
            if (current_color < 0) {
slouken@2994
    48
                current_color = 0;
slouken@2994
    49
                cycle_direction = -cycle_direction;
slouken@2994
    50
            }
slouken@2994
    51
            if (current_color > 255) {
slouken@2994
    52
                current_color = 255;
slouken@2994
    53
                cycle_direction = -cycle_direction;
slouken@2994
    54
            }
slouken@2994
    55
        }
slouken@2994
    56
        if (cycle_alpha) {
slouken@2994
    57
            current_alpha += cycle_direction;
slouken@2994
    58
            if (current_alpha < 0) {
slouken@2994
    59
                current_alpha = 0;
slouken@2994
    60
                cycle_direction = -cycle_direction;
slouken@2994
    61
            }
slouken@2994
    62
            if (current_alpha > 255) {
slouken@2994
    63
                current_alpha = 255;
slouken@2994
    64
                cycle_direction = -cycle_direction;
slouken@2994
    65
            }
slouken@2994
    66
        }
slouken@5147
    67
        SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color,
slouken@2994
    68
                               (Uint8) current_color, (Uint8) current_alpha);
slouken@2994
    69
slouken@5297
    70
        x = rand() % viewport.w;
slouken@5297
    71
        y = rand() % viewport.h;
slouken@5147
    72
        SDL_RenderDrawPoint(renderer, x, y);
slouken@2994
    73
    }
slouken@2994
    74
}
slouken@2994
    75
slouken@2994
    76
#define MAX_LINES 16
slouken@2994
    77
int num_lines = 0;
slouken@2994
    78
SDL_Rect lines[MAX_LINES];
slouken@2997
    79
static int
slouken@2997
    80
add_line(int x1, int y1, int x2, int y2)
slouken@2997
    81
{
slouken@2997
    82
    if (num_lines >= MAX_LINES)
slouken@2997
    83
        return 0;
slouken@2997
    84
    if ((x1 == x2) && (y1 == y2))
slouken@2997
    85
        return 0;
slouken@2994
    86
aschiffler@7639
    87
    SDL_Log("adding line (%d, %d), (%d, %d)\n", x1, y1, x2, y2);
slouken@2994
    88
    lines[num_lines].x = x1;
slouken@2994
    89
    lines[num_lines].y = y1;
slouken@2994
    90
    lines[num_lines].w = x2;
slouken@2994
    91
    lines[num_lines].h = y2;
slouken@2994
    92
slouken@2994
    93
    return ++num_lines;
slouken@2994
    94
}
slouken@2994
    95
slouken@2994
    96
slouken@2994
    97
void
slouken@5297
    98
DrawLines(SDL_Renderer * renderer)
slouken@2994
    99
{
slouken@2994
   100
    int i;
slouken@5297
   101
    SDL_Rect viewport;
slouken@2994
   102
slouken@2994
   103
    /* Query the sizes */
slouken@5297
   104
    SDL_RenderGetViewport(renderer, &viewport);
slouken@5297
   105
slouken@5297
   106
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
slouken@2994
   107
slouken@2994
   108
    for (i = 0; i < num_lines; ++i) {
slouken@2994
   109
        if (i == -1) {
slouken@5297
   110
            SDL_RenderDrawLine(renderer, 0, 0, viewport.w - 1, viewport.h - 1);
slouken@5297
   111
            SDL_RenderDrawLine(renderer, 0, viewport.h - 1, viewport.w - 1, 0);
slouken@5297
   112
            SDL_RenderDrawLine(renderer, 0, viewport.h / 2, viewport.w - 1, viewport.h / 2);
slouken@5297
   113
            SDL_RenderDrawLine(renderer, viewport.w / 2, 0, viewport.w / 2, viewport.h - 1);
slouken@2994
   114
        } else {
slouken@5147
   115
            SDL_RenderDrawLine(renderer, lines[i].x, lines[i].y, lines[i].w, lines[i].h);
slouken@2994
   116
        }
slouken@2994
   117
    }
slouken@2994
   118
}
slouken@2994
   119
slouken@2994
   120
#define MAX_RECTS 16
slouken@2994
   121
int num_rects = 0;
slouken@2994
   122
SDL_Rect rects[MAX_RECTS];
slouken@2997
   123
static int
slouken@2997
   124
add_rect(int x1, int y1, int x2, int y2)
slouken@2997
   125
{
slouken@2997
   126
    if (num_rects >= MAX_RECTS)
slouken@2997
   127
        return 0;
slouken@2997
   128
    if ((x1 == x2) || (y1 == y2))
slouken@2997
   129
        return 0;
slouken@2994
   130
slouken@2997
   131
    if (x1 > x2)
slouken@2997
   132
        SWAP(int, x1, x2);
slouken@2997
   133
    if (y1 > y2)
slouken@2997
   134
        SWAP(int, y1, y2);
slouken@2994
   135
aschiffler@7639
   136
    SDL_Log("adding rect (%d, %d), (%d, %d) [%dx%d]\n", x1, y1, x2, y2,
slouken@2997
   137
           x2 - x1, y2 - y1);
slouken@2994
   138
slouken@2994
   139
    rects[num_rects].x = x1;
slouken@2994
   140
    rects[num_rects].y = y1;
slouken@2994
   141
    rects[num_rects].w = x2 - x1;
slouken@2994
   142
    rects[num_rects].h = y2 - y1;
slouken@2994
   143
slouken@2994
   144
    return ++num_rects;
slouken@2994
   145
}
slouken@2994
   146
slouken@2994
   147
static void
slouken@5297
   148
DrawRects(SDL_Renderer * renderer)
slouken@2994
   149
{
slouken@5297
   150
    SDL_SetRenderDrawColor(renderer, 255, 127, 0, 255);
slouken@5297
   151
    SDL_RenderFillRects(renderer, rects, num_rects);
slouken@2994
   152
}
slouken@2994
   153
slouken@2994
   154
static void
slouken@5297
   155
DrawRectLineIntersections(SDL_Renderer * renderer)
slouken@2994
   156
{
slouken@5297
   157
    int i, j;
slouken@2994
   158
slouken@5297
   159
    SDL_SetRenderDrawColor(renderer, 0, 255, 55, 255);
slouken@2994
   160
slouken@2994
   161
    for (i = 0; i < num_rects; i++)
slouken@2997
   162
        for (j = 0; j < num_lines; j++) {
slouken@2997
   163
            int x1, y1, x2, y2;
slouken@2997
   164
            SDL_Rect r;
slouken@2994
   165
slouken@2997
   166
            r = rects[i];
slouken@2997
   167
            x1 = lines[j].x;
slouken@2997
   168
            y1 = lines[j].y;
slouken@2997
   169
            x2 = lines[j].w;
slouken@2997
   170
            y2 = lines[j].h;
slouken@2997
   171
slouken@2997
   172
            if (SDL_IntersectRectAndLine(&r, &x1, &y1, &x2, &y2)) {
slouken@5147
   173
                SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
slouken@2997
   174
            }
slouken@2994
   175
        }
slouken@2994
   176
}
slouken@2994
   177
slouken@2994
   178
static void
slouken@5297
   179
DrawRectRectIntersections(SDL_Renderer * renderer)
slouken@2994
   180
{
slouken@2994
   181
    int i, j;
slouken@2994
   182
slouken@5297
   183
    SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255);
slouken@5297
   184
slouken@2994
   185
    for (i = 0; i < num_rects; i++)
slouken@2997
   186
        for (j = i + 1; j < num_rects; j++) {
slouken@2997
   187
            SDL_Rect r;
slouken@2997
   188
            if (SDL_IntersectRect(&rects[i], &rects[j], &r)) {
slouken@5147
   189
                SDL_RenderFillRect(renderer, &r);
slouken@2997
   190
            }
slouken@2994
   191
        }
slouken@2994
   192
}
slouken@2994
   193
slouken@2994
   194
int
slouken@2994
   195
main(int argc, char *argv[])
slouken@2994
   196
{
slouken@2994
   197
    int mouse_begin_x = -1, mouse_begin_y = -1;
slouken@2994
   198
    int i, done;
slouken@2994
   199
    SDL_Event event;
slouken@2994
   200
    Uint32 then, now, frames;
slouken@2994
   201
aschiffler@7639
   202
    /* Enable standard application logging */
aschiffler@7639
   203
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   204
slouken@2994
   205
    /* Initialize parameters */
slouken@2994
   206
    num_objects = NUM_OBJECTS;
slouken@2994
   207
slouken@2994
   208
    /* Initialize test framework */
slouken@6785
   209
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
slouken@2994
   210
    if (!state) {
slouken@2994
   211
        return 1;
slouken@2994
   212
    }
slouken@2994
   213
    for (i = 1; i < argc;) {
slouken@2994
   214
        int consumed;
slouken@2994
   215
slouken@6785
   216
        consumed = SDLTest_CommonArg(state, i);
slouken@2994
   217
        if (consumed == 0) {
slouken@2994
   218
            consumed = -1;
slouken@2994
   219
            if (SDL_strcasecmp(argv[i], "--blend") == 0) {
slouken@2994
   220
                if (argv[i + 1]) {
slouken@2994
   221
                    if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
slouken@2994
   222
                        blendMode = SDL_BLENDMODE_NONE;
slouken@2994
   223
                        consumed = 2;
slouken@2994
   224
                    } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
slouken@2994
   225
                        blendMode = SDL_BLENDMODE_BLEND;
slouken@2994
   226
                        consumed = 2;
slouken@2994
   227
                    } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
slouken@2994
   228
                        blendMode = SDL_BLENDMODE_ADD;
slouken@2994
   229
                        consumed = 2;
slouken@5184
   230
                    } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
slouken@5184
   231
                        blendMode = SDL_BLENDMODE_MOD;
slouken@5184
   232
                        consumed = 2;
slouken@2994
   233
                    }
slouken@2994
   234
                }
slouken@2994
   235
            } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
slouken@2994
   236
                cycle_color = SDL_TRUE;
slouken@2994
   237
                consumed = 1;
slouken@2994
   238
            } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
slouken@2994
   239
                cycle_alpha = SDL_TRUE;
slouken@2994
   240
                consumed = 1;
slouken@2994
   241
            } else if (SDL_isdigit(*argv[i])) {
slouken@2994
   242
                num_objects = SDL_atoi(argv[i]);
slouken@2994
   243
                consumed = 1;
slouken@2994
   244
            }
slouken@2994
   245
        }
slouken@2994
   246
        if (consumed < 0) {
aschiffler@7639
   247
            SDL_Log("Usage: %s %s [--blend none|blend|add|mod] [--cyclecolor] [--cyclealpha]\n",
slouken@6785
   248
                    argv[0], SDLTest_CommonUsage(state));
slouken@2994
   249
            return 1;
slouken@2994
   250
        }
slouken@2994
   251
        i += consumed;
slouken@2994
   252
    }
slouken@6785
   253
    if (!SDLTest_CommonInit(state)) {
slouken@2994
   254
        return 2;
slouken@2994
   255
    }
slouken@2994
   256
slouken@2994
   257
    /* Create the windows and initialize the renderers */
slouken@2994
   258
    for (i = 0; i < state->num_windows; ++i) {
slouken@5147
   259
        SDL_Renderer *renderer = state->renderers[i];
slouken@5147
   260
        SDL_SetRenderDrawBlendMode(renderer, blendMode);
slouken@5147
   261
        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
slouken@5147
   262
        SDL_RenderClear(renderer);
slouken@2994
   263
    }
slouken@2994
   264
slouken@2994
   265
    srand(time(NULL));
slouken@2994
   266
slouken@2994
   267
    /* Main render loop */
slouken@2994
   268
    frames = 0;
slouken@2994
   269
    then = SDL_GetTicks();
slouken@2994
   270
    done = 0;
slouken@2994
   271
    while (!done) {
slouken@2994
   272
        /* Check for events */
slouken@2994
   273
        ++frames;
slouken@2994
   274
        while (SDL_PollEvent(&event)) {
slouken@6785
   275
            SDLTest_CommonEvent(state, &event, &done);
slouken@2994
   276
            switch (event.type) {
slouken@2994
   277
            case SDL_MOUSEBUTTONDOWN:
slouken@4465
   278
                mouse_begin_x = event.button.x;
slouken@4465
   279
                mouse_begin_y = event.button.y;
slouken@2994
   280
                break;
slouken@2994
   281
            case SDL_MOUSEBUTTONUP:
slouken@4465
   282
                if (event.button.button == 3)
slouken@4465
   283
                    add_line(mouse_begin_x, mouse_begin_y, event.button.x,
slouken@4465
   284
                             event.button.y);
slouken@4465
   285
                if (event.button.button == 1)
slouken@4465
   286
                    add_rect(mouse_begin_x, mouse_begin_y, event.button.x,
slouken@4465
   287
                             event.button.y);
slouken@2994
   288
                break;
slouken@2994
   289
            case SDL_KEYDOWN:
slouken@2994
   290
                switch (event.key.keysym.sym) {
slouken@2997
   291
                case 'l':
slouken@2997
   292
                    if (event.key.keysym.mod & KMOD_SHIFT)
slouken@2997
   293
                        num_lines = 0;
slouken@2997
   294
                    else
slouken@2997
   295
                        add_line(rand() % 640, rand() % 480, rand() % 640,
slouken@2997
   296
                                 rand() % 480);
slouken@2997
   297
                    break;
slouken@2997
   298
                case 'r':
slouken@2997
   299
                    if (event.key.keysym.mod & KMOD_SHIFT)
slouken@2997
   300
                        num_rects = 0;
slouken@2997
   301
                    else
slouken@2997
   302
                        add_rect(rand() % 640, rand() % 480, rand() % 640,
slouken@2997
   303
                                 rand() % 480);
slouken@2997
   304
                    break;
slouken@2994
   305
                }
slouken@2994
   306
                break;
slouken@2994
   307
            default:
slouken@2994
   308
                break;
slouken@2994
   309
            }
slouken@2994
   310
        }
slouken@2994
   311
        for (i = 0; i < state->num_windows; ++i) {
slouken@5147
   312
            SDL_Renderer *renderer = state->renderers[i];
slouken@7787
   313
            if (state->windows[i] == NULL)
slouken@7787
   314
                continue;
slouken@5147
   315
            SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
slouken@5147
   316
            SDL_RenderClear(renderer);
slouken@2994
   317
slouken@5297
   318
            DrawRects(renderer);
slouken@5297
   319
            DrawPoints(renderer);
slouken@5297
   320
            DrawRectRectIntersections(renderer);
slouken@5297
   321
            DrawLines(renderer);
slouken@5297
   322
            DrawRectLineIntersections(renderer);
slouken@2994
   323
slouken@5147
   324
            SDL_RenderPresent(renderer);
slouken@2994
   325
        }
slouken@2994
   326
    }
slouken@2994
   327
slouken@6785
   328
    SDLTest_CommonQuit(state);
lestat@3371
   329
slouken@2994
   330
    /* Print out some timing information */
slouken@2994
   331
    now = SDL_GetTicks();
slouken@2994
   332
    if (now > then) {
slouken@2994
   333
        double fps = ((double) frames * 1000) / (now - then);
aschiffler@7639
   334
        SDL_Log("%2.2f frames per second\n", fps);
slouken@2994
   335
    }
slouken@2994
   336
    return 0;
slouken@2994
   337
}
slouken@2994
   338
slouken@2994
   339
/* vi: set ts=4 sw=4 expandtab: */