test/testintersections.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 18 Dec 2014 00:19:52 -0500
changeset 9278 8900afb78a19
parent 8149 681eb46b8ac4
child 9607 7746ab058d12
permissions -rw-r--r--
Initial merge of Emscripten port!

With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.

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