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 1706 1577404809f0
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
--- a/include/SDL_video.h	Sat Jun 24 04:31:42 2006 +0000
+++ b/include/SDL_video.h	Sat Jun 24 16:51:01 2006 +0000
@@ -763,7 +763,7 @@
 /**
  * \fn SDL_TextureID SDL_CreateTexture(Uint32 format, int access, int w, int h)
  *
- * \brief Create a texture
+ * \brief Create a texture for the current rendering context.
  *
  * \param format The format of the texture
  * \param access One of the enumerated values in SDL_TextureAccess
--- a/src/video/SDL_bmp.c	Sat Jun 24 04:31:42 2006 +0000
+++ b/src/video/SDL_bmp.c	Sat Jun 24 16:51:01 2006 +0000
@@ -232,7 +232,6 @@
                 SDL_RWread(src, &palette->colors[i].unused, 1, 1);
             }
         }
-        palette->ncolors = biClrUsed;
     }
 
     /* Read the surface pixels.  Note that the bmp image is upside down */
--- a/src/video/SDL_pixels.c	Sat Jun 24 04:31:42 2006 +0000
+++ b/src/video/SDL_pixels.c	Sat Jun 24 16:51:01 2006 +0000
@@ -642,8 +642,11 @@
     if (identical) {
         if (src->ncolors <= dst->ncolors) {
             /* If an identical palette, no need to map */
-            if (SDL_memcmp(src->colors, dst->colors, src->ncolors *
-                           sizeof(SDL_Color)) == 0) {
+            if (src == dst
+                ||
+                (SDL_memcmp
+                 (src->colors, dst->colors,
+                  src->ncolors * sizeof(SDL_Color)) == 0)) {
                 *identical = 1;
                 return (NULL);
             }
--- a/src/video/SDL_renderer_sw.c	Sat Jun 24 04:31:42 2006 +0000
+++ b/src/video/SDL_renderer_sw.c	Sat Jun 24 16:51:01 2006 +0000
@@ -111,7 +111,8 @@
 SDL_Renderer *
 SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags)
 {
-    SDL_DisplayMode *displayMode = &window->display->current_mode;
+    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
+    SDL_DisplayMode *displayMode = &display->current_mode;
     SDL_Renderer *renderer;
     SDL_SW_RenderData *data;
     int i, n;
@@ -156,7 +157,7 @@
     renderer->DestroyTexture = SDL_SW_DestroyTexture;
     renderer->DestroyRenderer = SDL_SW_DestroyRenderer;
     renderer->info = SDL_SW_RenderDriver.info;
-    renderer->window = window;
+    renderer->window = window->id;
     renderer->driverdata = data;
 
     renderer->info.flags = SDL_Renderer_RenderTarget;
@@ -179,14 +180,14 @@
             SDL_SW_DestroyRenderer(renderer);
             return NULL;
         }
-        SDL_SetSurfacePalette(data->screens[i], window->display->palette);
+        SDL_SetSurfacePalette(data->screens[i], display->palette);
     }
     data->current_screen = 0;
     data->target = data->screens[0];
 
     /* Find a render driver that we can use to display data */
-    for (i = 0; i < window->display->num_render_drivers; ++i) {
-        SDL_RenderDriver *driver = &window->display->render_drivers[i];
+    for (i = 0; i < display->num_render_drivers; ++i) {
+        SDL_RenderDriver *driver = &display->render_drivers[i];
         if (driver->info.name != SDL_SW_RenderDriver.info.name) {
             data->renderer =
                 driver->CreateRenderer(window, SDL_Renderer_PresentDiscard);
@@ -195,7 +196,7 @@
             }
         }
     }
-    if (i == window->display->num_render_drivers) {
+    if (i == display->num_render_drivers) {
         SDL_SW_DestroyRenderer(renderer);
         SDL_SetError("Couldn't find display render driver");
         return NULL;
@@ -377,6 +378,8 @@
                   int blendMode, int scaleMode)
 {
     SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata;
+    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
+    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
 
     if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
         SDL_Surface *target = data->target;
@@ -384,9 +387,8 @@
             (Uint8 *) target->pixels + dstrect->y * target->pitch +
             dstrect->x * target->format->BytesPerPixel;
         return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
-                                   srcrect,
-                                   renderer->window->display->current_mode.
-                                   format, dstrect->w, dstrect->h, pixels,
+                                   srcrect, display->current_mode.format,
+                                   dstrect->w, dstrect->h, pixels,
                                    target->pitch);
     } else {
         SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
--- a/src/video/SDL_sysvideo.h	Sat Jun 24 04:31:42 2006 +0000
+++ b/src/video/SDL_sysvideo.h	Sat Jun 24 16:51:01 2006 +0000
@@ -104,7 +104,7 @@
     SDL_RendererInfo info;
 
     /* The window associated with the renderer */
-    SDL_Window *window;
+    SDL_WindowID window;
 
     void *driverdata;
 };
@@ -130,7 +130,7 @@
 
     Uint16 *gamma;
 
-    SDL_VideoDisplay *display;
+    int display;
     SDL_Renderer *renderer;
 
     void *userdata;
@@ -445,6 +445,9 @@
 extern void SDL_AddRenderDriver(int displayIndex,
                                 const SDL_RenderDriver * driver);
 
+extern SDL_Window *SDL_GetWindowFromID(SDL_WindowID windowID);
+extern SDL_VideoDisplay *SDL_GetDisplayFromWindow(SDL_Window * window);
+
 #endif /* _SDL_sysvideo_h */
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/SDL_video.c	Sat Jun 24 04:31:42 2006 +0000
+++ b/src/video/SDL_video.c	Sat Jun 24 16:51:01 2006 +0000
@@ -507,6 +507,16 @@
         } else {
             closest->refresh_rate = mode->refresh_rate;
         }
