Added a multi-window version of testsprite using the new API.
--- 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: */