Mercurial > sdl-ios-xcode
comparison src/video/SDL_video.c @ 5157:fb424691cfc7
Moved the rendering code out to a separate directory in the hope that it can someday be completely decoupled from the rest of the library and be expanded to an awesome 2D on 3D library.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 02 Feb 2011 14:34:54 -0800 |
parents | 1435f8a6425c |
children | 2b1989f59674 |
comparison
equal
deleted
inserted
replaced
5156:3e4086b3bcd2 | 5157:fb424691cfc7 |
---|---|
26 #include "SDL.h" | 26 #include "SDL.h" |
27 #include "SDL_video.h" | 27 #include "SDL_video.h" |
28 #include "SDL_sysvideo.h" | 28 #include "SDL_sysvideo.h" |
29 #include "SDL_blit.h" | 29 #include "SDL_blit.h" |
30 #include "SDL_pixels_c.h" | 30 #include "SDL_pixels_c.h" |
31 #include "SDL_renderer_gl.h" | |
32 #include "SDL_renderer_gles.h" | |
33 #include "SDL_renderer_sw.h" | |
34 #include "../events/SDL_events_c.h" | 31 #include "../events/SDL_events_c.h" |
35 | |
36 #if SDL_VIDEO_DRIVER_WINDOWS | |
37 #include "windows/SDL_windowsvideo.h" | |
38 extern void IME_Present(SDL_VideoData *videodata); | |
39 #endif | |
40 | 32 |
41 #if SDL_VIDEO_OPENGL_ES | 33 #if SDL_VIDEO_OPENGL_ES |
42 #include "SDL_opengles.h" | 34 #include "SDL_opengles.h" |
43 #endif /* SDL_VIDEO_OPENGL_ES */ | 35 #endif /* SDL_VIDEO_OPENGL_ES */ |
44 | 36 |
98 if (!window || window->magic != &_this->window_magic) { \ | 90 if (!window || window->magic != &_this->window_magic) { \ |
99 SDL_SetError("Invalid window"); \ | 91 SDL_SetError("Invalid window"); \ |
100 return retval; \ | 92 return retval; \ |
101 } | 93 } |
102 | 94 |
103 #define CHECK_RENDERER_MAGIC(renderer, retval) \ | |
104 if (!renderer || renderer->magic != &_this->renderer_magic) { \ | |
105 SDL_SetError("Invalid renderer"); \ | |
106 return retval; \ | |
107 } | |
108 | |
109 #define CHECK_TEXTURE_MAGIC(texture, retval) \ | |
110 if (!_this) { \ | |
111 SDL_UninitializedVideo(); \ | |
112 return retval; \ | |
113 } \ | |
114 if (!texture || texture->magic != &_this->texture_magic) { \ | |
115 SDL_SetError("Invalid texture"); \ | |
116 return retval; \ | |
117 } | |
118 | |
119 /* Various local functions */ | 95 /* Various local functions */ |
120 static void SDL_UpdateWindowGrab(SDL_Window * window); | 96 static void SDL_UpdateWindowGrab(SDL_Window * window); |
121 | 97 |
122 static int | 98 static int |
123 cmpmodes(const void *A, const void *B) | 99 cmpmodes(const void *A, const void *B) |
256 if (_this->num_displays == 0) { | 232 if (_this->num_displays == 0) { |
257 SDL_SetError("The video driver did not add any displays"); | 233 SDL_SetError("The video driver did not add any displays"); |
258 SDL_VideoQuit(); | 234 SDL_VideoQuit(); |
259 return (-1); | 235 return (-1); |
260 } | 236 } |
261 /* The software renderer is always available */ | |
262 for (i = 0; i < _this->num_displays; ++i) { | |
263 SDL_VideoDisplay *display = &_this->displays[i]; | |
264 if (_this->GL_CreateContext) { | |
265 #if SDL_VIDEO_RENDER_OGL | |
266 SDL_AddRenderDriver(display, &GL_RenderDriver); | |
267 #endif | |
268 #if SDL_VIDEO_RENDER_OGL_ES | |
269 SDL_AddRenderDriver(display, &GL_ES_RenderDriver); | |
270 #endif | |
271 } | |
272 if (display->num_render_drivers > 0) { | |
273 SDL_AddRenderDriver(display, &SW_RenderDriver); | |
274 } | |
275 } | |
276 | 237 |
277 /* We're ready to go! */ | 238 /* We're ready to go! */ |
278 return 0; | 239 return 0; |
279 } | 240 } |
280 | 241 |
721 *mode = fullscreen_mode; | 682 *mode = fullscreen_mode; |
722 } | 683 } |
723 return 0; | 684 return 0; |
724 } | 685 } |
725 | 686 |
687 Uint32 | |
688 SDL_GetWindowPixelFormat(SDL_Window * window) | |
689 { | |
690 SDL_VideoDisplay *display = window->display; | |
691 SDL_DisplayMode *displayMode = &display->current_mode; | |
692 return displayMode->format; | |
693 } | |
694 | |
726 static void | 695 static void |
727 SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt) | 696 SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt) |
728 { | 697 { |
729 SDL_VideoDisplay *display = window->display; | 698 SDL_VideoDisplay *display = window->display; |
730 | 699 |
1353 } | 1322 } |
1354 | 1323 |
1355 SDL_free(window); | 1324 SDL_free(window); |
1356 } | 1325 } |
1357 | 1326 |
1358 void | |
1359 SDL_AddRenderDriver(SDL_VideoDisplay * display, const SDL_RenderDriver * driver) | |
1360 { | |
1361 SDL_RenderDriver *render_drivers; | |
1362 | |
1363 render_drivers = | |
1364 SDL_realloc(display->render_drivers, | |
1365 (display->num_render_drivers + | |
1366 1) * sizeof(*render_drivers)); | |
1367 if (render_drivers) { | |
1368 render_drivers[display->num_render_drivers] = *driver; | |
1369 display->render_drivers = render_drivers; | |
1370 display->num_render_drivers++; | |
1371 } | |
1372 } | |
1373 | |
1374 int | |
1375 SDL_GetNumRenderDrivers(void) | |
1376 { | |
1377 if (_this) { | |
1378 return SDL_CurrentDisplay->num_render_drivers; | |
1379 } | |
1380 return 0; | |
1381 } | |
1382 | |
1383 int | |
1384 SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info) | |
1385 { | |
1386 if (!_this) { | |
1387 SDL_UninitializedVideo(); | |
1388 return -1; | |
1389 } | |
1390 if (index < 0 || index >= SDL_GetNumRenderDrivers()) { | |
1391 SDL_SetError("index must be in the range of 0 - %d", | |
1392 SDL_GetNumRenderDrivers() - 1); | |
1393 return -1; | |
1394 } | |
1395 *info = SDL_CurrentDisplay->render_drivers[index].info; | |
1396 return 0; | |
1397 } | |
1398 | |
1399 static int | |
1400 SDL_RendererEventWatch(void *userdata, SDL_Event *event) | |
1401 { | |
1402 SDL_Renderer *renderer = (SDL_Renderer *)userdata; | |
1403 | |
1404 if (event->type == SDL_WINDOWEVENT && renderer->WindowEvent) { | |
1405 SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); | |
1406 if (window == renderer->window) { | |
1407 renderer->WindowEvent(renderer, &event->window); | |
1408 } | |
1409 } | |
1410 return 0; | |
1411 } | |
1412 | |
1413 SDL_Renderer * | |
1414 SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) | |
1415 { | |
1416 SDL_Renderer *renderer = NULL; | |
1417 | |
1418 CHECK_WINDOW_MAGIC(window, NULL); | |
1419 | |
1420 if (index < 0) { | |
1421 char *override = SDL_getenv("SDL_VIDEO_RENDERER"); | |
1422 int n = SDL_GetNumRenderDrivers(); | |
1423 | |
1424 #if SDL_VIDEO_RENDER_OGL | |
1425 if (!override && (window->flags & SDL_WINDOW_OPENGL)) { | |
1426 override = "opengl"; | |
1427 } | |
1428 #endif /* SDL_VIDEO_RENDER_OGL */ | |
1429 #if SDL_VIDEO_RENDER_OGL_ES | |
1430 if (!override && (window->flags & SDL_WINDOW_OPENGL)) { | |
1431 override = "opengl_es"; | |
1432 } | |
1433 #endif /* SDL_VIDEO_RENDER_OGL_ES */ | |
1434 if (override) { | |
1435 for (index = 0; index < n; ++index) { | |
1436 SDL_RenderDriver *driver = | |
1437 &SDL_CurrentDisplay->render_drivers[index]; | |
1438 | |
1439 if (SDL_strcasecmp(override, driver->info.name) == 0) { | |
1440 /* Create a new renderer instance */ | |
1441 renderer = driver->CreateRenderer(window, flags); | |
1442 break; | |
1443 } | |
1444 } | |
1445 } else { | |
1446 for (index = 0; index < n; ++index) { | |
1447 SDL_RenderDriver *driver = | |
1448 &SDL_CurrentDisplay->render_drivers[index]; | |
1449 | |
1450 if ((driver->info.flags & flags) == flags) { | |
1451 /* Create a new renderer instance */ | |
1452 renderer = driver->CreateRenderer(window, flags); | |
1453 if (renderer) { | |
1454 /* Yay, we got one! */ | |
1455 break; | |
1456 } | |
1457 } | |
1458 } | |
1459 } | |
1460 if (index == n) { | |
1461 SDL_SetError("Couldn't find matching render driver"); | |
1462 return NULL; | |
1463 } | |
1464 } else { | |
1465 if (index >= SDL_GetNumRenderDrivers()) { | |
1466 SDL_SetError("index must be -1 or in the range of 0 - %d", | |
1467 SDL_GetNumRenderDrivers() - 1); | |
1468 return NULL; | |
1469 } | |
1470 /* Create a new renderer instance */ | |
1471 renderer = SDL_CurrentDisplay->render_drivers[index].CreateRenderer(window, flags); | |
1472 } | |
1473 | |
1474 if (renderer) { | |
1475 renderer->magic = &_this->renderer_magic; | |
1476 | |
1477 SDL_AddEventWatch(SDL_RendererEventWatch, renderer); | |
1478 } | |
1479 return renderer; | |
1480 } | |
1481 | |
1482 int | |
1483 SDL_GetRendererInfo(SDL_Renderer * renderer, SDL_RendererInfo * info) | |
1484 { | |
1485 CHECK_RENDERER_MAGIC(renderer, -1); | |
1486 | |
1487 *info = renderer->info; | |
1488 return 0; | |
1489 } | |
1490 | |
1491 SDL_Texture * | |
1492 SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h) | |
1493 { | |
1494 SDL_Texture *texture; | |
1495 | |
1496 CHECK_RENDERER_MAGIC(renderer, NULL); | |
1497 | |
1498 if (w <= 0 || h <= 0) { | |
1499 SDL_SetError("Texture dimensions can't be 0"); | |
1500 return 0; | |
1501 } | |
1502 texture = (SDL_Texture *) SDL_calloc(1, sizeof(*texture)); | |
1503 if (!texture) { | |
1504 SDL_OutOfMemory(); | |
1505 return 0; | |
1506 } | |
1507 texture->magic = &_this->texture_magic; | |
1508 texture->format = format; | |
1509 texture->access = access; | |
1510 texture->w = w; | |
1511 texture->h = h; | |
1512 texture->r = 255; | |
1513 texture->g = 255; | |
1514 texture->b = 255; | |
1515 texture->a = 255; | |
1516 texture->renderer = renderer; | |
1517 texture->next = renderer->textures; | |
1518 if (renderer->textures) { | |
1519 renderer->textures->prev = texture; | |
1520 } | |
1521 renderer->textures = texture; | |
1522 | |
1523 if (renderer->CreateTexture(renderer, texture) < 0) { | |
1524 SDL_DestroyTexture(texture); | |
1525 return 0; | |
1526 } | |
1527 return texture; | |
1528 } | |
1529 | |
1530 SDL_Texture * | |
1531 SDL_CreateTextureFromSurface(SDL_Renderer * renderer, Uint32 format, SDL_Surface * surface) | |
1532 { | |
1533 SDL_Texture *texture; | |
1534 Uint32 requested_format = format; | |
1535 SDL_PixelFormat *fmt; | |
1536 int bpp; | |
1537 Uint32 Rmask, Gmask, Bmask, Amask; | |
1538 | |
1539 CHECK_RENDERER_MAGIC(renderer, NULL); | |
1540 | |
1541 if (!surface) { | |
1542 SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); | |
1543 return NULL; | |
1544 } | |
1545 fmt = surface->format; | |
1546 | |
1547 if (format) { | |
1548 if (!SDL_PixelFormatEnumToMasks | |
1549 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
1550 SDL_SetError("Unknown pixel format"); | |
1551 return 0; | |
1552 } | |
1553 } else { | |
1554 if (surface->format->Amask | |
1555 || !(surface->map->info.flags & | |
1556 (SDL_COPY_COLORKEY | SDL_COPY_BLEND))) { | |
1557 Uint32 it; | |
1558 int pfmt; | |
1559 | |
1560 /* Pixel formats, sorted by best first */ | |
1561 static const Uint32 sdl_pformats[] = { | |
1562 SDL_PIXELFORMAT_ARGB8888, | |
1563 SDL_PIXELFORMAT_RGBA8888, | |
1564 SDL_PIXELFORMAT_ABGR8888, | |
1565 SDL_PIXELFORMAT_BGRA8888, | |
1566 SDL_PIXELFORMAT_RGB888, | |
1567 SDL_PIXELFORMAT_BGR888, | |
1568 SDL_PIXELFORMAT_RGB24, | |
1569 SDL_PIXELFORMAT_BGR24, | |
1570 SDL_PIXELFORMAT_RGB565, | |
1571 SDL_PIXELFORMAT_BGR565, | |
1572 SDL_PIXELFORMAT_ARGB1555, | |
1573 SDL_PIXELFORMAT_RGBA5551, | |
1574 SDL_PIXELFORMAT_ABGR1555, | |
1575 SDL_PIXELFORMAT_BGRA5551, | |
1576 SDL_PIXELFORMAT_RGB555, | |
1577 SDL_PIXELFORMAT_BGR555, | |
1578 SDL_PIXELFORMAT_ARGB4444, | |
1579 SDL_PIXELFORMAT_RGBA4444, | |
1580 SDL_PIXELFORMAT_ABGR4444, | |
1581 SDL_PIXELFORMAT_BGRA4444, | |
1582 SDL_PIXELFORMAT_RGB444, | |
1583 SDL_PIXELFORMAT_ARGB2101010, | |
1584 SDL_PIXELFORMAT_RGB332, | |
1585 SDL_PIXELFORMAT_UNKNOWN | |
1586 }; | |
1587 | |
1588 bpp = fmt->BitsPerPixel; | |
1589 Rmask = fmt->Rmask; | |
1590 Gmask = fmt->Gmask; | |
1591 Bmask = fmt->Bmask; | |
1592 Amask = fmt->Amask; | |
1593 | |
1594 format = | |
1595 SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask); | |
1596 if (!format) { | |
1597 SDL_SetError("Unknown pixel format"); | |
1598 return 0; | |
1599 } | |
1600 | |
1601 /* Search requested format in the supported texture */ | |
1602 /* formats by current renderer */ | |
1603 for (it = 0; it < renderer->info.num_texture_formats; it++) { | |
1604 if (renderer->info.texture_formats[it] == format) { | |
1605 break; | |
1606 } | |
1607 } | |
1608 | |
1609 /* If requested format can't be found, search any best */ | |
1610 /* format which renderer provides */ | |
1611 if (it == renderer->info.num_texture_formats) { | |
1612 pfmt = 0; | |
1613 for (;;) { | |
1614 if (sdl_pformats[pfmt] == SDL_PIXELFORMAT_UNKNOWN) { | |
1615 break; | |
1616 } | |
1617 | |
1618 for (it = 0; it < renderer->info.num_texture_formats; | |
1619 it++) { | |
1620 if (renderer->info.texture_formats[it] == | |
1621 sdl_pformats[pfmt]) { | |
1622 break; | |
1623 } | |
1624 } | |
1625 | |
1626 if (it != renderer->info.num_texture_formats) { | |
1627 /* The best format has been found */ | |
1628 break; | |
1629 } | |
1630 pfmt++; | |
1631 } | |
1632 | |
1633 /* If any format can't be found, then return an error */ | |
1634 if (it == renderer->info.num_texture_formats) { | |
1635 SDL_SetError | |
1636 ("Any of the supported pixel formats can't be found"); | |
1637 return 0; | |
1638 } | |
1639 | |
1640 /* Convert found pixel format back to color masks */ | |
1641 if (SDL_PixelFormatEnumToMasks | |
1642 (renderer->info.texture_formats[it], &bpp, &Rmask, &Gmask, | |
1643 &Bmask, &Amask) != SDL_TRUE) { | |
1644 SDL_SetError("Unknown pixel format"); | |
1645 return 0; | |
1646 } | |
1647 } | |
1648 } else { | |
1649 /* Need a format with alpha */ | |
1650 Uint32 it; | |
1651 int apfmt; | |
1652 | |
1653 /* Pixel formats with alpha, sorted by best first */ | |
1654 static const Uint32 sdl_alpha_pformats[] = { | |
1655 SDL_PIXELFORMAT_ARGB8888, | |
1656 SDL_PIXELFORMAT_RGBA8888, | |
1657 SDL_PIXELFORMAT_ABGR8888, | |
1658 SDL_PIXELFORMAT_BGRA8888, | |
1659 SDL_PIXELFORMAT_ARGB1555, | |
1660 SDL_PIXELFORMAT_RGBA5551, | |
1661 SDL_PIXELFORMAT_ABGR1555, | |
1662 SDL_PIXELFORMAT_BGRA5551, | |
1663 SDL_PIXELFORMAT_ARGB4444, | |
1664 SDL_PIXELFORMAT_RGBA4444, | |
1665 SDL_PIXELFORMAT_ABGR4444, | |
1666 SDL_PIXELFORMAT_BGRA4444, | |
1667 SDL_PIXELFORMAT_ARGB2101010, | |
1668 SDL_PIXELFORMAT_UNKNOWN | |
1669 }; | |
1670 | |
1671 if (surface->format->Amask) { | |
1672 /* If surface already has alpha, then try an original */ | |
1673 /* surface format first */ | |
1674 bpp = fmt->BitsPerPixel; | |
1675 Rmask = fmt->Rmask; | |
1676 Gmask = fmt->Gmask; | |
1677 Bmask = fmt->Bmask; | |
1678 Amask = fmt->Amask; | |
1679 } else { | |
1680 bpp = 32; | |
1681 Rmask = 0x00FF0000; | |
1682 Gmask = 0x0000FF00; | |
1683 Bmask = 0x000000FF; | |
1684 Amask = 0xFF000000; | |
1685 } | |
1686 | |
1687 format = | |
1688 SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask); | |
1689 if (!format) { | |
1690 SDL_SetError("Unknown pixel format"); | |
1691 return 0; | |
1692 } | |
1693 | |
1694 /* Search this format in the supported texture formats */ | |
1695 /* by current renderer */ | |
1696 for (it = 0; it < renderer->info.num_texture_formats; it++) { | |
1697 if (renderer->info.texture_formats[it] == format) { | |
1698 break; | |
1699 } | |
1700 } | |
1701 | |
1702 /* If this format can't be found, search any best */ | |
1703 /* compatible format with alpha which renderer provides */ | |
1704 if (it == renderer->info.num_texture_formats) { | |
1705 apfmt = 0; | |
1706 for (;;) { | |
1707 if (sdl_alpha_pformats[apfmt] == SDL_PIXELFORMAT_UNKNOWN) { | |
1708 break; | |
1709 } | |
1710 | |
1711 for (it = 0; it < renderer->info.num_texture_formats; | |
1712 it++) { | |
1713 if (renderer->info.texture_formats[it] == | |
1714 sdl_alpha_pformats[apfmt]) { | |
1715 break; | |
1716 } | |
1717 } | |
1718 | |
1719 if (it != renderer->info.num_texture_formats) { | |
1720 /* Compatible format has been found */ | |
1721 break; | |
1722 } | |
1723 apfmt++; | |
1724 } | |
1725 | |
1726 /* If compatible format can't be found, then return an error */ | |
1727 if (it == renderer->info.num_texture_formats) { | |
1728 SDL_SetError("Compatible pixel format can't be found"); | |
1729 return 0; | |
1730 } | |
1731 | |
1732 /* Convert found pixel format back to color masks */ | |
1733 if (SDL_PixelFormatEnumToMasks | |
1734 (renderer->info.texture_formats[it], &bpp, &Rmask, &Gmask, | |
1735 &Bmask, &Amask) != SDL_TRUE) { | |
1736 SDL_SetError("Unknown pixel format"); | |
1737 return 0; | |
1738 } | |
1739 } | |
1740 } | |
1741 | |
1742 format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask); | |
1743 if (!format) { | |
1744 SDL_SetError("Unknown pixel format"); | |
1745 return 0; | |
1746 } | |
1747 } | |
1748 | |
1749 texture = | |
1750 SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC, | |
1751 surface->w, surface->h); | |
1752 if (!texture && !requested_format) { | |
1753 SDL_DisplayMode desktop_mode; | |
1754 SDL_GetDesktopDisplayMode(&desktop_mode); | |
1755 format = desktop_mode.format; | |
1756 texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC, | |
1757 surface->w, surface->h); | |
1758 } | |
1759 if (!texture) { | |
1760 return 0; | |
1761 } | |
1762 if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask | |
1763 && Bmask == fmt->Bmask && Amask == fmt->Amask) { | |
1764 if (SDL_MUSTLOCK(surface)) { | |
1765 SDL_LockSurface(surface); | |
1766 SDL_UpdateTexture(texture, NULL, surface->pixels, | |
1767 surface->pitch); | |
1768 SDL_UnlockSurface(surface); | |
1769 } else { | |
1770 SDL_UpdateTexture(texture, NULL, surface->pixels, | |
1771 surface->pitch); | |
1772 } | |
1773 } else { | |
1774 SDL_PixelFormat dst_fmt; | |
1775 SDL_Surface *dst = NULL; | |
1776 | |
1777 /* Set up a destination surface for the texture update */ | |
1778 SDL_InitFormat(&dst_fmt, bpp, Rmask, Gmask, Bmask, Amask); | |
1779 dst = SDL_ConvertSurface(surface, &dst_fmt, 0); | |
1780 if (dst) { | |
1781 SDL_UpdateTexture(texture, NULL, dst->pixels, dst->pitch); | |
1782 SDL_FreeSurface(dst); | |
1783 } | |
1784 if (!dst) { | |
1785 SDL_DestroyTexture(texture); | |
1786 return 0; | |
1787 } | |
1788 } | |
1789 | |
1790 { | |
1791 Uint8 r, g, b, a; | |
1792 SDL_BlendMode blendMode; | |
1793 | |
1794 SDL_GetSurfaceColorMod(surface, &r, &g, &b); | |
1795 SDL_SetTextureColorMod(texture, r, g, b); | |
1796 | |
1797 SDL_GetSurfaceAlphaMod(surface, &a); | |
1798 SDL_SetTextureAlphaMod(texture, a); | |
1799 | |
1800 if (surface->map->info.flags & SDL_COPY_COLORKEY) { | |
1801 /* We converted to a texture with alpha format */ | |
1802 SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); | |
1803 } else { | |
1804 SDL_GetSurfaceBlendMode(surface, &blendMode); | |
1805 SDL_SetTextureBlendMode(texture, blendMode); | |
1806 } | |
1807 } | |
1808 return texture; | |
1809 } | |
1810 | |
1811 int | |
1812 SDL_QueryTexture(SDL_Texture * texture, Uint32 * format, int *access, | |
1813 int *w, int *h) | |
1814 { | |
1815 CHECK_TEXTURE_MAGIC(texture, -1); | |
1816 | |
1817 if (format) { | |
1818 *format = texture->format; | |
1819 } | |
1820 if (access) { | |
1821 *access = texture->access; | |
1822 } | |
1823 if (w) { | |
1824 *w = texture->w; | |
1825 } | |
1826 if (h) { | |
1827 *h = texture->h; | |
1828 } | |
1829 return 0; | |
1830 } | |
1831 | |
1832 int | |
1833 SDL_QueryTexturePixels(SDL_Texture * texture, void **pixels, int *pitch) | |
1834 { | |
1835 SDL_Renderer *renderer; | |
1836 | |
1837 CHECK_TEXTURE_MAGIC(texture, -1); | |
1838 | |
1839 renderer = texture->renderer; | |
1840 if (!renderer->QueryTexturePixels) { | |
1841 SDL_Unsupported(); | |
1842 return -1; | |
1843 } | |
1844 return renderer->QueryTexturePixels(renderer, texture, pixels, pitch); | |
1845 } | |
1846 | |
1847 int | |
1848 SDL_SetTextureColorMod(SDL_Texture * texture, Uint8 r, Uint8 g, Uint8 b) | |
1849 { | |
1850 SDL_Renderer *renderer; | |
1851 | |
1852 CHECK_TEXTURE_MAGIC(texture, -1); | |
1853 | |
1854 renderer = texture->renderer; | |
1855 if (r < 255 || g < 255 || b < 255) { | |
1856 texture->modMode |= SDL_TEXTUREMODULATE_COLOR; | |
1857 } else { | |
1858 texture->modMode &= ~SDL_TEXTUREMODULATE_COLOR; | |
1859 } | |
1860 texture->r = r; | |
1861 texture->g = g; | |
1862 texture->b = b; | |
1863 if (renderer->SetTextureColorMod) { | |
1864 return renderer->SetTextureColorMod(renderer, texture); | |
1865 } else { | |
1866 return 0; | |
1867 } | |
1868 } | |
1869 | |
1870 int | |
1871 SDL_GetTextureColorMod(SDL_Texture * texture, Uint8 * r, Uint8 * g, | |
1872 Uint8 * b) | |
1873 { | |
1874 SDL_Renderer *renderer; | |
1875 | |
1876 CHECK_TEXTURE_MAGIC(texture, -1); | |
1877 | |
1878 renderer = texture->renderer; | |
1879 if (r) { | |
1880 *r = texture->r; | |
1881 } | |
1882 if (g) { | |
1883 *g = texture->g; | |
1884 } | |
1885 if (b) { | |
1886 *b = texture->b; | |
1887 } | |
1888 return 0; | |
1889 } | |
1890 | |
1891 int | |
1892 SDL_SetTextureAlphaMod(SDL_Texture * texture, Uint8 alpha) | |
1893 { | |
1894 SDL_Renderer *renderer; | |
1895 | |
1896 CHECK_TEXTURE_MAGIC(texture, -1); | |
1897 | |
1898 renderer = texture->renderer; | |
1899 if (alpha < 255) { | |
1900 texture->modMode |= SDL_TEXTUREMODULATE_ALPHA; | |
1901 } else { | |
1902 texture->modMode &= ~SDL_TEXTUREMODULATE_ALPHA; | |
1903 } | |
1904 texture->a = alpha; | |
1905 if (renderer->SetTextureAlphaMod) { | |
1906 return renderer->SetTextureAlphaMod(renderer, texture); | |
1907 } else { | |
1908 return 0; | |
1909 } | |
1910 } | |
1911 | |
1912 int | |
1913 SDL_GetTextureAlphaMod(SDL_Texture * texture, Uint8 * alpha) | |
1914 { | |
1915 CHECK_TEXTURE_MAGIC(texture, -1); | |
1916 | |
1917 if (alpha) { | |
1918 *alpha = texture->a; | |
1919 } | |
1920 return 0; | |
1921 } | |
1922 | |
1923 int | |
1924 SDL_SetTextureBlendMode(SDL_Texture * texture, SDL_BlendMode blendMode) | |
1925 { | |
1926 SDL_Renderer *renderer; | |
1927 | |
1928 CHECK_TEXTURE_MAGIC(texture, -1); | |
1929 | |
1930 renderer = texture->renderer; | |
1931 texture->blendMode = blendMode; | |
1932 if (renderer->SetTextureBlendMode) { | |
1933 return renderer->SetTextureBlendMode(renderer, texture); | |
1934 } else { | |
1935 return 0; | |
1936 } | |
1937 } | |
1938 | |
1939 int | |
1940 SDL_GetTextureBlendMode(SDL_Texture * texture, SDL_BlendMode *blendMode) | |
1941 { | |
1942 CHECK_TEXTURE_MAGIC(texture, -1); | |
1943 | |
1944 if (blendMode) { | |
1945 *blendMode = texture->blendMode; | |
1946 } | |
1947 return 0; | |
1948 } | |
1949 | |
1950 int | |
1951 SDL_UpdateTexture(SDL_Texture * texture, const SDL_Rect * rect, | |
1952 const void *pixels, int pitch) | |
1953 { | |
1954 SDL_Renderer *renderer; | |
1955 SDL_Rect full_rect; | |
1956 | |
1957 CHECK_TEXTURE_MAGIC(texture, -1); | |
1958 | |
1959 renderer = texture->renderer; | |
1960 if (!renderer->UpdateTexture) { | |
1961 SDL_Unsupported(); | |
1962 return -1; | |
1963 } | |
1964 if (!rect) { | |
1965 full_rect.x = 0; | |
1966 full_rect.y = 0; | |
1967 full_rect.w = texture->w; | |
1968 full_rect.h = texture->h; | |
1969 rect = &full_rect; | |
1970 } | |
1971 return renderer->UpdateTexture(renderer, texture, rect, pixels, pitch); | |
1972 } | |
1973 | |
1974 int | |
1975 SDL_LockTexture(SDL_Texture * texture, const SDL_Rect * rect, int markDirty, | |
1976 void **pixels, int *pitch) | |
1977 { | |
1978 SDL_Renderer *renderer; | |
1979 SDL_Rect full_rect; | |
1980 | |
1981 CHECK_TEXTURE_MAGIC(texture, -1); | |
1982 | |
1983 if (texture->access != SDL_TEXTUREACCESS_STREAMING) { | |
1984 SDL_SetError("SDL_LockTexture(): texture must be streaming"); | |
1985 return -1; | |
1986 } | |
1987 renderer = texture->renderer; | |
1988 if (!renderer->LockTexture) { | |
1989 SDL_Unsupported(); | |
1990 return -1; | |
1991 } | |
1992 if (!rect) { | |
1993 full_rect.x = 0; | |
1994 full_rect.y = 0; | |
1995 full_rect.w = texture->w; | |
1996 full_rect.h = texture->h; | |
1997 rect = &full_rect; | |
1998 } | |
1999 return renderer->LockTexture(renderer, texture, rect, markDirty, pixels, | |
2000 pitch); | |
2001 } | |
2002 | |
2003 void | |
2004 SDL_UnlockTexture(SDL_Texture * texture) | |
2005 { | |
2006 SDL_Renderer *renderer; | |
2007 | |
2008 CHECK_TEXTURE_MAGIC(texture, ); | |
2009 | |
2010 if (texture->access != SDL_TEXTUREACCESS_STREAMING) { | |
2011 return; | |
2012 } | |
2013 renderer = texture->renderer; | |
2014 if (!renderer->UnlockTexture) { | |
2015 return; | |
2016 } | |
2017 renderer->UnlockTexture(renderer, texture); | |
2018 } | |
2019 | |
2020 void | |
2021 SDL_DirtyTexture(SDL_Texture * texture, int numrects, | |
2022 const SDL_Rect * rects) | |
2023 { | |
2024 SDL_Renderer *renderer; | |
2025 | |
2026 CHECK_TEXTURE_MAGIC(texture, ); | |
2027 | |
2028 if (texture->access != SDL_TEXTUREACCESS_STREAMING) { | |
2029 return; | |
2030 } | |
2031 renderer = texture->renderer; | |
2032 if (!renderer->DirtyTexture) { | |
2033 return; | |
2034 } | |
2035 renderer->DirtyTexture(renderer, texture, numrects, rects); | |
2036 } | |
2037 | |
2038 int | |
2039 SDL_SetRenderDrawColor(SDL_Renderer * renderer, | |
2040 Uint8 r, Uint8 g, Uint8 b, Uint8 a) | |
2041 { | |
2042 CHECK_RENDERER_MAGIC(renderer, -1); | |
2043 | |
2044 renderer->r = r; | |
2045 renderer->g = g; | |
2046 renderer->b = b; | |
2047 renderer->a = a; | |
2048 return 0; | |
2049 } | |
2050 | |
2051 int | |
2052 SDL_GetRenderDrawColor(SDL_Renderer * renderer, | |
2053 Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a) | |
2054 { | |
2055 CHECK_RENDERER_MAGIC(renderer, -1); | |
2056 | |
2057 if (r) { | |
2058 *r = renderer->r; | |
2059 } | |
2060 if (g) { | |
2061 *g = renderer->g; | |
2062 } | |
2063 if (b) { | |
2064 *b = renderer->b; | |
2065 } | |
2066 if (a) { | |
2067 *a = renderer->a; | |
2068 } | |
2069 return 0; | |
2070 } | |
2071 | |
2072 int | |
2073 SDL_SetRenderDrawBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) | |
2074 { | |
2075 CHECK_RENDERER_MAGIC(renderer, -1); | |
2076 | |
2077 renderer->blendMode = blendMode; | |
2078 return 0; | |
2079 } | |
2080 | |
2081 int | |
2082 SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, SDL_BlendMode *blendMode) | |
2083 { | |
2084 CHECK_RENDERER_MAGIC(renderer, -1); | |
2085 | |
2086 *blendMode = renderer->blendMode; | |
2087 return 0; | |
2088 } | |
2089 | |
2090 int | |
2091 SDL_RenderClear(SDL_Renderer * renderer) | |
2092 { | |
2093 CHECK_RENDERER_MAGIC(renderer, -1); | |
2094 | |
2095 if (!renderer->RenderClear) { | |
2096 SDL_BlendMode blendMode = renderer->blendMode; | |
2097 int status; | |
2098 | |
2099 if (blendMode >= SDL_BLENDMODE_BLEND) { | |
2100 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); | |
2101 } | |
2102 | |
2103 status = SDL_RenderFillRect(renderer, NULL); | |
2104 | |
2105 if (blendMode >= SDL_BLENDMODE_BLEND) { | |
2106 SDL_SetRenderDrawBlendMode(renderer, blendMode); | |
2107 } | |
2108 return status; | |
2109 } | |
2110 return renderer->RenderClear(renderer); | |
2111 } | |
2112 | |
2113 int | |
2114 SDL_RenderDrawPoint(SDL_Renderer * renderer, int x, int y) | |
2115 { | |
2116 SDL_Point point; | |
2117 | |
2118 point.x = x; | |
2119 point.y = y; | |
2120 return SDL_RenderDrawPoints(renderer, &point, 1); | |
2121 } | |
2122 | |
2123 int | |
2124 SDL_RenderDrawPoints(SDL_Renderer * renderer, | |
2125 const SDL_Point * points, int count) | |
2126 { | |
2127 CHECK_RENDERER_MAGIC(renderer, -1); | |
2128 | |
2129 if (!points) { | |
2130 SDL_SetError("SDL_RenderDrawPoints(): Passed NULL points"); | |
2131 return -1; | |
2132 } | |
2133 if (count < 1) { | |
2134 return 0; | |
2135 } | |
2136 return renderer->RenderDrawPoints(renderer, points, count); | |
2137 } | |
2138 | |
2139 int | |
2140 SDL_RenderDrawLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2) | |
2141 { | |
2142 SDL_Point points[2]; | |
2143 | |
2144 points[0].x = x1; | |
2145 points[0].y = y1; | |
2146 points[1].x = x2; | |
2147 points[1].y = y2; | |
2148 return SDL_RenderDrawLines(renderer, points, 2); | |
2149 } | |
2150 | |
2151 int | |
2152 SDL_RenderDrawLines(SDL_Renderer * renderer, | |
2153 const SDL_Point * points, int count) | |
2154 { | |
2155 CHECK_RENDERER_MAGIC(renderer, -1); | |
2156 | |
2157 if (!points) { | |
2158 SDL_SetError("SDL_RenderDrawLines(): Passed NULL points"); | |
2159 return -1; | |
2160 } | |
2161 if (count < 2) { | |
2162 return 0; | |
2163 } | |
2164 return renderer->RenderDrawLines(renderer, points, count); | |
2165 } | |
2166 | |
2167 int | |
2168 SDL_RenderDrawRect(SDL_Renderer * renderer, const SDL_Rect * rect) | |
2169 { | |
2170 SDL_Rect full_rect; | |
2171 SDL_Point points[5]; | |
2172 | |
2173 CHECK_RENDERER_MAGIC(renderer, -1); | |
2174 | |
2175 /* If 'rect' == NULL, then outline the whole surface */ | |
2176 if (!rect) { | |
2177 SDL_Window *window = renderer->window; | |
2178 | |
2179 full_rect.x = 0; | |
2180 full_rect.y = 0; | |
2181 full_rect.w = window->w; | |
2182 full_rect.h = window->h; | |
2183 rect = &full_rect; | |
2184 } | |
2185 | |
2186 points[0].x = rect->x; | |
2187 points[0].y = rect->y; | |
2188 points[1].x = rect->x+rect->w-1; | |
2189 points[1].y = rect->y; | |
2190 points[2].x = rect->x+rect->w-1; | |
2191 points[2].y = rect->y+rect->h-1; | |
2192 points[3].x = rect->x; | |
2193 points[3].y = rect->y+rect->h-1; | |
2194 points[4].x = rect->x; | |
2195 points[4].y = rect->y; | |
2196 return SDL_RenderDrawLines(renderer, points, 5); | |
2197 } | |
2198 | |
2199 int | |
2200 SDL_RenderDrawRects(SDL_Renderer * renderer, | |
2201 const SDL_Rect ** rects, int count) | |
2202 { | |
2203 int i; | |
2204 | |
2205 CHECK_RENDERER_MAGIC(renderer, -1); | |
2206 | |
2207 if (!rects) { | |
2208 SDL_SetError("SDL_RenderDrawRects(): Passed NULL rects"); | |
2209 return -1; | |
2210 } | |
2211 if (count < 1) { | |
2212 return 0; | |
2213 } | |
2214 | |
2215 /* Check for NULL rect, which means fill entire window */ | |
2216 for (i = 0; i < count; ++i) { | |
2217 if (SDL_RenderDrawRect(renderer, rects[i]) < 0) { | |
2218 return -1; | |
2219 } | |
2220 } | |
2221 return 0; | |
2222 } | |
2223 | |
2224 int | |
2225 SDL_RenderFillRect(SDL_Renderer * renderer, const SDL_Rect * rect) | |
2226 { | |
2227 return SDL_RenderFillRects(renderer, &rect, 1); | |
2228 } | |
2229 | |
2230 int | |
2231 SDL_RenderFillRects(SDL_Renderer * renderer, | |
2232 const SDL_Rect ** rects, int count) | |
2233 { | |
2234 int i; | |
2235 | |
2236 CHECK_RENDERER_MAGIC(renderer, -1); | |
2237 | |
2238 if (!rects) { | |
2239 SDL_SetError("SDL_RenderFillRects(): Passed NULL rects"); | |
2240 return -1; | |
2241 } | |
2242 if (count < 1) { | |
2243 return 0; | |
2244 } | |
2245 | |
2246 /* Check for NULL rect, which means fill entire window */ | |
2247 for (i = 0; i < count; ++i) { | |
2248 if (rects[i] == NULL) { | |
2249 SDL_Window *window = renderer->window; | |
2250 SDL_Rect full_rect; | |
2251 const SDL_Rect *rect; | |
2252 | |
2253 full_rect.x = 0; | |
2254 full_rect.y = 0; | |
2255 full_rect.w = window->w; | |
2256 full_rect.h = window->h; | |
2257 rect = &full_rect; | |
2258 return renderer->RenderFillRects(renderer, &rect, 1); | |
2259 } | |
2260 } | |
2261 return renderer->RenderFillRects(renderer, rects, count); | |
2262 } | |
2263 | |
2264 int | |
2265 SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | |
2266 const SDL_Rect * srcrect, const SDL_Rect * dstrect) | |
2267 { | |
2268 SDL_Window *window; | |
2269 SDL_Rect real_srcrect; | |
2270 SDL_Rect real_dstrect; | |
2271 | |
2272 CHECK_RENDERER_MAGIC(renderer, -1); | |
2273 CHECK_TEXTURE_MAGIC(texture, -1); | |
2274 | |
2275 if (renderer != texture->renderer) { | |
2276 SDL_SetError("Texture was not created with this renderer"); | |
2277 return -1; | |
2278 } | |
2279 window = renderer->window; | |
2280 | |
2281 real_srcrect.x = 0; | |
2282 real_srcrect.y = 0; | |
2283 real_srcrect.w = texture->w; | |
2284 real_srcrect.h = texture->h; | |
2285 if (srcrect) { | |
2286 if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) { | |
2287 return 0; | |
2288 } | |
2289 } | |
2290 | |
2291 real_dstrect.x = 0; | |
2292 real_dstrect.y = 0; | |
2293 real_dstrect.w = window->w; | |
2294 real_dstrect.h = window->h; | |
2295 if (dstrect) { | |
2296 if (!SDL_IntersectRect(dstrect, &real_dstrect, &real_dstrect)) { | |
2297 return 0; | |
2298 } | |
2299 /* Clip srcrect by the same amount as dstrect was clipped */ | |
2300 if (dstrect->w != real_dstrect.w) { | |
2301 int deltax = (real_dstrect.x - dstrect->x); | |
2302 int deltaw = (real_dstrect.w - dstrect->w); | |
2303 real_srcrect.x += (deltax * real_srcrect.w) / dstrect->w; | |
2304 real_srcrect.w += (deltaw * real_srcrect.w) / dstrect->w; | |
2305 } | |
2306 if (dstrect->h != real_dstrect.h) { | |
2307 int deltay = (real_dstrect.y - dstrect->y); | |
2308 int deltah = (real_dstrect.h - dstrect->h); | |
2309 real_srcrect.y += (deltay * real_srcrect.h) / dstrect->h; | |
2310 real_srcrect.h += (deltah * real_srcrect.h) / dstrect->h; | |
2311 } | |
2312 } | |
2313 | |
2314 return renderer->RenderCopy(renderer, texture, &real_srcrect, | |
2315 &real_dstrect); | |
2316 } | |
2317 | |
2318 int | |
2319 SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
2320 Uint32 format, void * pixels, int pitch) | |
2321 { | |
2322 SDL_Window *window; | |
2323 SDL_Rect real_rect; | |
2324 | |
2325 CHECK_RENDERER_MAGIC(renderer, -1); | |
2326 | |
2327 if (!renderer->RenderReadPixels) { | |
2328 SDL_Unsupported(); | |
2329 return -1; | |
2330 } | |
2331 window = renderer->window; | |
2332 | |
2333 if (!format) { | |
2334 format = window->display->current_mode.format; | |
2335 } | |
2336 | |
2337 real_rect.x = 0; | |
2338 real_rect.y = 0; | |
2339 real_rect.w = window->w; | |
2340 real_rect.h = window->h; | |
2341 if (rect) { | |
2342 if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) { | |
2343 return 0; | |
2344 } | |
2345 if (real_rect.y > rect->y) { | |
2346 pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y); | |
2347 } | |
2348 if (real_rect.x > rect->x) { | |
2349 Uint32 format = SDL_CurrentDisplay->current_mode.format; | |
2350 int bpp = SDL_BYTESPERPIXEL(format); | |
2351 pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x); | |
2352 } | |
2353 } | |
2354 | |
2355 return renderer->RenderReadPixels(renderer, &real_rect, | |
2356 format, pixels, pitch); | |
2357 } | |
2358 | |
2359 int | |
2360 SDL_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
2361 Uint32 format, const void * pixels, int pitch) | |
2362 { | |
2363 SDL_Window *window; | |
2364 SDL_Rect real_rect; | |
2365 | |
2366 CHECK_RENDERER_MAGIC(renderer, -1); | |
2367 | |
2368 if (!renderer->RenderWritePixels) { | |
2369 SDL_Unsupported(); | |
2370 return -1; | |
2371 } | |
2372 window = renderer->window; | |
2373 | |
2374 if (!format) { | |
2375 format = window->display->current_mode.format; | |
2376 } | |
2377 | |
2378 real_rect.x = 0; | |
2379 real_rect.y = 0; | |
2380 real_rect.w = window->w; | |
2381 real_rect.h = window->h; | |
2382 if (rect) { | |
2383 if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) { | |
2384 return 0; | |
2385 } | |
2386 if (real_rect.y > rect->y) { | |
2387 pixels = (const Uint8 *)pixels + pitch * (real_rect.y - rect->y); | |
2388 } | |
2389 if (real_rect.x > rect->x) { | |
2390 Uint32 format = SDL_CurrentDisplay->current_mode.format; | |
2391 int bpp = SDL_BYTESPERPIXEL(format); | |
2392 pixels = (const Uint8 *)pixels + bpp * (real_rect.x - rect->x); | |
2393 } | |
2394 } | |
2395 | |
2396 return renderer->RenderWritePixels(renderer, &real_rect, | |
2397 format, pixels, pitch); | |
2398 } | |
2399 | |
2400 void | |
2401 SDL_RenderPresent(SDL_Renderer * renderer) | |
2402 { | |
2403 CHECK_RENDERER_MAGIC(renderer, ); | |
2404 | |
2405 #if SDL_VIDEO_DRIVER_WINDOWS | |
2406 IME_Present((SDL_VideoData *)_this->driverdata); | |
2407 #endif | |
2408 renderer->RenderPresent(renderer); | |
2409 } | |
2410 | |
2411 void | |
2412 SDL_DestroyTexture(SDL_Texture * texture) | |
2413 { | |
2414 SDL_Renderer *renderer; | |
2415 | |
2416 CHECK_TEXTURE_MAGIC(texture, ); | |
2417 texture->magic = NULL; | |
2418 | |
2419 renderer = texture->renderer; | |
2420 if (texture->next) { | |
2421 texture->next->prev = texture->prev; | |
2422 } | |
2423 if (texture->prev) { | |
2424 texture->prev->next = texture->next; | |
2425 } else { | |
2426 renderer->textures = texture->next; | |
2427 } | |
2428 | |
2429 renderer->DestroyTexture(renderer, texture); | |
2430 SDL_free(texture); | |
2431 } | |
2432 | |
2433 void | |
2434 SDL_DestroyRenderer(SDL_Renderer * renderer) | |
2435 { | |
2436 CHECK_RENDERER_MAGIC(renderer, ); | |
2437 | |
2438 SDL_DelEventWatch(SDL_RendererEventWatch, renderer); | |
2439 | |
2440 /* Free existing textures for this renderer */ | |
2441 while (renderer->textures) { | |
2442 SDL_DestroyTexture(renderer->textures); | |
2443 } | |
2444 | |
2445 /* It's no longer magical... */ | |
2446 renderer->magic = NULL; | |
2447 | |
2448 /* Free the renderer instance */ | |
2449 renderer->DestroyRenderer(renderer); | |
2450 } | |
2451 | |
2452 SDL_bool | 1327 SDL_bool |
2453 SDL_IsScreenSaverEnabled() | 1328 SDL_IsScreenSaverEnabled() |
2454 { | 1329 { |
2455 if (!_this) { | 1330 if (!_this) { |
2456 return SDL_TRUE; | 1331 return SDL_TRUE; |
2509 for (i = _this->num_displays; i--;) { | 1384 for (i = _this->num_displays; i--;) { |
2510 SDL_VideoDisplay *display = &_this->displays[i]; | 1385 SDL_VideoDisplay *display = &_this->displays[i]; |
2511 while (display->windows) { | 1386 while (display->windows) { |
2512 SDL_DestroyWindow(display->windows); | 1387 SDL_DestroyWindow(display->windows); |
2513 } | 1388 } |
2514 if (display->render_drivers) { | |
2515 SDL_free(display->render_drivers); | |
2516 display->render_drivers = NULL; | |
2517 } | |
2518 display->num_render_drivers = 0; | |
2519 } | 1389 } |
2520 _this->VideoQuit(_this); | 1390 _this->VideoQuit(_this); |
2521 | 1391 |
2522 for (i = _this->num_displays; i--;) { | 1392 for (i = _this->num_displays; i--;) { |
2523 SDL_VideoDisplay *display = &_this->displays[i]; | 1393 SDL_VideoDisplay *display = &_this->displays[i]; |