Mercurial > sdl-ios-xcode
changeset 1907:06c27a737b7a
Streamlined the API a bit and optimized the software renderer.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 15 Jul 2006 09:46:36 +0000 |
parents | 0c49855a7a3e |
children | e079dafea2bf |
files | include/SDL_video.h src/SDL_compat.c src/video/SDL_renderer_sw.c src/video/SDL_sysvideo.h src/video/SDL_video.c src/video/dummy/SDL_nullrender.c src/video/win32/SDL_d3drender.c src/video/win32/SDL_gdirender.c test/testsprite.c test/testsprite2.c |
diffstat | 10 files changed, 283 insertions(+), 558 deletions(-) [+] |
line wrap: on
line diff
--- a/include/SDL_video.h Fri Jul 14 08:24:43 2006 +0000 +++ b/include/SDL_video.h Sat Jul 15 09:46:36 2006 +0000 @@ -176,9 +176,7 @@ SDL_Renderer_PresentFlip3 = 0x00000008, /**< Present uses a flip, rotating between two back buffers and a front buffer */ SDL_Renderer_PresentDiscard = 0x00000010, /**< Present leaves the contents of the backbuffer undefined */ SDL_Renderer_PresentVSync = 0x00000020, /**< Present is synchronized with the refresh rate */ - SDL_Renderer_RenderTarget = 0x00000040, /**< The renderer can create texture render targets */ - SDL_Renderer_Accelerated = 0x00000080, /**< The renderer uses hardware acceleration */ - SDL_Renderer_Minimal = 0x00000100, /**< The renderer only supports the read/write pixel and present functions */ + SDL_Renderer_Accelerated = 0x00000040, /**< The renderer uses hardware acceleration */ } SDL_RendererFlags; /** @@ -193,7 +191,7 @@ Uint32 blend_modes; /**< A mask of supported blend modes */ Uint32 scale_modes; /**< A mask of supported scale modes */ Uint32 num_texture_formats; /**< The number of available texture formats */ - Uint32 texture_formats[32]; /**< The available texture formats */ + Uint32 texture_formats[16]; /**< The available texture formats */ int max_texture_width; /**< The maximimum texture width */ int max_texture_height; /**< The maximimum texture height */ } SDL_RendererInfo; @@ -205,9 +203,8 @@ */ typedef enum { - SDL_TextureAccess_Render, /**< Unlockable video memory, rendering allowed */ + SDL_TextureAccess_Local, /**< Lockable system memory */ SDL_TextureAccess_Remote, /**< Unlockable video memory */ - SDL_TextureAccess_Local, /**< Lockable system memory */ } SDL_TextureAccess; /** @@ -836,11 +833,16 @@ extern DECLSPEC int SDLCALL SDL_GetNumRenderers(void); /** - * \fn SDL_RendererInfo *SDL_GetRendererInfo(int index) + * \fn int SDL_GetRendererInfo(int index, SDL_RendererInfo *info) * * \brief Get information about a specific render manager on the current * display. * + * \param index The index to query information about, or -1 to query the currently renderer + * \param info A pointer to an SDL_RendererInfo struct to be filled with information on the renderer + * + * \return 0 on success, -1 if the index was out of range + * * \sa SDL_CreateRenderer() */ extern DECLSPEC int SDLCALL SDL_GetRendererInfo(int index,
--- a/src/SDL_compat.c Fri Jul 14 08:24:43 2006 +0000 +++ b/src/SDL_compat.c Sat Jul 15 09:46:36 2006 +0000 @@ -31,6 +31,7 @@ static SDL_WindowID SDL_VideoWindow; +static SDL_RendererInfo SDL_VideoRendererInfo; static SDL_TextureID SDL_VideoTexture; static SDL_Surface *SDL_VideoSurface; static SDL_Surface *SDL_ShadowSurface; @@ -442,10 +443,12 @@ } /* Create a renderer for the window */ - if (SDL_CreateRenderer(SDL_VideoWindow, -1, SDL_Renderer_SingleBuffer) < - 0) { + if (SDL_CreateRenderer + (SDL_VideoWindow, -1, + SDL_Renderer_SingleBuffer | SDL_Renderer_PresentDiscard) < 0) { return NULL; } + SDL_GetRendererInfo(-1, &SDL_VideoRendererInfo); /* Create a texture for the screen surface */ SDL_VideoTexture = @@ -642,8 +645,19 @@ screen = SDL_VideoSurface; } if (screen == SDL_VideoSurface) { - for (i = 0; i < numrects; ++i) { - SDL_RenderCopy(SDL_VideoTexture, &rects[i], &rects[i], + if (SDL_VideoRendererInfo.flags & SDL_Renderer_PresentCopy) { + for (i = 0; i < numrects; ++i) { + SDL_RenderCopy(SDL_VideoTexture, &rects[i], &rects[i], + SDL_TextureBlendMode_None, + SDL_TextureScaleMode_None); + } + } else { + SDL_Rect rect; + rect.x = 0; + rect.y = 0; + rect.w = screen->w; + rect.h = screen->h; + SDL_RenderCopy(SDL_VideoTexture, &rect, &rect, SDL_TextureBlendMode_None, SDL_TextureScaleMode_None); }
--- a/src/video/SDL_renderer_sw.c Fri Jul 14 08:24:43 2006 +0000 +++ b/src/video/SDL_renderer_sw.c Sat Jul 15 09:46:36 2006 +0000 @@ -23,6 +23,7 @@ #include "SDL_video.h" #include "SDL_sysvideo.h" +#include "SDL_pixels_c.h" #include "SDL_rect_c.h" #include "SDL_yuv_sw_c.h" @@ -53,20 +54,12 @@ static void SDL_SW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, const SDL_Rect * rects); -static void SDL_SW_SelectRenderTexture(SDL_Renderer * renderer, - SDL_Texture * texture); static int SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color); static int SDL_SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect, int blendMode, int scaleMode); -static int SDL_SW_RenderReadPixels(SDL_Renderer * renderer, - const SDL_Rect * rect, void *pixels, - int pitch); -static int SDL_SW_RenderWritePixels(SDL_Renderer * renderer, - const SDL_Rect * rect, const void *pixels, - int pitch); static void SDL_SW_RenderPresent(SDL_Renderer * renderer); static void SDL_SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); @@ -79,7 +72,7 @@ "software", (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | - SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), + SDL_Renderer_PresentDiscard | SDL_Renderer_PresentVSync), (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), @@ -102,14 +95,63 @@ typedef struct { - int current_screen; - SDL_Surface *screens[3]; - SDL_Surface *target; + Uint32 format; + int current_texture; + SDL_Texture *texture[3]; + SDL_Surface surface; SDL_Renderer *renderer; SDL_DirtyRectList dirty; - SDL_bool makedirty; } SDL_SW_RenderData; +static SDL_Texture * +CreateTexture(SDL_Renderer * renderer, Uint32 format, int w, int h) +{ + SDL_Texture *texture; + + texture = (SDL_Texture *) SDL_malloc(sizeof(*texture)); + if (!texture) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_zerop(texture); + texture->format = format; + texture->access = SDL_TextureAccess_Local; + texture->w = w; + texture->h = h; + texture->renderer = renderer; + + if (renderer->CreateTexture(renderer, texture) < 0) { + SDL_free(texture); + return NULL; + } + return texture; +} + +static void +DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + renderer->DestroyTexture(renderer, texture); + SDL_free(texture); +} + +static int +DisplayPaletteChanged(void *userdata, SDL_Palette * palette) +{ + SDL_SW_RenderData *data = (SDL_SW_RenderData *) userdata; + int i; + + for (i = 0; i < SDL_arraysize(data->texture); ++i) { + if (data->texture[i] && data->renderer->SetTexturePalette) { + data->renderer->SetTexturePalette(data->renderer, + data->texture[i], + palette->colors, 0, + palette->ncolors); + } + } + return 0; +} + SDL_Renderer * SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags) { @@ -120,6 +162,7 @@ int i, n; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; + Uint32 renderer_flags; if (!SDL_PixelFormatEnumToMasks (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { @@ -149,11 +192,8 @@ renderer->LockTexture = SDL_SW_LockTexture; renderer->UnlockTexture = SDL_SW_UnlockTexture; renderer->DirtyTexture = SDL_SW_DirtyTexture; - renderer->SelectRenderTexture = SDL_SW_SelectRenderTexture; renderer->RenderFill = SDL_SW_RenderFill; renderer->RenderCopy = SDL_SW_RenderCopy; - renderer->RenderReadPixels = SDL_SW_RenderReadPixels; - renderer->RenderWritePixels = SDL_SW_RenderWritePixels; renderer->RenderPresent = SDL_SW_RenderPresent; renderer->DestroyTexture = SDL_SW_DestroyTexture; renderer->DestroyRenderer = SDL_SW_DestroyRenderer; @@ -161,7 +201,7 @@ renderer->window = window->id; renderer->driverdata = data; - renderer->info.flags = SDL_Renderer_RenderTarget; + renderer->info.flags = 0; if (flags & SDL_Renderer_PresentFlip2) { renderer->info.flags |= SDL_Renderer_PresentFlip2; @@ -173,28 +213,18 @@ renderer->info.flags |= SDL_Renderer_PresentCopy; n = 1; } - for (i = 0; i < n; ++i) { - data->screens[i] = - SDL_CreateRGBSurface(0, window->w, window->h, bpp, Rmask, Gmask, - Bmask, Amask); - if (!data->screens[i]) { - SDL_SW_DestroyRenderer(renderer); - return NULL; - } - SDL_SetSurfacePalette(data->screens[i], display->palette); - } - data->current_screen = 0; - data->target = data->screens[0]; - data->makedirty = SDL_TRUE; + data->format = displayMode->format; /* Find a render driver that we can use to display data */ + renderer_flags = (SDL_Renderer_SingleBuffer | + SDL_Renderer_PresentDiscard); + if (flags & SDL_Renderer_PresentVSync) { + renderer_flags |= SDL_Renderer_PresentVSync; + } 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_SingleBuffer | - SDL_Renderer_PresentDiscard)); + data->renderer = driver->CreateRenderer(window, renderer_flags); if (data->renderer) { break; } @@ -205,6 +235,35 @@ SDL_SetError("Couldn't find display render driver"); return NULL; } + if (data->renderer->info.flags & SDL_Renderer_PresentVSync) { + renderer->info.flags |= SDL_Renderer_PresentVSync; + } + + /* Create the textures we'll use for display */ + for (i = 0; i < n; ++i) { + data->texture[i] = + CreateTexture(data->renderer, data->format, window->w, window->h); + if (!data->texture[i]) { + SDL_SW_DestroyRenderer(renderer); + return NULL; + } + } + data->current_texture = 0; + + /* Create a surface we'll use for rendering */ + data->surface.flags = SDL_PREALLOC; + data->surface.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); + if (!data->surface.format) { + SDL_SW_DestroyRenderer(renderer); + return NULL; + } + SDL_SetSurfacePalette(&data->surface, display->palette); + + /* Set up a palette watch on the display palette */ + if (display->palette) { + SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data); + } + return renderer; } @@ -212,10 +271,6 @@ SDL_SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { - if (texture->access == SDL_TextureAccess_Render) { - SDL_SetError("Rendering to YUV format textures is not supported"); - return -1; - } texture->driverdata = SDL_SW_CreateYUVTexture(texture); } else { int bpp; @@ -347,29 +402,18 @@ { } -static void -SDL_SW_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; - - if (texture) { - data->target = (SDL_Surface *) texture->driverdata; - data->makedirty = SDL_FALSE; - } else { - data->target = data->screens[data->current_screen]; - data->makedirty = SDL_TRUE; - } -} - static int SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color) { SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; - SDL_Rect real_rect = *rect; Uint8 r, g, b, a; + void *pixels; + int pitch; + SDL_Rect real_rect; + int status; - if (data->makedirty) { + if (data->renderer->info.flags & SDL_Renderer_PresentCopy) { SDL_AddDirtyRect(&data->dirty, rect); } @@ -377,9 +421,25 @@ r = (Uint8) ((color >> 16) & 0xFF); g = (Uint8) ((color >> 8) & 0xFF); b = (Uint8) (color & 0xFF); - color = SDL_MapRGBA(data->target->format, r, g, b, a); + color = SDL_MapRGBA(data->surface.format, r, g, b, a); - return SDL_FillRect(data->target, &real_rect, color); + if (data->renderer-> + LockTexture(data->renderer, data->texture[data->current_texture], + rect, 1, &data->surface.pixels, + &data->surface.pitch) < 0) { + return -1; + } + data->surface.w = rect->w; + data->surface.h = rect->h; + data->surface.clip_rect.w = rect->w; + data->surface.clip_rect.h = rect->h; + real_rect = data->surface.clip_rect; + + status = SDL_FillRect(&data->surface, &real_rect, color); + + data->renderer->UnlockTexture(data->renderer, + data->texture[data->current_texture]); + return status; } static int @@ -389,25 +449,34 @@ { SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; SDL_Window *window = SDL_GetWindowFromID(renderer->window); - SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); + int status; + + if (data->renderer->info.flags & SDL_Renderer_PresentCopy) { + SDL_AddDirtyRect(&data->dirty, dstrect); + } - if (data->makedirty) { - SDL_AddDirtyRect(&data->dirty, dstrect); + if (data->renderer-> + LockTexture(data->renderer, data->texture[data->current_texture], + dstrect, 1, &data->surface.pixels, + &data->surface.pitch) < 0) { + return -1; } if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { - SDL_Surface *target = data->target; - void *pixels = - (Uint8 *) target->pixels + dstrect->y * target->pitch + - dstrect->x * target->format->BytesPerPixel; - return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata, - srcrect, display->current_mode.format, - dstrect->w, dstrect->h, pixels, - target->pitch); + status = + SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata, + srcrect, data->format, dstrect->w, dstrect->h, + data->surface.pixels, data->surface.pitch); } else { SDL_Surface *surface = (SDL_Surface *) texture->driverdata; SDL_Rect real_srcrect = *srcrect; - SDL_Rect real_dstrect = *dstrect; + SDL_Rect real_dstrect; + + data->surface.w = dstrect->w; + data->surface.h = dstrect->h; + data->surface.clip_rect.w = dstrect->w; + data->surface.clip_rect.h = dstrect->h; + real_dstrect = data->surface.clip_rect; if (blendMode & (SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend)) { @@ -417,91 +486,53 @@ } if (scaleMode != SDL_TextureScaleMode_None && (srcrect->w != dstrect->w || srcrect->h != dstrect->h)) { - return SDL_SoftStretch(surface, &real_srcrect, data->target, - &real_dstrect); + status = + SDL_SoftStretch(surface, &real_srcrect, &data->surface, + &real_dstrect); } else { - return SDL_LowerBlit(surface, &real_srcrect, data->target, - &real_dstrect); + status = + SDL_LowerBlit(surface, &real_srcrect, &data->surface, + &real_dstrect); } } -} - -static int -SDL_SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - void *pixels, int pitch) -{ - SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; - SDL_Surface *surface = data->target; - Uint8 *src, *dst; - int row; - size_t length; - - src = - (Uint8 *) surface->pixels + rect->y * surface->pitch + - rect->x * surface->format->BytesPerPixel; - dst = (Uint8 *) pixels; - length = rect->w * surface->format->BytesPerPixel; - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += surface->pitch; - dst += pitch; - } - return 0; -} - -static int -SDL_SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, - const void *pixels, int pitch) -{ - SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; - SDL_Surface *surface = data->target; - Uint8 *src, *dst; - int row; - size_t length; - - if (data->makedirty) { - SDL_AddDirtyRect(&data->dirty, rect); - } - - src = (Uint8 *) pixels; - dst = - (Uint8 *) surface->pixels + rect->y * surface->pitch + - rect->x * surface->format->BytesPerPixel; - length = rect->w * surface->format->BytesPerPixel; - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += pitch; - dst += surface->pitch; - } - return 0; + data->renderer->UnlockTexture(data->renderer, + data->texture[data->current_texture]); + return status; } static void SDL_SW_RenderPresent(SDL_Renderer * renderer) { SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; - SDL_Surface *surface = data->screens[data->current_screen]; - SDL_DirtyRect *dirty; + SDL_Texture *texture = data->texture[data->current_texture]; /* Send the data to the display */ - for (dirty = data->dirty.list; dirty; dirty = dirty->next) { - void *pixels = - (void *) ((Uint8 *) surface->pixels + - dirty->rect.y * surface->pitch + - dirty->rect.x * surface->format->BytesPerPixel); - data->renderer->RenderWritePixels(data->renderer, &dirty->rect, - pixels, surface->pitch); + if (data->renderer->info.flags & SDL_Renderer_PresentCopy) { + SDL_DirtyRect *dirty; + for (dirty = data->dirty.list; dirty; dirty = dirty->next) { + data->renderer->RenderCopy(data->renderer, texture, &dirty->rect, + &dirty->rect, + SDL_TextureBlendMode_None, + SDL_TextureScaleMode_None); + } + SDL_ClearDirtyRects(&data->dirty); + } else { + SDL_Rect rect; + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + data->renderer->RenderCopy(data->renderer, texture, &rect, &rect, + SDL_TextureBlendMode_None, + SDL_TextureScaleMode_None); } - SDL_ClearDirtyRects(&data->dirty); data->renderer->RenderPresent(data->renderer); /* Update the flipping chain, if any */ if (renderer->info.flags & SDL_Renderer_PresentFlip2) { - data->current_screen = (data->current_screen + 1) % 2; - data->target = data->screens[data->current_screen]; + data->current_texture = (data->current_texture + 1) % 2; } else if (renderer->info.flags & SDL_Renderer_PresentFlip3) { - data->current_screen = (data->current_screen + 1) % 3; - data->target = data->screens[data->current_screen]; + data->current_texture = (data->current_texture + 1) % 3; } } @@ -521,14 +552,27 @@ SDL_SW_DestroyRenderer(SDL_Renderer * renderer) { SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; + SDL_Window *window = SDL_GetWindowFromID(renderer->window); + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); int i; if (data) { - for (i = 0; i < SDL_arraysize(data->screens); ++i) { - if (data->screens[i]) { - SDL_FreeSurface(data->screens[i]); + for (i = 0; i < SDL_arraysize(data->texture); ++i) { + if (data->texture[i]) { + DestroyTexture(data->renderer, data->texture[i]); } } + if (data->surface.format) { + SDL_SetSurfacePalette(&data->surface, NULL); + SDL_FreeFormat(data->surface.format); + } + if (display->palette) { + SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, + data); + } + if (data->renderer) { + data->renderer->DestroyRenderer(data->renderer); + } SDL_FreeDirtyRects(&data->dirty); SDL_free(data); }
--- a/src/video/SDL_sysvideo.h Fri Jul 14 08:24:43 2006 +0000 +++ b/src/video/SDL_sysvideo.h Sat Jul 15 09:46:36 2006 +0000 @@ -73,17 +73,11 @@ void (*UnlockTexture) (SDL_Renderer * renderer, SDL_Texture * texture); void (*DirtyTexture) (SDL_Renderer * renderer, SDL_Texture * texture, int numrects, const SDL_Rect * rects); - void (*SelectRenderTexture) (SDL_Renderer * renderer, - SDL_Texture * texture); int (*RenderFill) (SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color); int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect, int blendMode, int scaleMode); - int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect, - void *pixels, int pitch); - int (*RenderWritePixels) (SDL_Renderer * renderer, const SDL_Rect * rect, - const void *pixels, int pitch); void (*RenderPresent) (SDL_Renderer * renderer); void (*DestroyTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
--- a/src/video/SDL_video.c Fri Jul 14 08:24:43 2006 +0000 +++ b/src/video/SDL_video.c Sat Jul 15 09:46:36 2006 +0000 @@ -1277,12 +1277,24 @@ int SDL_GetRendererInfo(int index, SDL_RendererInfo * info) { - if (index < 0 || index >= SDL_GetNumRenderers()) { + if (!_this) { + return -1; + } + + if (index >= SDL_GetNumRenderers()) { SDL_SetError("index must be in the range of 0 - %d", SDL_GetNumRenderers() - 1); return -1; } - *info = SDL_CurrentDisplay.render_drivers[index].info; + if (index < 0) { + if (!SDL_CurrentDisplay.current_renderer) { + SDL_SetError("There is no current renderer"); + return -1; + } + *info = SDL_CurrentDisplay.current_renderer->info; + } else { + *info = SDL_CurrentDisplay.render_drivers[index].info; + } return 0; } @@ -1307,11 +1319,6 @@ break; } } else { - /* Skip minimal drivers in automatic scans */ - if (!(flags & SDL_Renderer_Minimal) - && (driver->info.flags & SDL_Renderer_Minimal)) { - continue; - } if ((driver->info.flags & flags) == flags) { break; } @@ -1734,22 +1741,6 @@ renderer->DirtyTexture(renderer, texture, numrects, rects); } -void -SDL_SelectRenderTexture(SDL_TextureID textureID) -{ - SDL_Texture *texture = SDL_GetTextureFromID(textureID); - SDL_Renderer *renderer; - - if (!texture || texture->access != SDL_TextureAccess_Render) { - return; - } - renderer = texture->renderer; - if (!renderer->SelectRenderTexture) { - return; - } - renderer->SelectRenderTexture(renderer, texture); -} - int SDL_RenderFill(const SDL_Rect * rect, Uint32 color) { @@ -1821,60 +1812,6 @@ &real_dstrect, blendMode, scaleMode); } -int -SDL_RenderReadPixels(const SDL_Rect * rect, void *pixels, int pitch) -{ - SDL_Renderer *renderer; - SDL_Rect full_rect; - - if (!_this) { - return -1; - } - - renderer = SDL_CurrentDisplay.current_renderer; - if (!renderer || !renderer->RenderReadPixels) { - return -1; - } - - if (!rect) { - SDL_Window *window = SDL_GetWindowFromID(renderer->window); - full_rect.x = 0; - full_rect.y = 0; - full_rect.w = window->w; - full_rect.h = window->h; - rect = &full_rect; - } - - return renderer->RenderReadPixels(renderer, rect, pixels, pitch); -} - -int -SDL_RenderWritePixels(const SDL_Rect * rect, const void *pixels, int pitch) -{ - SDL_Renderer *renderer; - SDL_Rect full_rect; - - if (!_this) { - return -1; - } - - renderer = SDL_CurrentDisplay.current_renderer; - if (!renderer || !renderer->RenderWritePixels) { - return -1; - } - - if (!rect) { - SDL_Window *window = SDL_GetWindowFromID(renderer->window); - full_rect.x = 0; - full_rect.y = 0; - full_rect.w = window->w; - full_rect.h = window->h; - rect = &full_rect; - } - - return renderer->RenderWritePixels(renderer, rect, pixels, pitch); -} - void SDL_RenderPresent(void) { @@ -1888,10 +1825,6 @@ if (!renderer || !renderer->RenderPresent) { return; } - - if (renderer->SelectRenderTexture) { - renderer->SelectRenderTexture(renderer, NULL); - } renderer->RenderPresent(renderer); }
--- a/src/video/dummy/SDL_nullrender.c Fri Jul 14 08:24:43 2006 +0000 +++ b/src/video/dummy/SDL_nullrender.c Sat Jul 15 09:46:36 2006 +0000 @@ -31,12 +31,6 @@ Uint32 flags); static int SDL_DUMMY_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); -static int SDL_DUMMY_RenderReadPixels(SDL_Renderer * renderer, - const SDL_Rect * rect, void *pixels, - int pitch); -static int SDL_DUMMY_RenderWritePixels(SDL_Renderer * renderer, - const SDL_Rect * rect, - const void *pixels, int pitch); static void SDL_DUMMY_RenderPresent(SDL_Renderer * renderer); static void SDL_DUMMY_DestroyRenderer(SDL_Renderer * renderer); @@ -45,8 +39,7 @@ SDL_DUMMY_CreateRenderer, { "dummy", - (SDL_Renderer_Minimal | SDL_Renderer_PresentDiscard | - SDL_Renderer_PresentCopy), + (SDL_Renderer_PresentDiscard | SDL_Renderer_PresentCopy), SDL_TextureBlendMode_None, SDL_TextureScaleMode_None, 0, @@ -91,8 +84,6 @@ } SDL_zerop(data); - renderer->RenderReadPixels = SDL_DUMMY_RenderReadPixels; - renderer->RenderWritePixels = SDL_DUMMY_RenderWritePixels; renderer->RenderPresent = SDL_DUMMY_RenderPresent; renderer->DestroyRenderer = SDL_DUMMY_DestroyRenderer; renderer->info = SDL_DUMMY_RenderDriver.info; @@ -111,54 +102,6 @@ return renderer; } -int -SDL_DUMMY_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - void *pixels, int pitch) -{ - SDL_DUMMY_RenderData *data = - (SDL_DUMMY_RenderData *) renderer->driverdata; - SDL_Surface *surface = data->surface; - Uint8 *src, *dst; - int row; - size_t length; - - src = - (Uint8 *) surface->pixels + rect->y * surface->pitch + - rect->x * surface->format->BytesPerPixel; - dst = (Uint8 *) pixels; - length = rect->w * surface->format->BytesPerPixel; - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += surface->pitch; - dst += pitch; - } - return 0; -} - -int -SDL_DUMMY_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, - const void *pixels, int pitch) -{ - SDL_DUMMY_RenderData *data = - (SDL_DUMMY_RenderData *) renderer->driverdata; - SDL_Surface *surface = data->surface; - Uint8 *src, *dst; - int row; - size_t length; - - src = (Uint8 *) pixels; - dst = - (Uint8 *) surface->pixels + rect->y * surface->pitch + - rect->x * surface->format->BytesPerPixel; - length = rect->w * surface->format->BytesPerPixel; - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += pitch; - dst += surface->pitch; - } - return 0; -} - void SDL_DUMMY_RenderPresent(SDL_Renderer * renderer) {
--- a/src/video/win32/SDL_d3drender.c Fri Jul 14 08:24:43 2006 +0000 +++ b/src/video/win32/SDL_d3drender.c Sat Jul 15 09:46:36 2006 +0000 @@ -50,20 +50,12 @@ static void SDL_D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, const SDL_Rect * rects); -static void SDL_D3D_SelectRenderTexture(SDL_Renderer * renderer, - SDL_Texture * texture); static int SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color); static int SDL_D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect, int blendMode, int scaleMode); -static int SDL_D3D_RenderReadPixels(SDL_Renderer * renderer, - const SDL_Rect * rect, void *pixels, - int pitch); -static int SDL_D3D_RenderWritePixels(SDL_Renderer * renderer, - const SDL_Rect * rect, - const void *pixels, int pitch); static void SDL_D3D_RenderPresent(SDL_Renderer * renderer); static void SDL_D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); @@ -76,10 +68,9 @@ "d3d", (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | - SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), - (SDL_TextureBlendMode_None | - SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), - (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), + SDL_Renderer_PresentDiscard | SDL_Renderer_PresentVSync), + (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), /* FIXME */ + (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), /* FIXME */ 12, { SDL_PixelFormat_Index8, @@ -101,8 +92,6 @@ typedef struct { IDirect3DDevice9 *device; - IDirect3DSurface9 *surface; - IDirect3DSurface9 *offscreen; SDL_bool beginScene; } SDL_D3D_RenderData; @@ -250,6 +239,7 @@ SDL_D3D_RenderData *data; HRESULT result; D3DPRESENT_PARAMETERS pparams; + IDirect3DSwapChain9 *chain; renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer)); if (!renderer) { @@ -273,11 +263,8 @@ renderer->LockTexture = SDL_D3D_LockTexture; renderer->UnlockTexture = SDL_D3D_UnlockTexture; renderer->DirtyTexture = SDL_D3D_DirtyTexture; - renderer->SelectRenderTexture = SDL_D3D_SelectRenderTexture; renderer->RenderFill = SDL_D3D_RenderFill; renderer->RenderCopy = SDL_D3D_RenderCopy; - renderer->RenderReadPixels = SDL_D3D_RenderReadPixels; - renderer->RenderWritePixels = SDL_D3D_RenderWritePixels; renderer->RenderPresent = SDL_D3D_RenderPresent; renderer->DestroyTexture = SDL_D3D_DestroyTexture; renderer->DestroyRenderer = SDL_D3D_DestroyRenderer; @@ -285,7 +272,7 @@ renderer->window = window->id; renderer->driverdata = data; - renderer->info.flags = SDL_Renderer_RenderTarget; + renderer->info.flags = SDL_Renderer_Accelerated; SDL_zero(pparams); pparams.BackBufferWidth = window->w; @@ -317,7 +304,11 @@ pparams.Windowed = TRUE; pparams.FullScreen_RefreshRateInHz = 0; } - pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + if (flags & SDL_Renderer_PresentVSync) { + pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } else { + pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT, /* FIXME */ D3DDEVTYPE_HAL, @@ -331,6 +322,43 @@ } data->beginScene = SDL_TRUE; + /* Get presentation parameters to fill info */ + result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); + if (FAILED(result)) { + SDL_D3D_DestroyRenderer(renderer); + D3D_SetError("GetSwapChain()", result); + return NULL; + } + result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); + if (FAILED(result)) { + IDirect3DSwapChain9_Release(chain); + SDL_D3D_DestroyRenderer(renderer); + D3D_SetError("GetPresentParameters()", result); + return NULL; + } + IDirect3DSwapChain9_Release(chain); + switch (pparams.SwapEffect) { + case D3DSWAPEFFECT_COPY: + renderer->info.flags |= SDL_Renderer_PresentCopy; + break; + case D3DSWAPEFFECT_FLIP: + switch (pparams.BackBufferCount) { + case 2: + renderer->info.flags |= SDL_Renderer_PresentFlip2; + break; + case 3: + renderer->info.flags |= SDL_Renderer_PresentFlip3; + break; + } + break; + case D3DSWAPEFFECT_DISCARD: + renderer->info.flags |= SDL_Renderer_PresentDiscard; + break; + } + if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { + renderer->info.flags |= SDL_Renderer_PresentVSync; + } + /* Set up parameters for rendering */ IDirect3DDevice9_SetVertexShader(data->device, NULL); IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZRHW | D3DFVF_TEX1); @@ -527,14 +555,6 @@ } } -static void -SDL_D3D_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; - - /* FIXME */ -} - static int SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color) @@ -637,93 +657,6 @@ return 0; } -static int -SDL_D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - void *pixels, int pitch) -{ - SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; - - /* FIXME */ - return 0; -} - -static int -SDL_D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, - const void *pixels, int pitch) -{ - SDL_Window *window = SDL_GetWindowFromID(renderer->window); - SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; - RECT d3drect; - POINT point; - D3DLOCKED_RECT locked; - const Uint8 *src; - Uint8 *dst; - int row, length; - HRESULT result; - - if (!data->surface) { - result = - IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, - D3DBACKBUFFER_TYPE_MONO, - &data->surface); - if (FAILED(result)) { - D3D_SetError("GetBackBuffer()", result); - return -1; - } - } - if (!data->offscreen) { - result = - IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, - window->w, window->h, - PixelFormatToD3DFMT - (display-> - current_mode. - format), - D3DPOOL_SYSTEMMEM, - &data->offscreen, - NULL); - if (FAILED(result)) { - D3D_SetError("CreateOffscreenPlainSurface()", result); - return -1; - } - } - - d3drect.left = rect->x; - d3drect.right = rect->x + rect->w; - d3drect.top = rect->y; - d3drect.bottom = rect->y + rect->h; - - result = - IDirect3DSurface9_LockRect(data->offscreen, &locked, &d3drect, 0); - if (FAILED(result)) { - D3D_SetError("LockRect()", result); - return -1; - } - - src = pixels; - dst = locked.pBits; - length = rect->w * SDL_BYTESPERPIXEL(display->current_mode.format); - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += pitch; - dst += locked.Pitch; - } - IDirect3DSurface9_UnlockRect(data->offscreen); - - point.x = rect->x; - point.y = rect->y; - result = - IDirect3DDevice9_UpdateSurface(data->device, data->offscreen, - &d3drect, data->surface, &point); - if (FAILED(result)) { - D3D_SetError("UpdateSurface()", result); - return -1; - } - - return 0; -} - static void SDL_D3D_RenderPresent(SDL_Renderer * renderer) { @@ -765,12 +698,6 @@ if (data->device) { IDirect3DDevice9_Release(data->device); } - if (data->surface) { - IDirect3DSurface9_Release(data->surface); - } - if (data->offscreen) { - IDirect3DSurface9_Release(data->offscreen); - } SDL_free(data); } SDL_free(renderer);
--- a/src/video/win32/SDL_gdirender.c Fri Jul 14 08:24:43 2006 +0000 +++ b/src/video/win32/SDL_gdirender.c Sat Jul 15 09:46:36 2006 +0000 @@ -55,20 +55,12 @@ static void SDL_GDI_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, const SDL_Rect * rects); -static void SDL_GDI_SelectRenderTexture(SDL_Renderer * renderer, - SDL_Texture * texture); static int SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color); static int SDL_GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect, int blendMode, int scaleMode); -static int SDL_GDI_RenderReadPixels(SDL_Renderer * renderer, - const SDL_Rect * rect, void *pixels, - int pitch); -static int SDL_GDI_RenderWritePixels(SDL_Renderer * renderer, - const SDL_Rect * rect, - const void *pixels, int pitch); static void SDL_GDI_RenderPresent(SDL_Renderer * renderer); static void SDL_GDI_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); @@ -81,7 +73,7 @@ "gdi", (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | - SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), + SDL_Renderer_PresentDiscard), (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), @@ -114,9 +106,6 @@ int current_hbm; SDL_DirtyRectList dirty; SDL_bool makedirty; - HBITMAP window_dib; - void *window_pixels; - int window_pitch; } SDL_GDI_RenderData; typedef struct @@ -182,11 +171,8 @@ renderer->LockTexture = SDL_GDI_LockTexture; renderer->UnlockTexture = SDL_GDI_UnlockTexture; renderer->DirtyTexture = SDL_GDI_DirtyTexture; - renderer->SelectRenderTexture = SDL_GDI_SelectRenderTexture; renderer->RenderFill = SDL_GDI_RenderFill; renderer->RenderCopy = SDL_GDI_RenderCopy; - renderer->RenderReadPixels = SDL_GDI_RenderReadPixels; - renderer->RenderWritePixels = SDL_GDI_RenderWritePixels; renderer->RenderPresent = SDL_GDI_RenderPresent; renderer->DestroyTexture = SDL_GDI_DestroyTexture; renderer->DestroyRenderer = SDL_GDI_DestroyRenderer; @@ -194,7 +180,7 @@ renderer->window = window->id; renderer->driverdata = data; - renderer->info.flags = SDL_Renderer_RenderTarget; + renderer->info.flags = SDL_Renderer_Accelerated; data->hwnd = windowdata->hwnd; data->window_hdc = GetDC(data->hwnd); @@ -218,7 +204,8 @@ DeleteObject(hbm); if (flags & SDL_Renderer_SingleBuffer) { - renderer->info.flags |= SDL_Renderer_SingleBuffer; + renderer->info.flags |= + (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy); n = 0; } else if (flags & SDL_Renderer_PresentFlip2) { renderer->info.flags |= SDL_Renderer_PresentFlip2; @@ -271,10 +258,6 @@ texture->driverdata = data; if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { - if (texture->access == SDL_TextureAccess_Render) { - SDL_SetError("Rendering to YUV format textures is not supported"); - return -1; - } data->yuv = SDL_SW_CreateYUVTexture(texture); if (!data->yuv) { SDL_GDI_DestroyTexture(renderer, texture); @@ -521,31 +504,6 @@ { } -static void -SDL_GDI_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata; - - if (texture) { - SDL_GDI_TextureData *texturedata = - (SDL_GDI_TextureData *) texture->driverdata; - SelectObject(data->render_hdc, texturedata->hbm); - if (texturedata->hpal) { - SelectPalette(data->render_hdc, texturedata->hpal, TRUE); - RealizePalette(data->render_hdc); - } - data->current_hdc = data->render_hdc; - data->makedirty = SDL_FALSE; - } else if (renderer->info.flags & SDL_Renderer_SingleBuffer) { - data->current_hdc = data->window_hdc; - data->makedirty = SDL_FALSE; - } else { - SelectObject(data->render_hdc, data->hbm[data->current_hbm]); - data->current_hdc = data->render_hdc; - data->makedirty = SDL_TRUE; - } -} - static int SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color) @@ -637,98 +595,6 @@ return 0; } -static int -CreateWindowDIB(SDL_GDI_RenderData * data, SDL_Window * window) -{ - data->window_pitch = window->w * (data->bmi->bmiHeader.biBitCount / 8); - data->bmi->bmiHeader.biWidth = window->w; - data->bmi->bmiHeader.biHeight = -window->h; - data->bmi->bmiHeader.biSizeImage = - window->h * (data->bmi->bmiHeader.biBitCount / 8); - data->window_dib = - CreateDIBSection(data->window_hdc, data->bmi, DIB_RGB_COLORS, - &data->window_pixels, NULL, 0); - if (!data->window_dib) { - WIN_SetError("CreateDIBSection()"); - return -1; - } - return 0; -} - -static int -SDL_GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - void *pixels, int pitch) -{ - SDL_Window *window = SDL_GetWindowFromID(renderer->window); - SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata; - - if (!data->window_dib) { - if (CreateWindowDIB(data, window) < 0) { - return -1; - } - } - - SelectObject(data->memory_hdc, data->window_dib); - BitBlt(data->memory_hdc, rect->x, rect->y, rect->w, rect->h, - data->current_hdc, rect->x, rect->y, SRCCOPY); - - { - int bpp = data->bmi->bmiHeader.biBitCount / 8; - Uint8 *src = - (Uint8 *) data->window_pixels + rect->y * data->window_pitch + - rect->x * bpp; - Uint8 *dst = (Uint8 *) pixels; - int row; - - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, rect->w * bpp); - src += data->window_pitch; - dst += pitch; - } - } - - return 0; -} - -static int -SDL_GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, - const void *pixels, int pitch) -{ - SDL_Window *window = SDL_GetWindowFromID(renderer->window); - SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata; - - if (data->makedirty) { - SDL_AddDirtyRect(&data->dirty, rect); - } - - if (!data->window_dib) { - if (CreateWindowDIB(data, window) < 0) { - return -1; - } - } - - { - int bpp = data->bmi->bmiHeader.biBitCount / 8; - Uint8 *src = (Uint8 *) pixels; - Uint8 *dst = - (Uint8 *) data->window_pixels + rect->y * data->window_pitch + - rect->x * bpp; - int row; - - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, rect->w * bpp); - src += pitch; - dst += data->window_pitch; - } - } - - SelectObject(data->memory_hdc, data->window_dib); - BitBlt(data->current_hdc, rect->x, rect->y, rect->w, rect->h, - data->memory_hdc, rect->x, rect->y, SRCCOPY); - - return 0; -} - static void SDL_GDI_RenderPresent(SDL_Renderer * renderer) { @@ -795,9 +661,6 @@ } } SDL_FreeDirtyRects(&data->dirty); - if (data->window_dib) { - DeleteObject(data->window_dib); - } SDL_free(data); } SDL_free(renderer);
--- a/test/testsprite.c Fri Jul 14 08:24:43 2006 +0000 +++ b/test/testsprite.c Sat Jul 15 09:46:36 2006 +0000 @@ -1,6 +1,7 @@ /* Simple program: Move N sprites around on the screen as fast as possible */ #include <stdlib.h> +#include <stdio.h> #include <time.h> #include "SDL.h"
--- a/test/testsprite2.c Fri Jul 14 08:24:43 2006 +0000 +++ b/test/testsprite2.c Sat Jul 15 09:46:36 2006 +0000 @@ -1,6 +1,7 @@ /* Simple program: Move N sprites around on the screen as fast as possible */ #include <stdlib.h> +#include <stdio.h> #include <time.h> #include "SDL.h" @@ -126,6 +127,7 @@ { int window_w, window_h; Uint32 window_flags = SDL_WINDOW_SHOWN; + Uint32 render_flags = 0; SDL_DisplayMode *mode, fullscreen_mode; int i, done; SDL_Event event; @@ -152,11 +154,13 @@ } else if (strcmp(argv[i], "-fullscreen") == 0) { num_windows = 1; window_flags |= SDL_WINDOW_FULLSCREEN; + } else if (strcmp(argv[i], "-sync") == 0) { + render_flags |= SDL_Renderer_PresentVSync; } else if (isdigit(argv[i][0])) { num_sprites = atoi(argv[i]); } else { fprintf(stderr, - "Usage: %s [-width N] [-height N] [-windows N] [-fullscreen] [numsprites]\n", + "Usage: %s [-width N] [-height N] [-windows N] [-fullscreen] [-sync] [numsprites]\n", argv[0]); quit(1); } @@ -189,7 +193,7 @@ quit(2); } - if (SDL_CreateRenderer(windows[i], -1, 0) < 0) { + if (SDL_CreateRenderer(windows[i], -1, render_flags) < 0) { fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError()); quit(2); }