test/automated/surface/surface.c
author Edgar Simo <bobbens@gmail.com>
Tue, 07 Jul 2009 11:25:56 +0000
branchgsoc2009_unit_tests
changeset 3718 9d71382713b5
parent 3716 ac6bc19a2dfb
child 3719 15373e31daff
permissions -rw-r--r--
Added 3 new tests: loadsurface, blitting, alpha blitting.
Alpha Blitting is not complete as it seems like SDL doesn't work well with alpha blitting yet.
     1 /**
     2  * Automated SDL_Surface test.
     3  *
     4  * Written by Edgar Simo "bobbens"
     5  *
     6  * Released under Public Domain.
     7  */
     8 
     9 
    10 #include "SDL.h"
    11 #include "SDL_at.h"
    12 
    13 
    14 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
    15 #  define RMASK   0xff000000 /**< Red bit mask. */
    16 #  define GMASK   0x00ff0000 /**< Green bit mask. */
    17 #  define BMASK   0x0000ff00 /**< Blue bit mask. */
    18 #  define AMASK   0x000000ff /**< Alpha bit mask. */
    19 #else
    20 #  define RMASK   0x000000ff /**< Red bit mask. */
    21 #  define GMASK   0x0000ff00 /**< Green bit mask. */
    22 #  define BMASK   0x00ff0000 /**< Blue bit mask. */
    23 #  define AMASK   0xff000000 /**< Alpha bit mask. */
    24 #endif
    25 
    26 
    27 typedef struct SurfaceImage_s {
    28    unsigned int  width;
    29    unsigned int  height;
    30    unsigned int  bytes_per_pixel; /* 3:RGB, 4:RGBA */ 
    31    const unsigned char pixel_data[];
    32 } SurfaceImage_t;
    33 
    34 
    35 /*
    36  * Pull in images for testcases.
    37  */
    38 #include "primitives.c"
    39 #include "blend.c"
    40 #include "face.c"
    41 #include "blit.c"
    42 
    43 
    44 /**
    45  * @brief Compares a surface and a surface image for equality.
    46  *
    47  *    @param sur Surface to compare.
    48  *    @param img Image to compare against.
    49  *    @return 0 if they are the same, -1 on error and positive if different.
    50  */
    51 static int surface_compare( SDL_Surface *sur, const SurfaceImage_t *img )
    52 {
    53    int ret;
    54    int i,j;
    55    Uint32 pix;
    56    int bpp;
    57    Uint8 *p, *pd;
    58 
    59    /* Make sure size is the same. */
    60    if ((sur->w != img->width) || (sur->h != img->height))
    61       return -1;
    62 
    63    SDL_LockSurface( sur );
    64 
    65    ret = 0;
    66    bpp = sur->format->BytesPerPixel;
    67 
    68    /* Compare image - should be same format. */
    69    for (j=0; j<sur->h; j++) {
    70       for (i=0; i<sur->w; i++) {
    71          p  = (Uint8 *)sur->pixels + j * sur->pitch + i * bpp;
    72          pd = (Uint8 *)img->pixel_data + (j*img->width + i) * img->bytes_per_pixel;
    73          switch (bpp) {
    74             case 1:
    75                /* Paletted not supported atm. */
    76                ret += 1;
    77                break;
    78 
    79             case 2:
    80                /* 16 BPP not supported atm. */
    81                ret += 1;
    82                break;
    83 
    84             case 3:
    85                /* 24 BPP not supported atm. */
    86                ret += 1;
    87                break;
    88 
    89             case 4:
    90                ret += !( (p[0] == pd[0]) &&
    91                          (p[1] == pd[1]) &&
    92                          (p[2] == pd[2]) );
    93                break;
    94          }
    95       }
    96    }
    97   
    98    SDL_UnlockSurface( sur );
    99 
   100    return ret;
   101 }
   102 
   103 
   104 /**
   105  * @brief Tests sprite loading.
   106  */
   107 static void surface_testLoad (void)
   108 {
   109    int ret;
   110    SDL_Surface *face, *rface, *testsur;
   111 
   112    SDL_ATbegin( "Load Test" );
   113 
   114    /* Create the blit surface. */
   115    face = SDL_LoadBMP("../icon.bmp");
   116    if (SDL_ATassert( "SDL_CreateLoadBmp", face != NULL))
   117       return;
   118 
   119    /* Set transparent pixel as the pixel at (0,0) */
   120    if (face->format->palette) {
   121       ret = SDL_SetColorKey(face, (SDL_SRCCOLORKEY | SDL_RLEACCEL),
   122             *(Uint8 *) face->pixels);
   123       if (SDL_ATassert( "SDL_SetColorKey", ret == 0))
   124          return;
   125    }
   126 
   127    /* Create the test surface. */
   128    testsur = SDL_CreateRGBSurface( 0, 80, 60, 32, 
   129          RMASK, GMASK, BMASK, AMASK );
   130    if (SDL_ATassert( "SDL_CreateRGBSurface", testsur != NULL))
   131       return;
   132 
   133    /* Convert to 32 bit to compare. */
   134    rface = SDL_ConvertSurface( face, testsur->format, 0 );
   135    if (SDL_ATassert( "SDL_ConvertSurface", rface != NULL))
   136       return;
   137 
   138    /* See if it's the same. */
   139    if (SDL_ATassert( "Primitives output not the same.",
   140             surface_compare( rface, &img_face)==0 ))
   141       return;
   142 
   143    /* Clean up. */
   144    SDL_FreeSurface( testsur );
   145    SDL_FreeSurface( rface );
   146    SDL_FreeSurface( face );
   147 
   148    SDL_ATend();
   149 }
   150 
   151 
   152 /**
   153  * @brief Tests the SDL primitives for rendering.
   154  */
   155 static void surface_testPrimitives (void)
   156 {
   157    int ret;
   158    int x, y;
   159    SDL_Rect rect;
   160    SDL_Surface *testsur;
   161 
   162    SDL_ATbegin( "Primitives Test" );
   163 
   164    /* Create the surface. */
   165    testsur = SDL_CreateRGBSurface( 0, 80, 60, 32, 
   166          RMASK, GMASK, BMASK, AMASK );
   167    if (SDL_ATassert( "SDL_CreateRGBSurface", testsur != NULL))
   168       return;
   169 
   170    /* Draw a rectangle. */
   171    rect.x = 40;
   172    rect.y = 0;
   173    rect.w = 40;
   174    rect.h = 80;
   175    ret = SDL_FillRect( testsur, &rect,
   176          SDL_MapRGB( testsur->format, 13, 73, 200 ) );
   177    if (SDL_ATassert( "SDL_FillRect", ret == 0))
   178       return;
   179 
   180    /* Draw a rectangle. */
   181    rect.x = 10;
   182    rect.y = 10;
   183    rect.w = 60;
   184    rect.h = 40;
   185    ret = SDL_FillRect( testsur, &rect,
   186          SDL_MapRGB( testsur->format, 200, 0, 100 ) );
   187    if (SDL_ATassert( "SDL_FillRect", ret == 0))
   188       return;
   189 
   190    /* Draw some points like so:
   191     * X.X.X.X..
   192     * .X.X.X.X.
   193     * X.X.X.X.. */
   194    for (y=0; y<3; y++) {
   195       x = y % 2;
   196       for (; x<80; x+=2)
   197          ret = SDL_DrawPoint( testsur, x, y,
   198                SDL_MapRGB( testsur->format, x*y, x*y/2, x*y/3 ) );
   199       if (SDL_ATassert( "SDL_DrawPoint", ret == 0))
   200          return;
   201    }
   202 
   203    /* Draw some lines. */
   204    ret = SDL_DrawLine( testsur, 0, 30, 80, 30,
   205          SDL_MapRGB( testsur->format, 0, 255, 0 ) );
   206    if (SDL_ATassert( "SDL_DrawLine", ret == 0))
   207       return;
   208    ret = SDL_DrawLine( testsur, 40, 30, 40, 60,
   209          SDL_MapRGB( testsur->format, 55, 55, 5 ) );
   210    if (SDL_ATassert( "SDL_DrawLine", ret == 0))
   211       return;
   212    ret = SDL_DrawLine( testsur, 0, 60, 80, 0,
   213          SDL_MapRGB( testsur->format, 5, 105, 105 ) );
   214    if (SDL_ATassert( "SDL_DrawLine", ret == 0))
   215       return;
   216 
   217    /* See if it's the same. */
   218    if (SDL_ATassert( "Primitives output not the same.",
   219             surface_compare( testsur, &img_primitives )==0 ))
   220       return;
   221 
   222    /* Clean up. */
   223    SDL_FreeSurface( testsur );
   224 
   225    SDL_ATend();
   226 }
   227 
   228 
   229 /**
   230  * @brief Tests the SDL primitives with alpha for rendering.
   231  */
   232 static void surface_testPrimitivesAlpha (void)
   233 {
   234    int ret;
   235    int i, j;
   236    SDL_Rect rect;
   237    SDL_Surface *testsur;
   238 
   239    SDL_ATbegin( "Primitives Alpha Test" );
   240 
   241    /* Create the surface. */
   242    testsur = SDL_CreateRGBSurface( 0, 80, 60, 32, 
   243          RMASK, GMASK, BMASK, AMASK );
   244    if (SDL_ATassert( "SDL_CreateRGBSurface", testsur != NULL))
   245       return;
   246 
   247    /* Create some rectangles for each blend mode. */
   248    ret = SDL_BlendRect( testsur, NULL, SDL_BLENDMODE_NONE, 255, 255, 255, 0 );
   249    if (SDL_ATassert( "SDL_BlendRect", ret == 0))
   250       return;
   251    rect.x = 10;
   252    rect.y = 25;
   253    rect.w = 40;
   254    rect.h = 25;
   255    ret = SDL_BlendRect( testsur, &rect, SDL_BLENDMODE_ADD, 240, 10, 10, 75 );
   256    if (SDL_ATassert( "SDL_BlendRect", ret == 0))
   257       return;
   258    rect.x = 30;
   259    rect.y = 40;
   260    rect.w = 45;
   261    rect.h = 15;
   262    ret = SDL_BlendRect( testsur, &rect, SDL_BLENDMODE_BLEND, 10, 240, 10, 100 );
   263    if (SDL_ATassert( "SDL_BlendRect", ret == 0))
   264       return;
   265    rect.x = 25;
   266    rect.y = 25;
   267    rect.w = 25;
   268    rect.h = 25;
   269    ret = SDL_BlendRect( testsur, &rect, SDL_BLENDMODE_MOD, 10, 10, 240, 125 );
   270    if (SDL_ATassert( "SDL_BlendRect", ret == 0))
   271       return;
   272 
   273    /* Draw blended lines, lines for everyone. */
   274    for (i=0; i<testsur->w; i+=2)  {
   275       ret = SDL_BlendLine( testsur, 0, 0, i, 59,
   276             (((i/2)%3)==0) ? SDL_BLENDMODE_BLEND :
   277                (((i/2)%3)==1) ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_MOD,
   278             60+2*j, 240-2*j, 50, 3*j );
   279       if (SDL_ATassert( "SDL_BlendLine", ret == 0))
   280          return;
   281    }
   282    for (i=0; i<testsur->h; i+=2)  {
   283       ret = SDL_BlendLine( testsur, 0, 0, 79, i,
   284             (((i/2)%3)==0) ? SDL_BLENDMODE_BLEND :
   285                (((i/2)%3)==1) ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_MOD,
   286             60+2*j, 240-2*j, 50, 3*j );
   287       if (SDL_ATassert( "SDL_BlendLine", ret == 0))
   288          return;
   289    }
   290 
   291    /* Draw points. */
   292    for (j=0; j<testsur->h; j+=3) {
   293       for (i=0; i<testsur->w; i+=3) {
   294       ret = SDL_BlendPoint( testsur, i, j,
   295             ((((i+j)/3)%3)==0) ? SDL_BLENDMODE_BLEND :
   296                ((((i+j)/3)%3)==1) ? SDL_BLENDMODE_ADD : SDL_BLENDMODE_MOD,
   297             j*4, i*3, j*4, i*3 );
   298       if (SDL_ATassert( "SDL_BlendPoint", ret == 0))
   299          return;
   300       }
   301    }
   302 
   303    /* See if it's the same. */
   304    if (SDL_ATassert( "Primitives output not the same.",
   305             surface_compare( testsur, &img_blend )==0 ))
   306       return;
   307 
   308    /* Clean up. */
   309    SDL_FreeSurface( testsur );
   310 
   311    SDL_ATend();
   312 }
   313 
   314 
   315 /**
   316  * @brief Tests some blitting routines.
   317  */
   318 static void surface_testBlit (void)
   319 {
   320    int ret;
   321    SDL_Rect rect;
   322    SDL_Surface *face, *testsur;
   323    int i, j, ni, nj;
   324    int mode;
   325 
   326    SDL_ATbegin( "Blit Test" );
   327 
   328    /* Create the blit surface. */
   329    face = SDL_LoadBMP("../icon.bmp");
   330    if (SDL_ATassert( "SDL_CreateLoadBmp", face != NULL))
   331       return;
   332 
   333    /* Set transparent pixel as the pixel at (0,0) */
   334    if (face->format->palette)
   335       SDL_SetColorKey(face, (SDL_SRCCOLORKEY | SDL_RLEACCEL),
   336             *(Uint8 *) face->pixels);
   337    /*
   338    face = SDL_CreateRGBSurfaceFrom( (void*)img_face.pixel_data,
   339          img_face.width, img_face.height, 32, img_face.width*4,
   340          RMASK, GMASK, BMASK, AMASK );
   341    if (SDL_ATassert( "SDL_CreateRGBSurfaceFrom", face != NULL))
   342       return;
   343    */
   344 
   345    /* Create the test surface. */
   346    testsur = SDL_CreateRGBSurface( 0, 80, 60, 32, 
   347          RMASK, GMASK, BMASK, AMASK );
   348    if (SDL_ATassert( "SDL_CreateRGBSurface", testsur != NULL))
   349       return;
   350 
   351    /* Steps to take. */
   352    ni = 40;
   353    nj = 30;
   354 
   355    /* Constant values. */
   356    rect.w = face->w;
   357    rect.h = face->h;
   358 
   359    /* Loop blit. */
   360    for (j=0; j <= testsur->h - face->h; j+=4) {
   361       for (i=0; i <= testsur->w - face->w; i+=4) {
   362          /* Blitting. */
   363          rect.x = i;
   364          rect.y = j;
   365          ret = SDL_BlitSurface( face, NULL, testsur, &rect );
   366          if (SDL_ATassert( "SDL_BlitSurface", ret == 0))
   367             return;
   368       }
   369    }
   370 
   371    /* See if it's the same. */
   372    if (SDL_ATassert( "Blitting output not the same.",
   373             surface_compare( testsur, &img_blit )==0 ))
   374       return;
   375 
   376    /* Clean up. */
   377    SDL_FreeSurface( face );
   378    SDL_FreeSurface( testsur );
   379 
   380    SDL_ATend();
   381 }
   382 
   383 
   384 /**
   385  * @brief Tests some more blitting routines.
   386  */
   387 static void surface_testBlitAlpha (void)
   388 {
   389    int ret;
   390    SDL_Rect rect;
   391    SDL_Surface *face, *testsur;
   392    int i, j, ni, nj;
   393    int mode;
   394 
   395    SDL_ATbegin( "Blit Alpha Test" );
   396 
   397    /* Create the blit surface. */
   398    face = SDL_CreateRGBSurfaceFrom( (void*)img_face.pixel_data,
   399          img_face.width, img_face.height, 32, img_face.width*4,
   400          RMASK, GMASK, BMASK, AMASK );
   401    if (SDL_ATassert( "SDL_CreateRGBSurfaceFrom", face != NULL))
   402       return;
   403 
   404    /* Create the test surface. */
   405    testsur = SDL_CreateRGBSurface( 0, 80, 60, 32, 
   406          RMASK, GMASK, BMASK, AMASK );
   407    if (SDL_ATassert( "SDL_CreateRGBSurface", testsur != NULL))
   408       return;
   409 
   410    /* Steps to take. */
   411    ni = 40;
   412    nj = 30;
   413 
   414    /* Constant values. */
   415    rect.w = face->w;
   416    rect.h = face->h;
   417 
   418    /* Loop blit. */
   419    for (j=0; j <= testsur->h - face->h; j+=4) {
   420       for (i=0; i <= testsur->w - face->w; i+=4) {
   421 
   422          /* Set colour mod. */
   423          ret = SDL_SetSurfaceColorMod( face, (255/nj)*j, (255/ni)*i, (255/nj)*j );
   424          if (SDL_ATassert( "SDL_SetSurfaceColorMod", ret == 0))
   425             return;
   426 
   427          /* Set alpha mod. */
   428          ret = SDL_SetSurfaceAlphaMod( face, (255/ni)*i );
   429          if (SDL_ATassert( "SDL_SetSurfaceAlphaMod", ret == 0))
   430             return;
   431 
   432          /* Crazy blending mode magic. */
   433          mode = (i*j)%5;
   434          if      (mode==0) mode = SDL_BLENDMODE_NONE;
   435          else if (mode==1) mode = SDL_BLENDMODE_MASK;
   436          else if (mode==2) mode = SDL_BLENDMODE_BLEND;
   437          else if (mode==3) mode = SDL_BLENDMODE_ADD;
   438          else if (mode==4) mode = SDL_BLENDMODE_MOD;
   439          ret = SDL_SetSurfaceBlendMode( face, mode );
   440          if (SDL_ATassert( "SDL_SetSurfaceBlendMode", ret == 0))
   441             return;
   442 
   443          /* Blitting. */
   444          rect.x = i;
   445          rect.y = j;
   446          ret = SDL_BlitSurface( face, NULL, testsur, &rect );
   447          if (SDL_ATassert( "SDL_BlitSurface", ret == 0))
   448             return;
   449       }
   450    }
   451 
   452    SDL_SaveBMP( testsur, "blit.bmp" );
   453 
   454    /* Clean up. */
   455    SDL_FreeSurface( face );
   456    SDL_FreeSurface( testsur );
   457 
   458    SDL_ATend();
   459 }
   460 
   461 
   462 /**
   463  * @brief Entry point.
   464  */
   465 int main( int argc, const char *argv[] )
   466 {
   467    SDL_ATinit( "SDL_Surface" );
   468 
   469    /* Initializes the SDL subsystems. */
   470    SDL_Init(0);
   471 
   472    surface_testLoad();
   473    surface_testPrimitives();
   474    surface_testPrimitivesAlpha();
   475    surface_testBlit();
   476    /*surface_testBlitAlpha();*/
   477 
   478    /* Exit SDL. */
   479    SDL_Quit();
   480 
   481    return SDL_ATfinish(1);
   482 }