Added an automated test for rectangle routines, currently only testing line clipping.
authorSam Lantinga <slouken@libsdl.org>
Fri, 11 Dec 2009 09:22:34 +0000
changeset 35410c429a5fda8a
parent 3540 3ad09fdbfcb0
child 3542 97eae5a705f9
Added an automated test for rectangle routines, currently only testing line clipping.
Use the Cohen-Sutherland algorithm for line clipping which uses integer math and preserves ordering of clipped points.

Removed getopt() support in testsdl.c, replaced with simple argv scanning.
src/video/SDL_rect.c
test/automated/Makefile
test/automated/platform/platform.h
test/automated/rect/rect.c
test/automated/rect/rect.h
test/automated/testsdl.c
     1.1 --- a/src/video/SDL_rect.c	Fri Dec 11 09:13:51 2009 +0000
     1.2 +++ b/src/video/SDL_rect.c	Fri Dec 11 09:22:34 2009 +0000
     1.3 @@ -196,16 +196,40 @@
     1.4      return SDL_TRUE;
     1.5  }
     1.6  
     1.7 +/* Use the Cohen-Sutherland algorithm for line clipping */
     1.8 +#define CODE_BOTTOM 1
     1.9 +#define CODE_TOP    2
    1.10 +#define CODE_LEFT   4
    1.11 +#define CODE_RIGHT  8
    1.12 +
    1.13 +static int ComputeOutCode(const SDL_Rect * rect, int x, int y)
    1.14 +{
    1.15 +    int code = 0;
    1.16 +    if (y < 0) {
    1.17 +        code |= CODE_TOP;
    1.18 +    } else if (y >= rect->y + rect->h) {
    1.19 +        code |= CODE_BOTTOM;
    1.20 +    }
    1.21 +    if (x < 0) {
    1.22 +        code |= CODE_LEFT;
    1.23 +    } else if (x >= rect->x + rect->w) {
    1.24 +        code |= CODE_RIGHT;
    1.25 +    }
    1.26 +    return code;
    1.27 +}
    1.28 +
    1.29  SDL_bool
    1.30  SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
    1.31                           int *Y2)
    1.32  {
    1.33 +    int x, y;
    1.34      int x1, y1;
    1.35      int x2, y2;
    1.36      int rectx1;
    1.37      int recty1;
    1.38      int rectx2;
    1.39      int recty2;
    1.40 +    int outcode1, outcode2;
    1.41  
    1.42      if (!rect || !X1 || !Y1 || !X2 || !Y2) {
    1.43          return SDL_FALSE;
    1.44 @@ -262,95 +286,57 @@
    1.45          return SDL_TRUE;
    1.46      }
    1.47  
    1.48 -    else {
    1.49 -        /* The task of clipping a line with finite slope ratios in a fixed-
    1.50 -         * precision coordinate space is not as immediately simple as it is
    1.51 -         * with coordinates of arbitrary precision. If the ratio of slopes
    1.52 -         * between the input line segment and the result line segment is not
    1.53 -         * a whole number, you have in fact *moved* the line segment a bit,
    1.54 -         * and there can be no avoiding it without more precision
    1.55 -         */
    1.56 -        int *x_result_[] = { X1, X2, NULL }, **x_result = x_result_;
    1.57 -        int *y_result_[] = { Y1, Y2, NULL }, **y_result = y_result_;
    1.58 -        SDL_bool intersection = SDL_FALSE;
    1.59 -        double b, m, left, right, bottom, top;
    1.60 -        int xl, xh, yl, yh;
    1.61 -
    1.62 -        /* solve mx+b line formula */
    1.63 -        m = (double) (y1 - y2) / (double) (x1 - x2);
    1.64 -        b = y2 - m * (double) x2;
    1.65 -
    1.66 -        /* find some linear intersections */
    1.67 -        left = (m * (double) rectx1) + b;
    1.68 -        right = (m * (double) rectx2) + b;
    1.69 -        top = (recty1 - b) / m;
    1.70 -        bottom = (recty2 - b) / m;
    1.71 -
    1.72 -        /* sort end-points' x and y components individually */
    1.73 -        if (x1 < x2) {
    1.74 -            xl = x1;
    1.75 -            xh = x2;
    1.76 -        } else {
    1.77 -            xl = x2;
    1.78 -            xh = x1;
    1.79 -        }
    1.80 -        if (y1 < y2) {
    1.81 -            yl = y1;
    1.82 -            yh = y2;
    1.83 -        } else {
    1.84 -            yl = y2;
    1.85 -            yh = y1;
    1.86 +    /* More complicated Cohen-Sutherland algorithm */
    1.87 +    outcode1 = ComputeOutCode(rect, x1, y1);
    1.88 +    outcode2 = ComputeOutCode(rect, x2, y2);
    1.89 +    while (outcode1 || outcode2) {
    1.90 +        if (outcode1 & outcode2) {
    1.91 +            return SDL_FALSE;
    1.92          }
    1.93  
    1.94 -#define RISING(a, b, c) (((a)<=(b))&&((b)<=(c)))
    1.95 -
    1.96 -        /* check for a point that's entirely inside the rect */
    1.97 -        if (RISING(rectx1, x1, rectx2) && RISING(recty1, y1, recty2)) {
    1.98 -            x_result++;
    1.99 -            y_result++;
   1.100 -            intersection = SDL_TRUE;
   1.101 -        } else
   1.102 -            /* it was determined earlier that *both* end-points are not contained */
   1.103 -        if (RISING(rectx1, x2, rectx2) && RISING(recty1, y2, recty2)) {
   1.104 -            **(x_result++) = x2;
   1.105 -            **(y_result++) = y2;
   1.106 -            intersection = SDL_TRUE;
   1.107 +        if (outcode1) {
   1.108 +            if (outcode1 & CODE_TOP) {
   1.109 +                y = recty1;
   1.110 +                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
   1.111 +            } else if (outcode1 & CODE_BOTTOM) {
   1.112 +                y = recty2;
   1.113 +                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
   1.114 +            } else if (outcode1 & CODE_LEFT) {
   1.115 +                x = rectx1;
   1.116 +                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
   1.117 +            } else if (outcode1 & CODE_RIGHT) {
   1.118 +                x = rectx2;
   1.119 +                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
   1.120 +            }
   1.121 +            x1 = x;
   1.122 +            y1 = y;
   1.123 +            outcode1 = ComputeOutCode(rect, x, y);
   1.124          }
   1.125  
   1.126 -        if (RISING(recty1, left, recty2) && RISING(xl, rectx1, xh)) {
   1.127 -            **(x_result++) = rectx1;
   1.128 -            **(y_result++) = (int) left;
   1.129 -            intersection = SDL_TRUE;
   1.130 +        if (outcode2) {
   1.131 +            if (outcode2 & CODE_TOP) {
   1.132 +                y = recty1;
   1.133 +                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
   1.134 +            } else if (outcode2 & CODE_BOTTOM) {
   1.135 +                y = recty2;
   1.136 +                x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
   1.137 +            } else if (outcode2 & CODE_LEFT) {
   1.138 +                x = rectx1;
   1.139 +                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
   1.140 +            } else if (outcode2 & CODE_RIGHT) {
   1.141 +                x = rectx2;
   1.142 +                y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
   1.143 +            }
   1.144 +            x2 = x;
   1.145 +            y2 = y;
   1.146 +            outcode2 = ComputeOutCode(rect, x, y);
   1.147          }
   1.148 -
   1.149 -        if (*x_result == NULL)
   1.150 -            return intersection;
   1.151 -        if (RISING(recty1, right, recty2) && RISING(xl, rectx2, xh)) {
   1.152 -            **(x_result++) = rectx2;
   1.153 -            **(y_result++) = (int) right;
   1.154 -            intersection = SDL_TRUE;
   1.155 -        }
   1.156 -
   1.157 -        if (*x_result == NULL)
   1.158 -            return intersection;
   1.159 -        if (RISING(rectx1, top, rectx2) && RISING(yl, recty1, yh)) {
   1.160 -            **(x_result++) = (int) top;
   1.161 -            **(y_result++) = recty1;
   1.162 -            intersection = SDL_TRUE;
   1.163 -        }
   1.164 -
   1.165 -        if (*x_result == NULL)
   1.166 -            return intersection;
   1.167 -        if (RISING(rectx1, bottom, rectx2) && RISING(yl, recty2, yh)) {
   1.168 -            **(x_result++) = (int) bottom;
   1.169 -            **(y_result++) = recty2;
   1.170 -            intersection = SDL_TRUE;
   1.171 -        }
   1.172 -
   1.173 -        return intersection;
   1.174      }
   1.175 -
   1.176 -    return SDL_FALSE;
   1.177 +    *X1 = x1;
   1.178 +    *Y1 = y1;
   1.179 +    *X2 = x2;
   1.180 +    *Y2 = y2;
   1.181 +    return SDL_TRUE;
   1.182  }
   1.183  
   1.184  void
     2.1 --- a/test/automated/Makefile	Fri Dec 11 09:13:51 2009 +0000
     2.2 +++ b/test/automated/Makefile	Fri Dec 11 09:22:34 2009 +0000
     2.3 @@ -8,8 +8,9 @@
     2.4  #LDFLAGS := -lm -ldl -lesd -lpthread
     2.5  
     2.6  SRC         	:= testsdl.c \
     2.7 +						platform/platform.c \
     2.8  						rwops/rwops.c \
     2.9 -						platform/platform.c \
    2.10 +						rect/rect.c \
    2.11  						surface/surface.c \
    2.12  						render/render.c \
    2.13  						audio/audio.c
    2.14 @@ -17,8 +18,9 @@
    2.15  COMMON_INCLUDE := SDL_at.h
    2.16  
    2.17  TESTS_ALL := testsdl \
    2.18 +	platform/platform \
    2.19  	rwops/rwops \
    2.20 -	platform/platform \
    2.21 +	rect/rect \
    2.22  	surface/surface \
    2.23  	render/render \
    2.24  	audio/audio
    2.25 @@ -35,11 +37,14 @@
    2.26  testsdl: $(SRC) $(COMMON_SRC)
    2.27  	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(SRC) $(COMMON_SRC)
    2.28  
    2.29 +platform/platform: platform/platform.c $(COMMON_INCLUDE) $(COMMON_SRC)
    2.30 +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ platform/platform.c $(COMMON_SRC) -DTEST_STANDALONE
    2.31 +
    2.32  rwops/rwops: rwops/rwops.c $(COMMON_INCLUDE) $(COMMON_SRC)
    2.33  	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ rwops/rwops.c $(COMMON_SRC) -DTEST_STANDALONE
    2.34  
    2.35 -platform/platform: platform/platform.c $(COMMON_INCLUDE) $(COMMON_SRC)
    2.36 -	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ platform/platform.c $(COMMON_SRC) -DTEST_STANDALONE
    2.37 +rect/rect: rect/rect.c $(COMMON_INCLUDE) $(COMMON_SRC)
    2.38 +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ rect/rect.c $(COMMON_SRC) -DTEST_STANDALONE
    2.39  
    2.40  surface/surface: surface/surface.c $(COMMON_INCLUDE) $(COMMON_SRC)
    2.41  	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ surface/surface.c $(COMMON_SRC) -DTEST_STANDALONE
     3.1 --- a/test/automated/platform/platform.h	Fri Dec 11 09:13:51 2009 +0000
     3.2 +++ b/test/automated/platform/platform.h	Fri Dec 11 09:22:34 2009 +0000
     3.3 @@ -11,7 +11,6 @@
     3.4  #  define _TEST_PLATFORM
     3.5  
     3.6  
     3.7 -const char *platform_getPlatform (void);
     3.8  int test_platform (void);
     3.9  
    3.10  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/automated/rect/rect.c	Fri Dec 11 09:22:34 2009 +0000
     4.3 @@ -0,0 +1,156 @@
     4.4 +/**
     4.5 + * Automated SDL rect test.
     4.6 + *
     4.7 + * Written by Edgar Simo "bobbens"
     4.8 + *
     4.9 + * Released under Public Domain.
    4.10 + */
    4.11 +
    4.12 +
    4.13 +
    4.14 +
    4.15 +#include "SDL_rect.h"
    4.16 +#include "../SDL_at.h"
    4.17 +
    4.18 +
    4.19 +/*
    4.20 + * Prototypes.
    4.21 + */
    4.22 +static void rect_testIntersectRectAndLine (void);
    4.23 +
    4.24 +
    4.25 +/**
    4.26 + * @brief Tests SDL_IntersectRectAndLine()
    4.27 + */
    4.28 +static void rect_testIntersectRectAndLine (void)
    4.29 +{
    4.30 +    SDL_Rect rect = { 0, 0, 32, 32 };
    4.31 +    int x1, y1;
    4.32 +    int x2, y2;
    4.33 +    SDL_bool clipped;
    4.34 +
    4.35 +    SDL_ATbegin( "IntersectRectAndLine" );
    4.36 +
    4.37 +    x1 = -10;
    4.38 +    y1 = 0;
    4.39 +    x2 = -10;
    4.40 +    y2 = 31;
    4.41 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
    4.42 +    SDL_ATvassert( !clipped &&
    4.43 +                   x1 == -10 && y1 == 0 && x2 == -10 && y2 == 31,
    4.44 +        "line outside to the left was incorrectly clipped: %d,%d - %d,%d",
    4.45 +        x1, y1, x2, y2);
    4.46 +
    4.47 +    x1 = 40;
    4.48 +    y1 = 0;
    4.49 +    x2 = 40;
    4.50 +    y2 = 31;
    4.51 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
    4.52 +    SDL_ATvassert( !clipped &&
    4.53 +                   x1 == 40 && y1 == 0 && x2 == 40 && y2 == 31,
    4.54 +        "line outside to the right was incorrectly clipped: %d,%d - %d,%d",
    4.55 +        x1, y1, x2, y2);
    4.56 +
    4.57 +    x1 = 0;
    4.58 +    y1 = -10;
    4.59 +    x2 = 31;
    4.60 +    y2 = -10;
    4.61 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
    4.62 +    SDL_ATvassert( !clipped &&
    4.63 +                   x1 == 0 && y1 == -10 && x2 == 31 && y2 == -10,
    4.64 +        "line outside above was incorrectly clipped: %d,%d - %d,%d",
    4.65 +        x1, y1, x2, y2);
    4.66 +
    4.67 +    x1 = 0;
    4.68 +    y1 = 40;
    4.69 +    x2 = 31;
    4.70 +    y2 = 40;
    4.71 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
    4.72 +    SDL_ATvassert( !clipped &&
    4.73 +                   x1 == 0 && y1 == 40 && x2 == 31 && y2 == 40,
    4.74 +        "line outside below was incorrectly clipped: %d,%d - %d,%d",
    4.75 +        x1, y1, x2, y2);
    4.76 +
    4.77 +    x1 = 0;
    4.78 +    y1 = 0;
    4.79 +    x2 = 31;
    4.80 +    y2 = 31;
    4.81 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
    4.82 +    SDL_ATvassert( clipped &&
    4.83 +                   x1 == 0 && y1 == 0 && x2 == 31 && y2 == 31,
    4.84 +        "line fully inside rect was clipped: %d,%d - %d,%d",
    4.85 +        x1, y1, x2, y2);
    4.86 +
    4.87 +    x1 = -10;
    4.88 +    y1 = 15;
    4.89 +    x2 = 40;
    4.90 +    y2 = 15;
    4.91 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
    4.92 +    SDL_ATvassert( clipped &&
    4.93 +                   x1 == 0 && y1 == 15 && x2 == 31 && y2 == 15,
    4.94 +        "horizontal line rect was incorrectly clipped: %d,%d - %d,%d",
    4.95 +        x1, y1, x2, y2);
    4.96 +
    4.97 +    x1 = -32;
    4.98 +    y1 = -32;
    4.99 +    x2 = 63;
   4.100 +    y2 = 63;
   4.101 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
   4.102 +    SDL_ATvassert( clipped &&
   4.103 +                   x1 == 0 && y1 == 0 && x2 == 31 && y2 == 31,
   4.104 +        "diagonal line to lower right was incorrectly clipped: %d,%d - %d,%d",
   4.105 +        x1, y1, x2, y2);
   4.106 +
   4.107 +    x1 = 63;
   4.108 +    y1 = 63;
   4.109 +    x2 = -32;
   4.110 +    y2 = -32;
   4.111 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
   4.112 +    SDL_ATvassert( clipped &&
   4.113 +                   x1 == 31 && y1 == 31 && x2 == 0 && y2 == 0,
   4.114 +        "diagonal line to upper left was incorrectly clipped: %d,%d - %d,%d",
   4.115 +        x1, y1, x2, y2);
   4.116 +
   4.117 +    x1 = 63;
   4.118 +    y1 = -32;
   4.119 +    x2 = -32;
   4.120 +    y2 = 63;
   4.121 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
   4.122 +    SDL_ATvassert( clipped &&
   4.123 +                   x1 == 31 && y1 == 0 && x2 == 0 && y2 == 31,
   4.124 +        "diagonal line to lower left was incorrectly clipped: %d,%d - %d,%d",
   4.125 +        x1, y1, x2, y2);
   4.126 +
   4.127 +    x1 = -32;
   4.128 +    y1 = 63;
   4.129 +    x2 = 63;
   4.130 +    y2 = -32;
   4.131 +    clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2);
   4.132 +    SDL_ATvassert( clipped &&
   4.133 +                   x1 == 0 && y1 == 31 && x2 == 31 && y2 == 0,
   4.134 +        "diagonal line to upper right was incorrectly clipped: %d,%d - %d,%d",
   4.135 +        x1, y1, x2, y2);
   4.136 +
   4.137 +    SDL_ATend();
   4.138 +}
   4.139 +
   4.140 +
   4.141 +/**
   4.142 + * @brief Rect test entrypoint.
   4.143 + */
   4.144 +#ifdef TEST_STANDALONE
   4.145 +int main( int argc, const char *argv[] )
   4.146 +{
   4.147 +   (void) argc;
   4.148 +   (void) argv;
   4.149 +#else /* TEST_STANDALONE */
   4.150 +int test_rect (void)
   4.151 +{
   4.152 +#endif /* TEST_STANDALONE */
   4.153 +
   4.154 +   SDL_ATinit( "Rect" );
   4.155 +
   4.156 +   rect_testIntersectRectAndLine();
   4.157 +
   4.158 +   return SDL_ATfinish();
   4.159 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/automated/rect/rect.h	Fri Dec 11 09:22:34 2009 +0000
     5.3 @@ -0,0 +1,18 @@
     5.4 +/**
     5.5 + * Part of SDL test suite.
     5.6 + *
     5.7 + * Written by Edgar Simo "bobbens"
     5.8 + *
     5.9 + * Released under Public Domain.
    5.10 + */
    5.11 +
    5.12 +
    5.13 +#ifndef _TEST_RECT
    5.14 +#  define _TEST_RECT
    5.15 +
    5.16 +
    5.17 +int test_rect (void);
    5.18 +
    5.19 +
    5.20 +#endif /* _TEST_RECT */
    5.21 +
     6.1 --- a/test/automated/testsdl.c	Fri Dec 11 09:13:51 2009 +0000
     6.2 +++ b/test/automated/testsdl.c	Fri Dec 11 09:22:34 2009 +0000
     6.3 @@ -12,6 +12,7 @@
     6.4  
     6.5  #include "platform/platform.h"
     6.6  #include "rwops/rwops.h"
     6.7 +#include "rect/rect.h"
     6.8  #include "surface/surface.h"
     6.9  #include "render/render.h"
    6.10  #include "audio/audio.h"
    6.11 @@ -41,6 +42,7 @@
    6.12  /* Automatic. */
    6.13  static int run_platform    = 1; /**< Run platform tests. */
    6.14  static int run_rwops       = 1; /**< Run RWops tests. */
    6.15 +static int run_rect        = 1; /**< Run rect tests. */
    6.16  static int run_surface     = 1; /**< Run surface tests. */
    6.17  static int run_render      = 1; /**< Run render tests. */
    6.18  static int run_audio       = 1; /**< Run audio tests. */
    6.19 @@ -55,206 +57,75 @@
    6.20  /**
    6.21   * @brief Displays program usage.
    6.22   */
    6.23 -#ifdef NO_GETOPT
    6.24 -static void print_usage( const char *name )
    6.25 -{
    6.26 -}
    6.27 -#else
    6.28 -#if !defined(NO_GETOPT_LONG)
    6.29  static void print_usage( const char *name )
    6.30  {
    6.31     printf("Usage: %s [OPTIONS]\n", name);
    6.32     printf("Options are:\n");
    6.33     printf("   -m, --manual        enables tests that require user interaction\n");
    6.34 -   printf("   -p, --noplatform    do not run the platform tests\n");
    6.35 -   printf("   -o, --norwops       do not run the rwops tests\n");
    6.36 -   printf("   -s, --nosurface     do not run the surface tests\n");
    6.37 -   printf("   -r, --norender      do not run the render tests\n");
    6.38 -   printf("   -a, --noaudio       do not run the audio tests\n");
    6.39 +   printf("   --noplatform        do not run the platform tests\n");
    6.40 +   printf("   --norwops           do not run the rwops tests\n");
    6.41 +   printf("   --norect            do not run the rect tests\n");
    6.42 +   printf("   --nosurface         do not run the surface tests\n");
    6.43 +   printf("   --norender          do not run the render tests\n");
    6.44 +   printf("   --noaudio           do not run the audio tests\n");
    6.45     printf("   -v, --verbose       increases verbosity level by 1 for each -v\n");
    6.46     printf("   -q, --quiet         only displays errors\n");
    6.47     printf("   -h, --help          display this message and exit\n");
    6.48  }
    6.49 -#endif /* !NO_GETOPT_LONG */
    6.50 -
    6.51 -#if defined(NO_GETOPT_LONG)
    6.52 -static void print_usage( const char *name )
    6.53 -{
    6.54 -   printf("Usage: %s [OPTIONS]\n", name);
    6.55 -   printf("Options are:\n");
    6.56 -   printf("   -m,     enables tests that require user interaction\n");
    6.57 -   printf("   -p,     do not run the platform tests\n");
    6.58 -   printf("   -o,     do not run the rwops tests\n");
    6.59 -   printf("   -s,     do not run the surface tests\n");
    6.60 -   printf("   -r,     do not run the render tests\n");
    6.61 -   printf("   -a,     do not run the audio tests\n");
    6.62 -   printf("   -v,     increases verbosity level by 1 for each -v\n");
    6.63 -   printf("   -q,     only displays errors\n");
    6.64 -   printf("   -h,     display this message and exit\n");
    6.65 -}
    6.66 -#endif /* NO_GETOPT_LONG */
    6.67 -#endif /* NO_GETOPT */
    6.68  
    6.69  /**
    6.70   * @brief Handles the options.
    6.71   */
    6.72 -#ifdef NO_GETOPT
    6.73  static void parse_options( int argc, char *argv[] )
    6.74  {
    6.75 -}
    6.76 -#else
    6.77 -#if !defined(NO_GETOPT_LONG)
    6.78 -static void parse_options( int argc, char *argv[] )
    6.79 -{
    6.80 -   static struct option long_options[] = {
    6.81 -      { "manual", no_argument, 0, 'm' },
    6.82 -      { "noplatform", no_argument, 0, 'p' },
    6.83 -      { "norwops", no_argument, 0, 'o' },
    6.84 -      { "nosurface", no_argument, 0, 's' },
    6.85 -      { "norender", no_argument, 0, 'r' },
    6.86 -      { "noaudio", no_argument, 0, 'a' },
    6.87 -      { "verbose", no_argument, 0, 'v' },
    6.88 -      { "quiet", no_argument, 0, 'q' },
    6.89 -      { "help", no_argument, 0, 'h' },
    6.90 -      {NULL,0,0,0}
    6.91 -   };
    6.92 -   int option_index = 0;
    6.93 -   int c = 0;
    6.94     int i;
    6.95 -   const char *str;
    6.96  
    6.97 -   /* Iterate over options. */
    6.98 -   while ((c = getopt_long( argc, argv,
    6.99 -               "mposravqh",
   6.100 -               long_options, &option_index)) != -1) {
   6.101 +   for (i = 1; i < argc; ++i) {
   6.102 +      const char *arg = argv[i];
   6.103 +      if (SDL_strcmp(arg, "-m") == 0 || SDL_strcmp(arg, "--manual") == 0) {
   6.104 +         run_manual = 1;
   6.105 +         continue;
   6.106 +      }
   6.107 +      if (SDL_strcmp(arg, "-v") == 0 || SDL_strcmp(arg, "--verbose") == 0) {
   6.108 +         int level;
   6.109 +         SDL_ATgeti( SDL_AT_VERBOSE, &level );
   6.110 +         SDL_ATseti( SDL_AT_VERBOSE, level+1 );
   6.111 +         continue;
   6.112 +      }
   6.113 +      if (SDL_strcmp(arg, "-q") == 0 || SDL_strcmp(arg, "--quiet") == 0) {
   6.114 +         SDL_ATseti( SDL_AT_QUIET, 1 );
   6.115 +         continue;
   6.116 +      }
   6.117 +      if (SDL_strcmp(arg, "--noplatform") == 0) {
   6.118 +         run_platform = 0;
   6.119 +         continue;
   6.120 +      }
   6.121 +      if (SDL_strcmp(arg, "--norwops") == 0) {
   6.122 +         run_rwops = 0;
   6.123 +         continue;
   6.124 +      }
   6.125 +      if (SDL_strcmp(arg, "--norect") == 0) {
   6.126 +         run_rect = 0;
   6.127 +         continue;
   6.128 +      }
   6.129 +      if (SDL_strcmp(arg, "--nosurface") == 0) {
   6.130 +         run_surface = 0;
   6.131 +         continue;
   6.132 +      }
   6.133 +      if (SDL_strcmp(arg, "--norender") == 0) {
   6.134 +         run_render = 0;
   6.135 +         continue;
   6.136 +      }
   6.137 +      if (SDL_strcmp(arg, "--noaudio") == 0) {
   6.138 +         run_audio = 0;
   6.139 +         continue;
   6.140 +      }
   6.141  
   6.142 -      /* Handle options. */
   6.143 -      switch (c) {
   6.144 -         case 0:
   6.145 -            str = long_options[option_index].name;
   6.146 -            if (strcmp(str,"noplatform")==0)
   6.147 -               run_platform = 0;
   6.148 -            else if (strcmp(str,"norwops")==0)
   6.149 -               run_rwops = 0;
   6.150 -            else if (strcmp(str,"nosurface")==0)
   6.151 -               run_surface = 0;
   6.152 -            else if (strcmp(str,"norender")==0)
   6.153 -               run_render = 0;
   6.154 -            else if (strcmp(str,"noaudio")==0)
   6.155 -               run_audio = 0;
   6.156 -            break;
   6.157 -
   6.158 -         /* Manual. */
   6.159 -         case 'm':
   6.160 -            run_manual = 1;
   6.161 -            break;
   6.162 -
   6.163 -         /* No platform. */
   6.164 -         case 'p':
   6.165 -            run_platform = 0;
   6.166 -            break;
   6.167 -
   6.168 -         /* No rwops. */
   6.169 -         case 'o':
   6.170 -            run_rwops = 0;
   6.171 -            break;
   6.172 -
   6.173 -         /* No surface. */
   6.174 -         case 's':
   6.175 -            run_surface = 0;
   6.176 -            break;
   6.177 -
   6.178 -         /* No render. */
   6.179 -         case 'r':
   6.180 -            run_render = 0;
   6.181 -            break;
   6.182 -
   6.183 -         /* No audio. */
   6.184 -         case 'a':
   6.185 -            run_audio = 0;
   6.186 -            break;
   6.187 -
   6.188 -         /* Verbosity. */
   6.189 -         case 'v':
   6.190 -            SDL_ATgeti( SDL_AT_VERBOSE, &i );
   6.191 -            SDL_ATseti( SDL_AT_VERBOSE, i+1 );
   6.192 -            break;
   6.193 -
   6.194 -         /* Quiet. */
   6.195 -         case 'q':
   6.196 -            SDL_ATseti( SDL_AT_QUIET, 1 );
   6.197 -            break;
   6.198 -
   6.199 -         /* Help. */
   6.200 -         case 'h':
   6.201 -            print_usage( argv[0] );
   6.202 -            exit(EXIT_SUCCESS);
   6.203 -      }
   6.204 +      /* Print help and exit! */
   6.205 +      print_usage( argv[0] );
   6.206 +      exit(EXIT_FAILURE);
   6.207     }
   6.208  }
   6.209 -#endif /* !NO_GETOPT_LONG */
   6.210 -
   6.211 -#if defined(NO_GETOPT_LONG)
   6.212 -static void parse_options( int argc, char *argv[] )
   6.213 -{
   6.214 -   static char* short_options="mposravqh";
   6.215 -   int c = 0;
   6.216 -   int i;
   6.217 -
   6.218 -   /* Iterate over options. */
   6.219 -   while ((c = getopt(argc, argv, short_options)) != -1) {
   6.220 -      /* Handle options. */
   6.221 -      switch (c) {
   6.222 -         /* Manual. */
   6.223 -         case 'm':
   6.224 -            run_manual = 1;
   6.225 -            break;
   6.226 -
   6.227 -         /* No platform. */
   6.228 -         case 'p':
   6.229 -            run_platform = 0;
   6.230 -            break;
   6.231 -
   6.232 -         /* No rwops. */
   6.233 -         case 'o':
   6.234 -            run_rwops = 0;
   6.235 -            break;
   6.236 -
   6.237 -         /* No surface. */
   6.238 -         case 's':
   6.239 -            run_surface = 0;
   6.240 -            break;
   6.241 -
   6.242 -         /* No render. */
   6.243 -         case 'r':
   6.244 -            run_render = 0;
   6.245 -            break;
   6.246 -
   6.247 -         /* No audio. */
   6.248 -         case 'a':
   6.249 -            run_audio = 0;
   6.250 -            break;
   6.251 -
   6.252 -         /* Verbosity. */
   6.253 -         case 'v':
   6.254 -            SDL_ATgeti( SDL_AT_VERBOSE, &i );
   6.255 -            SDL_ATseti( SDL_AT_VERBOSE, i+1 );
   6.256 -            break;
   6.257 -
   6.258 -         /* Quiet. */
   6.259 -         case 'q':
   6.260 -            SDL_ATseti( SDL_AT_QUIET, 1 );
   6.261 -            break;
   6.262 -
   6.263 -         /* Help. */
   6.264 -         case 'h':
   6.265 -            print_usage( argv[0] );
   6.266 -            exit(EXIT_SUCCESS);
   6.267 -      }
   6.268 -   }
   6.269 -}
   6.270 -#endif /* NO_GETOPT_LONG */
   6.271 -#endif /* NO_GETOPT */
   6.272  
   6.273  /**
   6.274   * @brief Main entry point.
   6.275 @@ -282,6 +153,8 @@
   6.276        failed += test_platform();
   6.277     if (run_rwops)
   6.278        failed += test_rwops();
   6.279 +   if (run_rect)
   6.280 +      failed += test_rect();
   6.281     if (run_surface)
   6.282        failed += test_surface();
   6.283     if (run_render)