Added a multi-window version of testsprite using the new API. SDL-1.3
authorSam Lantinga <slouken@libsdl.org>
Sat, 24 Jun 2006 16:51:01 +0000
branchSDL-1.3
changeset 17061577404809f0
parent 1705 fc731a7d83ed
child 1707 57ce47f033a5
Added a multi-window version of testsprite using the new API.
include/SDL_video.h
src/video/SDL_bmp.c
src/video/SDL_pixels.c
src/video/SDL_renderer_sw.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/dummy/SDL_nullrender.c
test/Makefile.in
test/testsprite2.c
     1.1 --- a/include/SDL_video.h	Sat Jun 24 04:31:42 2006 +0000
     1.2 +++ b/include/SDL_video.h	Sat Jun 24 16:51:01 2006 +0000
     1.3 @@ -763,7 +763,7 @@
     1.4  /**
     1.5   * \fn SDL_TextureID SDL_CreateTexture(Uint32 format, int access, int w, int h)
     1.6   *
     1.7 - * \brief Create a texture
     1.8 + * \brief Create a texture for the current rendering context.
     1.9   *
    1.10   * \param format The format of the texture
    1.11   * \param access One of the enumerated values in SDL_TextureAccess
     2.1 --- a/src/video/SDL_bmp.c	Sat Jun 24 04:31:42 2006 +0000
     2.2 +++ b/src/video/SDL_bmp.c	Sat Jun 24 16:51:01 2006 +0000
     2.3 @@ -232,7 +232,6 @@
     2.4                  SDL_RWread(src, &palette->colors[i].unused, 1, 1);
     2.5              }
     2.6          }
     2.7 -        palette->ncolors = biClrUsed;
     2.8      }
     2.9  
    2.10      /* Read the surface pixels.  Note that the bmp image is upside down */
     3.1 --- a/src/video/SDL_pixels.c	Sat Jun 24 04:31:42 2006 +0000
     3.2 +++ b/src/video/SDL_pixels.c	Sat Jun 24 16:51:01 2006 +0000
     3.3 @@ -642,8 +642,11 @@
     3.4      if (identical) {
     3.5          if (src->ncolors <= dst->ncolors) {
     3.6              /* If an identical palette, no need to map */
     3.7 -            if (SDL_memcmp(src->colors, dst->colors, src->ncolors *
     3.8 -                           sizeof(SDL_Color)) == 0) {
     3.9 +            if (src == dst
    3.10 +                ||
    3.11 +                (SDL_memcmp
    3.12 +                 (src->colors, dst->colors,
    3.13 +                  src->ncolors * sizeof(SDL_Color)) == 0)) {
    3.14                  *identical = 1;
    3.15                  return (NULL);
    3.16              }
     4.1 --- a/src/video/SDL_renderer_sw.c	Sat Jun 24 04:31:42 2006 +0000
     4.2 +++ b/src/video/SDL_renderer_sw.c	Sat Jun 24 16:51:01 2006 +0000
     4.3 @@ -111,7 +111,8 @@
     4.4  SDL_Renderer *
     4.5  SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags)
     4.6  {
     4.7 -    SDL_DisplayMode *displayMode = &window->display->current_mode;
     4.8 +    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
     4.9 +    SDL_DisplayMode *displayMode = &display->current_mode;
    4.10      SDL_Renderer *renderer;
    4.11      SDL_SW_RenderData *data;
    4.12      int i, n;
    4.13 @@ -156,7 +157,7 @@
    4.14      renderer->DestroyTexture = SDL_SW_DestroyTexture;
    4.15      renderer->DestroyRenderer = SDL_SW_DestroyRenderer;
    4.16      renderer->info = SDL_SW_RenderDriver.info;
    4.17 -    renderer->window = window;
    4.18 +    renderer->window = window->id;
    4.19      renderer->driverdata = data;
    4.20  
    4.21      renderer->info.flags = SDL_Renderer_RenderTarget;
    4.22 @@ -179,14 +180,14 @@
    4.23              SDL_SW_DestroyRenderer(renderer);
    4.24              return NULL;
    4.25          }
    4.26 -        SDL_SetSurfacePalette(data->screens[i], window->display->palette);
    4.27 +        SDL_SetSurfacePalette(data->screens[i], display->palette);
    4.28      }
    4.29      data->current_screen = 0;
    4.30      data->target = data->screens[0];
    4.31  
    4.32      /* Find a render driver that we can use to display data */
    4.33 -    for (i = 0; i < window->display->num_render_drivers; ++i) {
    4.34 -        SDL_RenderDriver *driver = &window->display->render_drivers[i];
    4.35 +    for (i = 0; i < display->num_render_drivers; ++i) {
    4.36 +        SDL_RenderDriver *driver = &display->render_drivers[i];
    4.37          if (driver->info.name != SDL_SW_RenderDriver.info.name) {
    4.38              data->renderer =
    4.39                  driver->CreateRenderer(window, SDL_Renderer_PresentDiscard);
    4.40 @@ -195,7 +196,7 @@
    4.41              }
    4.42          }
    4.43      }
    4.44 -    if (i == window->display->num_render_drivers) {
    4.45 +    if (i == display->num_render_drivers) {
    4.46          SDL_SW_DestroyRenderer(renderer);
    4.47          SDL_SetError("Couldn't find display render driver");
    4.48          return NULL;
    4.49 @@ -377,6 +378,8 @@
    4.50                    int blendMode, int scaleMode)
    4.51  {
    4.52      SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata;
    4.53 +    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
    4.54 +    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
    4.55  
    4.56      if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
    4.57          SDL_Surface *target = data->target;
    4.58 @@ -384,9 +387,8 @@
    4.59              (Uint8 *) target->pixels + dstrect->y * target->pitch +
    4.60              dstrect->x * target->format->BytesPerPixel;
    4.61          return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
    4.62 -                                   srcrect,
    4.63 -                                   renderer->window->display->current_mode.
    4.64 -                                   format, dstrect->w, dstrect->h, pixels,
    4.65 +                                   srcrect, display->current_mode.format,
    4.66 +                                   dstrect->w, dstrect->h, pixels,
    4.67                                     target->pitch);
    4.68      } else {
    4.69          SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
     5.1 --- a/src/video/SDL_sysvideo.h	Sat Jun 24 04:31:42 2006 +0000
     5.2 +++ b/src/video/SDL_sysvideo.h	Sat Jun 24 16:51:01 2006 +0000
     5.3 @@ -104,7 +104,7 @@
     5.4      SDL_RendererInfo info;
     5.5  
     5.6      /* The window associated with the renderer */
     5.7 -    SDL_Window *window;
     5.8 +    SDL_WindowID window;
     5.9  
    5.10      void *driverdata;
    5.11  };
    5.12 @@ -130,7 +130,7 @@
    5.13  
    5.14      Uint16 *gamma;
    5.15  
    5.16 -    SDL_VideoDisplay *display;
    5.17 +    int display;
    5.18      SDL_Renderer *renderer;
    5.19  
    5.20      void *userdata;
    5.21 @@ -445,6 +445,9 @@
    5.22  extern void SDL_AddRenderDriver(int displayIndex,
    5.23                                  const SDL_RenderDriver * driver);
    5.24  
    5.25 +extern SDL_Window *SDL_GetWindowFromID(SDL_WindowID windowID);
    5.26 +extern SDL_VideoDisplay *SDL_GetDisplayFromWindow(SDL_Window * window);
    5.27 +
    5.28  #endif /* _SDL_sysvideo_h */
    5.29  
    5.30  /* vi: set ts=4 sw=4 expandtab: */
     6.1 --- a/src/video/SDL_video.c	Sat Jun 24 04:31:42 2006 +0000
     6.2 +++ b/src/video/SDL_video.c	Sat Jun 24 16:51:01 2006 +0000
     6.3 @@ -507,6 +507,16 @@
     6.4          } else {
     6.5              closest->refresh_rate = mode->refresh_rate;
     6.6          }
     6.7 +        /* Pick some reasonable defaults if the app and driver don't care */
     6.8 +        if (!closest->format) {
     6.9 +            closest->format = SDL_PixelFormat_RGB888;
    6.10 +        }
    6.11 +        if (!closest->w) {
    6.12 +            closest->w = 640;
    6.13 +        }
    6.14 +        if (!closest->h) {
    6.15 +            closest->h = 480;
    6.16 +        }
    6.17          return closest;
    6.18      }
    6.19      return NULL;
    6.20 @@ -577,6 +587,8 @@
    6.21              if (!display->palette) {
    6.22                  return -1;
    6.23              }
    6.24 +            SDL_DitherColors(display->palette->colors,
    6.25 +                             SDL_BITSPERPIXEL(display_mode.format));
    6.26          }
    6.27      }
    6.28  
    6.29 @@ -664,7 +676,7 @@
    6.30      window.w = w;
    6.31      window.h = h;
    6.32      window.flags = (flags & allowed_flags);
    6.33 -    window.display = &SDL_CurrentDisplay;
    6.34 +    window.display = _this->current_display;
    6.35  
    6.36      if (_this->CreateWindow && _this->CreateWindow(_this, &window) < 0) {
    6.37          if (window.title) {
    6.38 @@ -707,7 +719,7 @@
    6.39  
    6.40      SDL_zero(window);
    6.41      window.id = _this->next_object_id++;
    6.42 -    window.display = &SDL_CurrentDisplay;
    6.43 +    window.display = _this->current_display;
    6.44  
    6.45      if (!_this->CreateWindowFrom ||
    6.46          _this->CreateWindowFrom(_this, &window, data) < 0) {
    6.47 @@ -734,7 +746,7 @@
    6.48      return window.id;
    6.49  }
    6.50  
    6.51 -static __inline__ SDL_Window *
    6.52 +SDL_Window *
    6.53  SDL_GetWindowFromID(SDL_WindowID windowID)
    6.54  {
    6.55      int i, j;
    6.56 @@ -755,6 +767,15 @@
    6.57      return NULL;
    6.58  }
    6.59  
    6.60 +SDL_VideoDisplay *
    6.61 +SDL_GetDisplayFromWindow(SDL_Window * window)
    6.62 +{
    6.63 +    if (!_this) {
    6.64 +        return NULL;
    6.65 +    }
    6.66 +    return &_this->displays[window->display];
    6.67 +}
    6.68 +
    6.69  Uint32
    6.70  SDL_GetWindowFlags(SDL_WindowID windowID)
    6.71  {
    6.72 @@ -1221,11 +1242,20 @@
    6.73              return 0;
    6.74          }
    6.75      } else {
    6.76 -        bpp = fmt->BitsPerPixel;
    6.77 -        Rmask = fmt->Rmask;
    6.78 -        Gmask = fmt->Gmask;
    6.79 -        Bmask = fmt->Bmask;
    6.80 -        Amask = fmt->Amask;
    6.81 +        if (fmt->Amask || !(surface_flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA))) {
    6.82 +            bpp = fmt->BitsPerPixel;
    6.83 +            Rmask = fmt->Rmask;
    6.84 +            Gmask = fmt->Gmask;
    6.85 +            Bmask = fmt->Bmask;
    6.86 +            Amask = fmt->Amask;
    6.87 +        } else {
    6.88 +            /* Need a format with alpha */
    6.89 +            bpp = 32;
    6.90 +            Rmask = 0x00FF0000;
    6.91 +            Gmask = 0x0000FF00;
    6.92 +            Bmask = 0x000000FF;
    6.93 +            Amask = 0xFF000000;
    6.94 +        }
    6.95          format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
    6.96          if (!format) {
    6.97              SDL_SetError("Unknown pixel format");
    6.98 @@ -1261,14 +1291,10 @@
    6.99      }
   6.100  
   6.101      /* Copy the palette if any */
   6.102 -    if (fmt->palette && dst.format->palette) {
   6.103 +    if (fmt->palette) {
   6.104          SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
   6.105                                fmt->palette->ncolors);
   6.106 -
   6.107 -        SDL_memcpy(dst.format->palette->colors,
   6.108 -                   fmt->palette->colors,
   6.109 -                   fmt->palette->ncolors * sizeof(SDL_Color));
   6.110 -        dst.format->palette->ncolors = fmt->palette->ncolors;
   6.111 +        SDL_SetSurfacePalette(&dst, fmt->palette);
   6.112      }
   6.113  
   6.114      /* Make the texture transparent if the surface has colorkey */
   6.115 @@ -1552,10 +1578,11 @@
   6.116      }
   6.117  
   6.118      if (!rect) {
   6.119 +        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   6.120          full_rect.x = 0;
   6.121          full_rect.y = 0;
   6.122 -        full_rect.w = renderer->window->w;
   6.123 -        full_rect.h = renderer->window->h;
   6.124 +        full_rect.w = window->w;
   6.125 +        full_rect.h = window->h;
   6.126          rect = &full_rect;
   6.127      }
   6.128  
   6.129 @@ -1588,10 +1615,11 @@
   6.130          srcrect = &full_srcrect;
   6.131      }
   6.132      if (!dstrect) {
   6.133 +        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   6.134          full_dstrect.x = 0;
   6.135          full_dstrect.y = 0;
   6.136 -        full_dstrect.w = renderer->window->w;
   6.137 -        full_dstrect.h = renderer->window->h;
   6.138 +        full_dstrect.w = window->w;
   6.139 +        full_dstrect.h = window->h;
   6.140          dstrect = &full_dstrect;
   6.141      }
   6.142  
   6.143 @@ -1615,10 +1643,11 @@
   6.144      }
   6.145  
   6.146      if (!rect) {
   6.147 +        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   6.148          full_rect.x = 0;
   6.149          full_rect.y = 0;
   6.150 -        full_rect.w = renderer->window->w;
   6.151 -        full_rect.h = renderer->window->h;
   6.152 +        full_rect.w = window->w;
   6.153 +        full_rect.h = window->h;
   6.154          rect = &full_rect;
   6.155      }
   6.156  
   6.157 @@ -1641,10 +1670,11 @@
   6.158      }
   6.159  
   6.160      if (!rect) {
   6.161 +        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   6.162          full_rect.x = 0;
   6.163          full_rect.y = 0;
   6.164 -        full_rect.w = renderer->window->w;
   6.165 -        full_rect.h = renderer->window->h;
   6.166 +        full_rect.w = window->w;
   6.167 +        full_rect.h = window->h;
   6.168          rect = &full_rect;
   6.169      }
   6.170  
     7.1 --- a/src/video/dummy/SDL_nullrender.c	Sat Jun 24 04:31:42 2006 +0000
     7.2 +++ b/src/video/dummy/SDL_nullrender.c	Sat Jun 24 16:51:01 2006 +0000
     7.3 @@ -63,7 +63,8 @@
     7.4  SDL_Renderer *
     7.5  SDL_DUMMY_CreateRenderer(SDL_Window * window, Uint32 flags)
     7.6  {
     7.7 -    SDL_DisplayMode *displayMode = &window->display->current_mode;
     7.8 +    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
     7.9 +    SDL_DisplayMode *displayMode = &display->current_mode;
    7.10      SDL_Renderer *renderer;
    7.11      SDL_DUMMY_RenderData *data;
    7.12      int i, n;
    7.13 @@ -96,7 +97,7 @@
    7.14      renderer->RenderPresent = SDL_DUMMY_RenderPresent;
    7.15      renderer->DestroyRenderer = SDL_DUMMY_DestroyRenderer;
    7.16      renderer->info = SDL_DUMMY_RenderDriver.info;
    7.17 -    renderer->window = window;
    7.18 +    renderer->window = window->id;
    7.19      renderer->driverdata = data;
    7.20  
    7.21      data->surface =
    7.22 @@ -106,7 +107,7 @@
    7.23          SDL_DUMMY_DestroyRenderer(renderer);
    7.24          return NULL;
    7.25      }
    7.26 -    SDL_SetSurfacePalette(data->surface, window->display->palette);
    7.27 +    SDL_SetSurfacePalette(data->surface, display->palette);
    7.28  
    7.29      return renderer;
    7.30  }
    7.31 @@ -170,7 +171,7 @@
    7.32      if (SDL_getenv("SDL_VIDEO_DUMMY_SAVE_FRAMES")) {
    7.33          char file[128];
    7.34          SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
    7.35 -                     renderer->window->id, ++frame_number);
    7.36 +                     renderer->window, ++frame_number);
    7.37          SDL_SaveBMP(surface, file);
    7.38      }
    7.39  }
     8.1 --- a/test/Makefile.in	Sat Jun 24 04:31:42 2006 +0000
     8.2 +++ b/test/Makefile.in	Sat Jun 24 16:51:01 2006 +0000
     8.3 @@ -7,7 +7,7 @@
     8.4  CFLAGS  = @CFLAGS@
     8.5  LIBS	= @LIBS@
     8.6  
     8.7 -TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE)
     8.8 +TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE)
     8.9  
    8.10  all: $(TARGETS)
    8.11  
    8.12 @@ -80,6 +80,9 @@
    8.13  testsprite$(EXE): $(srcdir)/testsprite.c
    8.14  	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@
    8.15  
    8.16 +testsprite2$(EXE): $(srcdir)/testsprite2.c
    8.17 +	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@
    8.18 +
    8.19  testtimer$(EXE): $(srcdir)/testtimer.c
    8.20  	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
    8.21  
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/testsprite2.c	Sat Jun 24 16:51:01 2006 +0000
     9.3 @@ -0,0 +1,257 @@
     9.4 +/* Simple program:  Move N sprites around on the screen as fast as possible */
     9.5 +
     9.6 +#include <stdio.h>
     9.7 +#include <stdlib.h>
     9.8 +#include <string.h>
     9.9 +#include <ctype.h>
    9.10 +#include <math.h>
    9.11 +#include <time.h>
    9.12 +
    9.13 +#include "SDL.h"
    9.14 +
    9.15 +#define NUM_WINDOWS 2
    9.16 +#define WINDOW_W    640
    9.17 +#define WINDOW_H    480
    9.18 +#define NUM_SPRITES	100
    9.19 +#define MAX_SPEED 	1
    9.20 +
    9.21 +static int num_windows;
    9.22 +static int num_sprites;
    9.23 +static SDL_WindowID *windows;
    9.24 +static SDL_TextureID *sprites;
    9.25 +static SDL_Rect *positions;
    9.26 +static SDL_Rect *velocities;
    9.27 +static int sprite_w, sprite_h;
    9.28 +
    9.29 +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    9.30 +static void
    9.31 +quit(int rc)
    9.32 +{
    9.33 +    if (windows) {
    9.34 +        SDL_free(windows);
    9.35 +    }
    9.36 +    if (sprites) {
    9.37 +        SDL_free(sprites);
    9.38 +    }
    9.39 +    if (positions) {
    9.40 +        SDL_free(positions);
    9.41 +    }
    9.42 +    if (velocities) {
    9.43 +        SDL_free(velocities);
    9.44 +    }
    9.45 +    SDL_Quit();
    9.46 +    exit(rc);
    9.47 +}
    9.48 +
    9.49 +int
    9.50 +LoadSprite(char *file)
    9.51 +{
    9.52 +    int i;
    9.53 +    SDL_Surface *temp;
    9.54 +
    9.55 +    /* Load the sprite image */
    9.56 +    temp = SDL_LoadBMP(file);
    9.57 +    if (temp == NULL) {
    9.58 +        fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
    9.59 +        return (-1);
    9.60 +    }
    9.61 +    sprite_w = temp->w;
    9.62 +    sprite_h = temp->h;
    9.63 +
    9.64 +    /* Set transparent pixel as the pixel at (0,0) */
    9.65 +    if (temp->format->palette) {
    9.66 +        SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels);
    9.67 +    }
    9.68 +
    9.69 +    /* Create textures from the image */
    9.70 +    for (i = 0; i < num_windows; ++i) {
    9.71 +        SDL_SelectRenderer(windows[i]);
    9.72 +        sprites[i] =
    9.73 +            SDL_CreateTextureFromSurface(0, SDL_TextureAccess_Remote, temp);
    9.74 +        if (!sprites[i]) {
    9.75 +            fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
    9.76 +            SDL_FreeSurface(temp);
    9.77 +            return (-1);
    9.78 +        }
    9.79 +    }
    9.80 +    SDL_FreeSurface(temp);
    9.81 +
    9.82 +    /* We're ready to roll. :) */
    9.83 +    return (0);
    9.84 +}
    9.85 +
    9.86 +void
    9.87 +MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
    9.88 +{
    9.89 +    int i, n;
    9.90 +    int window_w, window_h;
    9.91 +    SDL_Rect area, *position, *velocity;
    9.92 +
    9.93 +    SDL_SelectRenderer(window);
    9.94 +
    9.95 +    SDL_RenderFill(NULL, 0);
    9.96 +
    9.97 +    /* Query the sizes */
    9.98 +    SDL_GetWindowSize(window, &window_w, &window_h);
    9.99 +
   9.100 +    /* Move the sprite, bounce at the wall, and draw */
   9.101 +    n = 0;
   9.102 +    for (i = 0; i < num_sprites; ++i) {
   9.103 +        position = &positions[i];
   9.104 +        velocity = &velocities[i];
   9.105 +        position->x += velocity->x;
   9.106 +        if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
   9.107 +            velocity->x = -velocity->x;
   9.108 +            position->x += velocity->x;
   9.109 +        }
   9.110 +        position->y += velocity->y;
   9.111 +        if ((position->y < 0) || (position->y >= (window_h - sprite_w))) {
   9.112 +            velocity->y = -velocity->y;
   9.113 +            position->y += velocity->y;
   9.114 +        }
   9.115 +
   9.116 +        /* Blit the sprite onto the screen */
   9.117 +        SDL_RenderCopy(sprite, NULL, position, SDL_TextureBlendMode_Mask,
   9.118 +                       SDL_TextureScaleMode_None);
   9.119 +    }
   9.120 +
   9.121 +    /* Update the screen! */
   9.122 +    SDL_RenderPresent();
   9.123 +}
   9.124 +
   9.125 +int
   9.126 +main(int argc, char *argv[])
   9.127 +{
   9.128 +    const SDL_DisplayMode *current_mode;
   9.129 +    int window_w, window_h;
   9.130 +    int i, done;
   9.131 +    SDL_Event event;
   9.132 +    Uint32 then, now, frames;
   9.133 +
   9.134 +    /* Initialize SDL */
   9.135 +    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
   9.136 +        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
   9.137 +        return (1);
   9.138 +    }
   9.139 +
   9.140 +    num_windows = NUM_WINDOWS;
   9.141 +    num_sprites = NUM_SPRITES;
   9.142 +    window_w = WINDOW_W;
   9.143 +    window_h = WINDOW_H;
   9.144 +    while (argc > 1) {
   9.145 +        --argc;
   9.146 +        if (strcmp(argv[argc - 1], "-width") == 0) {
   9.147 +            window_w = atoi(argv[argc]);
   9.148 +            --argc;
   9.149 +        } else if (strcmp(argv[argc - 1], "-height") == 0) {
   9.150 +            window_h = atoi(argv[argc]);
   9.151 +            --argc;
   9.152 +        } else if (isdigit(argv[argc][0])) {
   9.153 +            num_sprites = atoi(argv[argc]);
   9.154 +        } else {
   9.155 +            fprintf(stderr,
   9.156 +                    "Usage: %s [-width] [-height] [numsprites]\n", argv[0]);
   9.157 +            quit(1);
   9.158 +        }
   9.159 +    }
   9.160 +
   9.161 +    /* Initialize the video mode, if necessary */
   9.162 +    current_mode = SDL_GetCurrentDisplayMode();
   9.163 +    if (!current_mode->w || !current_mode->h) {
   9.164 +        SDL_DisplayMode mode;
   9.165 +
   9.166 +        /* Let the driver pick something it likes, we don't care */
   9.167 +        mode.format = 0;
   9.168 +        mode.w = 0;
   9.169 +        mode.h = 0;
   9.170 +        mode.refresh_rate = 0;
   9.171 +
   9.172 +        if (SDL_SetDisplayMode(&mode) < 0) {
   9.173 +            fprintf(stderr, "Couldn't set display mode: %s\n",
   9.174 +                    SDL_GetError());
   9.175 +            quit(2);
   9.176 +        }
   9.177 +    }
   9.178 +
   9.179 +    /* Create the windows, initialize the renderers, and load the textures */
   9.180 +    windows = (SDL_WindowID *) SDL_malloc(num_windows * sizeof(*windows));
   9.181 +    sprites = (SDL_TextureID *) SDL_malloc(num_windows * sizeof(*sprites));
   9.182 +    if (!windows || !sprites) {
   9.183 +        fprintf(stderr, "Out of memory!\n");
   9.184 +        quit(2);
   9.185 +    }
   9.186 +    for (i = 0; i < num_windows; ++i) {
   9.187 +        char title[32];
   9.188 +
   9.189 +        SDL_snprintf(title, sizeof(title), "testsprite %d", i + 1);
   9.190 +        windows[i] =
   9.191 +            SDL_CreateWindow(title, -1, -1, window_w, window_h,
   9.192 +                             SDL_WINDOW_SHOWN);
   9.193 +        if (!windows[i]) {
   9.194 +            fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
   9.195 +            quit(2);
   9.196 +        }
   9.197 +
   9.198 +        if (SDL_CreateRenderer(windows[i], -1, 0) < 0) {
   9.199 +            fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
   9.200 +            quit(2);
   9.201 +        }
   9.202 +    }
   9.203 +    if (LoadSprite("icon.bmp") < 0) {
   9.204 +        quit(2);
   9.205 +    }
   9.206 +
   9.207 +    /* Allocate memory for the sprite info */
   9.208 +    positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   9.209 +    velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   9.210 +    if (!positions || !velocities) {
   9.211 +        fprintf(stderr, "Out of memory!\n");
   9.212 +        quit(2);
   9.213 +    }
   9.214 +    srand(time(NULL));
   9.215 +    for (i = 0; i < num_sprites; ++i) {
   9.216 +        positions[i].x = rand() % (window_w - sprite_w);
   9.217 +        positions[i].y = rand() % (window_h - sprite_h);
   9.218 +        positions[i].w = sprite_w;
   9.219 +        positions[i].h = sprite_h;
   9.220 +        velocities[i].x = 0;
   9.221 +        velocities[i].y = 0;
   9.222 +        while (!velocities[i].x && !velocities[i].y) {
   9.223 +            velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   9.224 +            velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   9.225 +        }
   9.226 +    }
   9.227 +
   9.228 +    /* Loop, blitting sprites and waiting for a keystroke */
   9.229 +    frames = 0;
   9.230 +    then = SDL_GetTicks();
   9.231 +    done = 0;
   9.232 +    while (!done) {
   9.233 +        /* Check for events */
   9.234 +        ++frames;
   9.235 +        while (SDL_PollEvent(&event)) {
   9.236 +            switch (event.type) {
   9.237 +            case SDL_KEYDOWN:
   9.238 +                /* Any keypress quits the app... */
   9.239 +            case SDL_QUIT:
   9.240 +                done = 1;
   9.241 +                break;
   9.242 +            default:
   9.243 +                break;
   9.244 +            }
   9.245 +        }
   9.246 +        for (i = 0; i < num_windows; ++i) {
   9.247 +            MoveSprites(windows[i], sprites[i]);
   9.248 +        }
   9.249 +    }
   9.250 +
   9.251 +    /* Print out some timing information */
   9.252 +    now = SDL_GetTicks();
   9.253 +    if (now > then) {
   9.254 +        printf("%2.2f frames per second\n",
   9.255 +               ((double) frames * 1000) / (now - then));
   9.256 +    }
   9.257 +    quit(0);
   9.258 +}
   9.259 +
   9.260 +/* vi: set ts=4 sw=4 expandtab: */