+        /* Pick some reasonable defaults if the app and driver don't care */
+        if (!closest->format) {
+            closest->format = SDL_PixelFormat_RGB888;
+        }
+        if (!closest->w) {
+            closest->w = 640;
+        }
+        if (!closest->h) {
+            closest->h = 480;
+        }
         return closest;
     }
     return NULL;
@@ -577,6 +587,8 @@
             if (!display->palette) {
                 return -1;
             }
+            SDL_DitherColors(display->palette->colors,
+                             SDL_BITSPERPIXEL(display_mode.format));
         }
     }
 
@@ -664,7 +676,7 @@
     window.w = w;
     window.h = h;
     window.flags = (flags & allowed_flags);
-    window.display = &SDL_CurrentDisplay;
+    window.display = _this->current_display;
 
     if (_this->CreateWindow && _this->CreateWindow(_this, &window) < 0) {
         if (window.title) {
@@ -707,7 +719,7 @@
 
     SDL_zero(window);
     window.id = _this->next_object_id++;
-    window.display = &SDL_CurrentDisplay;
+    window.display = _this->current_display;
 
     if (!_this->CreateWindowFrom ||
         _this->CreateWindowFrom(_this, &window, data) < 0) {
@@ -734,7 +746,7 @@
     return window.id;
 }
 
-static __inline__ SDL_Window *
+SDL_Window *
 SDL_GetWindowFromID(SDL_WindowID windowID)
 {
     int i, j;
@@ -755,6 +767,15 @@
     return NULL;
 }
 
+SDL_VideoDisplay *
+SDL_GetDisplayFromWindow(SDL_Window * window)
+{
+    if (!_this) {
+        return NULL;
+    }
+    return &_this->displays[window->display];
+}
+
 Uint32
 SDL_GetWindowFlags(SDL_WindowID windowID)
 {
@@ -1221,11 +1242,20 @@
             return 0;
         }
     } else {
-        bpp = fmt->BitsPerPixel;
-        Rmask = fmt->Rmask;
-        Gmask = fmt->Gmask;
-        Bmask = fmt->Bmask;
-        Amask = fmt->Amask;
+        if (fmt->Amask || !(surface_flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA))) {
+            bpp = fmt->BitsPerPixel;
+            Rmask = fmt->Rmask;
+            Gmask = fmt->Gmask;
+            Bmask = fmt->Bmask;
+            Amask = fmt->Amask;
+        } else {
+            /* Need a format with alpha */
+            bpp = 32;
+            Rmask = 0x00FF0000;
+            Gmask = 0x0000FF00;
+            Bmask = 0x000000FF;
+            Amask = 0xFF000000;
+        }
         format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
         if (!format) {
             SDL_SetError("Unknown pixel format");
@@ -1261,14 +1291,10 @@
     }
 
     /* Copy the palette if any */
-    if (fmt->palette && dst.format->palette) {
+    if (fmt->palette) {
         SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
                               fmt->palette->ncolors);
-
-        SDL_memcpy(dst.format->palette->colors,
-                   fmt->palette->colors,
-                   fmt->palette->ncolors * sizeof(SDL_Color));
-        dst.format->palette->ncolors = fmt->palette->ncolors;
+        SDL_SetSurfacePalette(&dst, fmt->palette);
     }
 
     /* Make the texture transparent if the surface has colorkey */
@@ -1552,10 +1578,11 @@
     }
 
     if (!rect) {
+        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
         full_rect.x = 0;
         full_rect.y = 0;
-        full_rect.w = renderer->window->w;
-        full_rect.h = renderer->window->h;
+        full_rect.w = window->w;
+        full_rect.h = window->h;
         rect = &full_rect;
     }
 
