From a1c1e588a492f3332d1053f95540ffc04f640311 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 28 Oct 2009 06:04:07 +0000 Subject: [PATCH] Automatically initialize the video system and create a renderer to simplify use. --- src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 132 +++++++++++++++---------------- test/Makefile.in | 5 +- test/testspriteminimal.c | 165 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 232 insertions(+), 71 deletions(-) create mode 100644 test/testspriteminimal.c diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index c341cbbde..1d32db268 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -396,6 +396,7 @@ extern VideoBootStrap PND_bootstrap; #endif #define SDL_CurrentDisplay (_this->displays[_this->current_display]) +#define SDL_CurrentRenderer (SDL_CurrentDisplay.current_renderer) extern SDL_VideoDevice *SDL_GetVideoDevice(); extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 8c42fe326..1c390b7b4 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -754,8 +754,10 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) SDL_Window *windows; if (!_this) { - SDL_UninitializedVideo(); - return 0; + /* Initialize the video system if needed */ + if (SDL_VideoInit(NULL, 0) < 0) { + return 0; + } } if (flags & SDL_WINDOW_OPENGL) { if (!_this->GL_CreateContext) { @@ -926,15 +928,28 @@ SDL_GetWindowFromID(SDL_WindowID windowID) SDL_UninitializedVideo(); return NULL; } - for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; - for (j = 0; j < display->num_windows; ++j) { - SDL_Window *window = &display->windows[j]; - if (window->id == windowID) { + if (windowID) { + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + for (j = 0; j < display->num_windows; ++j) { + SDL_Window *window = &display->windows[j]; + if (window->id == windowID) { + return window; + } + } + } + } else { + /* Just return the first active window */ + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + for (j = 0; j < display->num_windows; ++j) { + SDL_Window *window = &display->windows[j]; return window; } } } + /* Couldn't find the window with the requested ID */ + SDL_SetError("Invalid window ID"); return NULL; } @@ -951,6 +966,23 @@ SDL_GetDisplayFromWindow(SDL_Window * window) return &_this->displays[window->display]; } +static __inline__ SDL_Renderer * +SDL_GetCurrentRenderer() +{ + SDL_Renderer *renderer; + + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + if (!SDL_CurrentRenderer) { + if (SDL_CreateRenderer(0, -1, 0) < 0) { + return NULL; + } + } + return SDL_CurrentRenderer; +} + Uint32 SDL_GetWindowFlags(SDL_WindowID windowID) { @@ -1506,31 +1538,29 @@ SDL_SelectRenderer(SDL_WindowID windowID) return -1; } renderer = window->renderer; - if (!renderer) { - SDL_SetError("Renderer hasn't been created yet"); - return -1; - } - if (renderer->ActivateRenderer) { - if (renderer->ActivateRenderer(renderer) < 0) { + if (renderer) { + if (renderer->ActivateRenderer) { + if (renderer->ActivateRenderer(renderer) < 0) { + return -1; + } + } + SDL_CurrentDisplay.current_renderer = renderer; + } else { + if (SDL_CreateRenderer(windowID, -1, 0) < 0) { return -1; } } - SDL_CurrentDisplay.current_renderer = renderer; return 0; } int SDL_GetRendererInfo(SDL_RendererInfo * info) { - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - if (!SDL_CurrentDisplay.current_renderer) { - SDL_SetError("There is no current renderer"); + SDL_Renderer *renderer = SDL_GetCurrentRenderer(); + if (!renderer) { return -1; } - *info = SDL_CurrentDisplay.current_renderer->info; + *info = renderer->info; return 0; } @@ -1541,11 +1571,7 @@ SDL_CreateTexture(Uint32 format, int access, int w, int h) SDL_Renderer *renderer; SDL_Texture *texture; - if (!_this) { - SDL_UninitializedVideo(); - return 0; - } - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { return 0; } @@ -1599,9 +1625,8 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) } fmt = surface->format; - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { - SDL_SetError("No current renderer available"); return 0; } @@ -2234,11 +2259,7 @@ SDL_SetRenderDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) { SDL_Renderer *renderer; - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { return -1; } @@ -2258,11 +2279,7 @@ SDL_GetRenderDrawColor(Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a) { SDL_Renderer *renderer; - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { return -1; } @@ -2286,11 +2303,7 @@ SDL_SetRenderDrawBlendMode(int blendMode) { SDL_Renderer *renderer; - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { return -1; } @@ -2307,11 +2320,7 @@ SDL_GetRenderDrawBlendMode(int *blendMode) { SDL_Renderer *renderer; - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { return -1; } @@ -2325,11 +2334,7 @@ SDL_RenderPoint(int x, int y) SDL_Renderer *renderer; SDL_Window *window; - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { return -1; } @@ -2355,11 +2360,7 @@ SDL_RenderLine(int x1, int y1, int x2, int y2) return SDL_RenderPoint(x1, y1); } - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { return -1; } @@ -2386,11 +2387,7 @@ SDL_RenderFill(const SDL_Rect * rect) SDL_Window *window; SDL_Rect real_rect; - if (!_this) { - SDL_UninitializedVideo(); - return -1; - } - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { return -1; } @@ -2422,9 +2419,8 @@ SDL_RenderCopy(SDL_TextureID textureID, const SDL_Rect * srcrect, SDL_Rect real_srcrect; SDL_Rect real_dstrect; - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer) { - SDL_SetError("No current renderer available"); return -1; } if (!texture) { @@ -2483,11 +2479,7 @@ SDL_RenderPresent(void) { SDL_Renderer *renderer; - if (!_this) { - SDL_UninitializedVideo(); - return; - } - renderer = SDL_CurrentDisplay.current_renderer; + renderer = SDL_GetCurrentRenderer(); if (!renderer || !renderer->RenderPresent) { return; } diff --git a/test/Makefile.in b/test/Makefile.in index 27f4ab6ef..816bae5c0 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -7,7 +7,7 @@ EXE = @EXE@ CFLAGS = @CFLAGS@ LIBS = @LIBS@ -TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testresample$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testpower$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testdyngles$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testgles$(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) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE) testatomic$(EXE) testime$(EXE) +TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testatomic$(EXE) testaudioinfo$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcursor$(EXE) testdraw2$(EXE) testdyngles$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl2$(EXE) testgles$(EXE) testgl$(EXE) testhaptic$(EXE) testhread$(EXE) testiconv$(EXE) testime$(EXE) testintersections$(EXE) testjoystick$(EXE) testkeys$(EXE) testloadso$(EXE) testlock$(EXE) testmmousetablet$(EXE) testmultiaudio$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testpower$(EXE) testresample$(EXE) testsem$(EXE) testsprite2$(EXE) testsprite$(EXE) testspriteminimal$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm2$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE) all: Makefile $(TARGETS) @@ -107,6 +107,9 @@ testplatform$(EXE): $(srcdir)/testplatform.c testsem$(EXE): $(srcdir)/testsem.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) +testspriteminimal$(EXE): $(srcdir)/testspriteminimal.c + $(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@ + testsprite$(EXE): $(srcdir)/testsprite.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@ diff --git a/test/testspriteminimal.c b/test/testspriteminimal.c new file mode 100644 index 000000000..b1f6055fd --- /dev/null +++ b/test/testspriteminimal.c @@ -0,0 +1,165 @@ +/* Simple program: Move N sprites around on the screen as fast as possible */ + +#include +#include +#include + +#include "SDL_events.h" +#include "SDL_video.h" + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 +#define NUM_SPRITES 100 +#define MAX_SPEED 1 + +static SDL_TextureID sprite; +static SDL_Rect positions[NUM_SPRITES]; +static SDL_Rect velocities[NUM_SPRITES]; +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) +{ + exit(rc); +} + +int +LoadSprite(char *file) +{ + 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_TRUE, *(Uint8 *) temp->pixels); + } else { + switch (temp->format->BitsPerPixel) { + case 15: + SDL_SetColorKey(temp, SDL_TRUE, + (*(Uint16 *) temp->pixels) & 0x00007FFF); + break; + case 16: + SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); + break; + case 24: + SDL_SetColorKey(temp, SDL_TRUE, + (*(Uint32 *) temp->pixels) & 0x00FFFFFF); + break; + case 32: + SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); + break; + } + } + + /* Create textures from the image */ + sprite = SDL_CreateTextureFromSurface(0, temp); + if (!sprite) { + SDL_SetColorKey(temp, 0, 0); + sprite = SDL_CreateTextureFromSurface(0, temp); + } + if (!sprite) { + 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; + int window_w = WINDOW_WIDTH; + int window_h = WINDOW_HEIGHT; + SDL_Rect *position, *velocity; + + /* Draw a gray background */ + SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF); + SDL_RenderFill(NULL); + + /* Move the sprite, bounce at the wall, and draw */ + 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_h))) { + velocity->y = -velocity->y; + position->y += velocity->y; + } + + /* Blit the sprite onto the screen */ + SDL_RenderCopy(sprite, NULL, position); + } + + /* Update the screen! */ + SDL_RenderPresent(); +} + +int +main(int argc, char *argv[]) +{ + SDL_WindowID window; + int i, done; + SDL_Event event; + + window = SDL_CreateWindow("Happy Smileys", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + WINDOW_WIDTH, WINDOW_HEIGHT, + SDL_WINDOW_SHOWN); + if (!window) { + quit(2); + } + + if (LoadSprite("icon.bmp") < 0) { + quit(2); + } + + /* Initialize the sprite positions */ + srand(time(NULL)); + for (i = 0; i < NUM_SPRITES; ++i) { + positions[i].x = rand() % (WINDOW_WIDTH - sprite_w); + positions[i].y = rand() % (WINDOW_HEIGHT - 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; + } + } + + /* Main render loop */ + done = 0; + while (!done) { + /* Check for events */ + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT || event.type == SDL_KEYDOWN) { + done = 1; + } + } + MoveSprites(window, sprite); + } + + quit(0); +} + +/* vi: set ts=4 sw=4 expandtab: */