@@ -1588,10 +1615,11 @@
         srcrect = &full_srcrect;
     }
     if (!dstrect) {
+        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
         full_dstrect.x = 0;
         full_dstrect.y = 0;
-        full_dstrect.w = renderer->window->w;
-        full_dstrect.h = renderer->window->h;
+        full_dstrect.w = window->w;
+        full_dstrect.h = window->h;
         dstrect = &full_dstrect;
     }
 
@@ -1615,10 +1643,11 @@
     }
 
     if (!rect) {
+        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
         full_rect.x = 0;
         full_rect.y = 0;
-        full_rect.w = renderer->window->w;
-        full_rect.h = renderer->window->h;
+        full_rect.w = window->w;
+        full_rect.h = window->h;
         rect = &full_rect;
     }
 
@@ -1641,10 +1670,11 @@
     }
 
     if (!rect) {
+        SDL_Window *window = SDL_GetWindowFromID(renderer->window);
         full_rect.x = 0;
         full_rect.y = 0;
-        full_rect.w = renderer->window->w;
-        full_rect.h = renderer->window->h;
+        full_rect.w = window->w;
+        full_rect.h = window->h;
         rect = &full_rect;
     }
 
--- a/src/video/dummy/SDL_nullrender.c	Sat Jun 24 04:31:42 2006 +0000
+++ b/src/video/dummy/SDL_nullrender.c	Sat Jun 24 16:51:01 2006 +0000
@@ -63,7 +63,8 @@
 SDL_Renderer *
 SDL_DUMMY_CreateRenderer(SDL_Window * window, Uint32 flags)
 {
-    SDL_DisplayMode *displayMode = &window->display->current_mode;
+    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
+    SDL_DisplayMode *displayMode = &display->current_mode;
     SDL_Renderer *renderer;
     SDL_DUMMY_RenderData *data;
     int i, n;
@@ -96,7 +97,7 @@
     renderer->RenderPresent = SDL_DUMMY_RenderPresent;
     renderer->DestroyRenderer = SDL_DUMMY_DestroyRenderer;
     renderer->info = SDL_DUMMY_RenderDriver.info;
-    renderer->window = window;
+    renderer->window = window->id;
     renderer->driverdata = data;
 
     data->surface =
@@ -106,7 +107,7 @@
         SDL_DUMMY_DestroyRenderer(renderer);
         return NULL;
     }
-    SDL_SetSurfacePalette(data->surface, window->display->palette);
+    SDL_SetSurfacePalette(data->surface, display->palette);
 
     return renderer;
 }
@@ -170,7 +171,7 @@
     if (SDL_getenv("SDL_VIDEO_DUMMY_SAVE_FRAMES")) {
         char file[128];
         SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
-                     renderer->window->id, ++frame_number);
+                     renderer->window, ++frame_number);
         SDL_SaveBMP(surface, file);
     }
 }
--- a/test/Makefile.in	Sat Jun 24 04:31:42 2006 +0000
+++ b/test/Makefile.in	Sat Jun 24 16:51:01 2006 +0000
@@ -7,7 +7,7 @@
 CFLAGS  = @CFLAGS@
 LIBS	= @LIBS@
 
-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)
+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)
 
 all: $(TARGETS)
 
@@ -80,6 +80,9 @@
 testsprite$(EXE): $(srcdir)/testsprite.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@
 
+testsprite2$(EXE): $(srcdir)/testsprite2.c
+	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@
+
 testtimer$(EXE): $(srcdir)/testtimer.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testsprite2.c	Sat Jun 24 16:51:01 2006 +0000
@@ -0,0 +1,257 @@
+/* Simple program:  Move N sprites around on the screen as fast as possible */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <time.h>
+
+#include "SDL.h"
+
+#define NUM_WINDOWS 2
+#define WINDOW_W    640
+#define WINDOW_H    480
+#define NUM_SPRITES	100
+#define MAX_SPEED 	1
+
+static int num_windows;
+static int num_sprites;
+static SDL_WindowID *windows;
+static SDL_TextureID *sprites;
+static SDL_Rect *positions;
+static SDL_Rect *velocities;
+static int sprite_w, sprite_h;
+
+/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
+static void
+quit(int rc)
+{
+    if (windows) {
+        SDL_free(windows);
+    }
+    if (sprites) {
+        SDL_free(sprites);
+    }
+    if (positions) {
+        SDL_free(positions);
+    }
+    if (velocities) {
+        SDL_free(velocities);
+    }
+    SDL_Quit();
+    exit(rc);
+}
+
+int
+LoadSprite(char *file)
+{
+    int i;
+    SDL_Surface *temp;
+
+    /* Load the sprite image */
+    temp = SDL_LoadBMP(file);
+    if (temp == NULL) {
+        fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
+        return (-1);
+    }
+    sprite_w = temp->w;
+    sprite_h = temp->h;
+
+    /* Set transparent pixel as the pixel at (0,0) */
+    if (temp->format->palette) {
+        SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels);
+    }
+
+    /* Create textures from the image */
+    for (i = 0; i < num_windows; ++i) {
+        SDL_SelectRenderer(windows[i]);
+        sprites[i] =
+            SDL_CreateTextureFromSurface(0, SDL_TextureAccess_Remote, temp);
+        if (!sprites[i]) {
+            fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
+            SDL_FreeSurface(temp);
+            return (-1);
+        }
+    }
+    SDL_FreeSurface(temp);
+
+    /* We're ready to roll. :) */
+    return (0);
+}
+
+void
+MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
+{
+    int i, n;
+    int window_w, window_h;
+    SDL_Rect area, *position, *velocity;
+
+    SDL_SelectRenderer(window);
+
+    SDL_RenderFill(NULL, 0);
+
+    /* Query the sizes */
+    SDL_GetWindowSize(window, &window_w, &window_h);
+
+    /* Move the sprite, bounce at the wall, and draw */
+    n = 0;
+    for (i = 0; i < num_sprites; ++i) {
+        position = &positions[i];
+        velocity = &velocities[i];
+        position->x += velocity->x;
+        if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
+            velocity->x = -velocity->x;
+            position->x += velocity->x;
+        }
+        position->y += velocity->y;
+        if ((position->y < 0) || (position->y >= (window_h - sprite_w))) {
+            velocity->y = -velocity->y;
+            position->y += velocity->y;
+        }
+
+        /* Blit the sprite onto the screen */
+        SDL_RenderCopy(sprite, NULL, position, SDL_TextureBlendMode_Mask,
+                       SDL_TextureScaleMode_None);
+    }
+
+    /* Update the screen! */
+    SDL_RenderPresent();
+}
+
+int
+main(int argc, char *argv[])
+{
+    const SDL_DisplayMode *current_mode;
+    int window_w, window_h;
+    int i, done;
+    SDL_Event event;
+    Uint32 then, now, frames;
+
+    /* Initialize SDL */
+    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
+        return (1);
+    }
+
+    num_windows = NUM_WINDOWS;
+    num_sprites = NUM_SPRITES;
+    window_w = WINDOW_W;
+    window_h = WINDOW_H;
+    while (argc > 1) {
+        --argc;
+        if (strcmp(argv[argc - 1], "-width") == 0) {
+            window_w = atoi(argv[argc]);
+            --argc;
+        } else if (strcmp(argv[argc - 1], "-height") == 0) {
+            window_h = atoi(argv[argc]);
+            --argc;
+        } else if (isdigit(argv[argc][0])) {
+            num_sprites = atoi(argv[argc]);
+        } else {
+            fprintf(stderr,
+                    "Usage: %s [-width] [-height] [numsprites]\n", argv[0]);
+            quit(1);
+        }
+    }
+
+    /* Initialize the video mode, if necessary */
+    current_mode = SDL_GetCurrentDisplayMode();
+    if (!current_mode->w || !current_mode->h) {
+        SDL_DisplayMode mode;
+
+        /* Let the driver pick something it likes, we don't care */
+        mode.format = 0;
+        mode.w = 0;
+        mode.h = 0;
+        mode.refresh_rate = 0;
+
+        if (SDL_SetDisplayMode(&mode) < 0) {
+            fprintf(stderr, "Couldn't set display mode: %s\n",
+                    SDL_GetError());
+            quit(2);
+        }
+    }
+
+    /* Create the windows, initialize the renderers, and load the textures */
+    windows = (SDL_WindowID *) SDL_malloc(num_windows * sizeof(*windows));
+    sprites = (SDL_TextureID *) SDL_malloc(num_windows * sizeof(*sprites));
+    if (!windows || !sprites) {
+        fprintf(stderr, "Out of memory!\n");
+        quit(2);
+    }
+    for (i = 0; i < num_windows; ++i) {
+        char title[32];
+
+        SDL_snprintf(title, sizeof(title), "testsprite %d", i + 1);
+        windows[i] =
+            SDL_CreateWindow(title, -1, -1, window_w, window_h,
+                             SDL_WINDOW_SHOWN);
+        if (!windows[i]) {
+            fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
+            quit(2);
+        }
+
+        if (SDL_CreateRenderer(windows[i], -1, 0) < 0) {
+            fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
+            quit(2);
+        }
+    }
+    if (LoadSprite("icon.bmp") < 0) {
+        quit(2);
+    }
+
+    /* Allocate memory for the sprite info */
+    positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
+    velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
+    if (!positions || !velocities) {
+        fprintf(stderr, "Out of memory!\n");
+        quit(2);
+    }
+    srand(time(NULL));
+    for (i = 0; i < num_sprites; ++i) {
+        positions[i].x = rand() % (window_w - sprite_w);
+        positions[i].y = rand() % (window_h - sprite_h);
+        positions[i].w = sprite_w;
+        positions[i].h = sprite_h;
+        velocities[i].x = 0;
+        velocities[i].y = 0;
+        while (!velocities[i].x && !velocities[i].y) {
+            velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
+            velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
+        }
+    }
+
+    /* Loop, blitting sprites and waiting for a keystroke */
+    frames = 0;
+    then = SDL_GetTicks();
+    done = 0;
+    while (!done) {
+        /* Check for events */
+        ++frames;
+        while (SDL_PollEvent(&event)) {
+            switch (event.type) {
+            case SDL_KEYDOWN:
+                /* Any keypress quits the app... */
+            case SDL_QUIT:
+                done = 1;
+                break;
+            default:
+                break;
+            }
+        }
+        for (i = 0; i < num_windows; ++i) {
+            MoveSprites(windows[i], sprites[i]);
+        }
+    }
+
+    /* Print out some timing information */
+    now = SDL_GetTicks();
+    if (now > then) {
+        printf("%2.2f frames per second\n",
+               ((double) frames * 1000) / (now - then));
+    }
+    quit(0);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */