ManaPlus
sdlgraphics.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef USE_SDL2
24 
25 #include "render/sdlgraphics.h"
26 
27 #include "graphicsmanager.h"
28 
29 #include "utils/sdlcheckutils.h"
30 
31 #include "utils/sdlpixel.h"
32 
34 
35 #include "resources/imagerect.h"
36 
37 #include "resources/image/image.h"
38 
39 #include "debug.h"
40 
41 #ifndef SDL_BIG_ENDIAN
42 #error missing SDL_endian.h
43 #endif // SDL_BYTEORDER
44 
45 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
46 static unsigned int *cR = nullptr;
47 static unsigned int *cG = nullptr;
48 static unsigned int *cB = nullptr;
49 #endif // SDL_BYTEORDER == SDL_LIL_ENDIAN
50 
52  Graphics(),
53  mOldPixel(0),
54  mOldAlpha(0)
55 {
57  mName = "Software";
58 }
59 
61 {
62 }
63 
65  int dstX, int dstY,
66  const int desiredWidth,
67  const int desiredHeight) restrict2
68 {
69  FUNC_BLOCK("Graphics::drawRescaledImage", 1)
70  // Check that preconditions for blitting are met.
71  if (mWindow == nullptr ||
72  image == nullptr ||
73  image->mSDLSurface == nullptr)
74  {
75  return;
76  }
77 
78  Image *const tmpImage = image->SDLgetScaledImage(
79  desiredWidth, desiredHeight);
80 
81  if ((tmpImage == nullptr) || (tmpImage->mSDLSurface == nullptr))
82  return;
83 
84  const ClipRect &top = mClipStack.top();
85  const SDL_Rect &bounds = image->mBounds;
86 
87  SDL_Rect srcRect =
88  {
89  CAST_S16(bounds.x),
90  CAST_S16(bounds.y),
91  CAST_U16(bounds.w),
92  CAST_U16(bounds.h)
93  };
94 
95  SDL_Rect dstRect =
96  {
97  CAST_S16(dstX + top.xOffset),
98  CAST_S16(dstY + top.yOffset),
99  0,
100  0
101  };
102 
103  SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect, mWindow, &dstRect);
104  delete tmpImage;
105 }
106 
107 void SDLGraphics::drawImage(const Image *restrict const image,
108  int dstX, int dstY) restrict2
109 {
110  drawImageInline(image, dstX, dstY);
111 }
112 
114  int dstX, int dstY) restrict2
115 {
116  FUNC_BLOCK("Graphics::drawImage", 1)
117  // Check that preconditions for blitting are met.
118  if (mWindow == nullptr ||
119  image == nullptr ||
120  image->mSDLSurface == nullptr)
121  {
122  return;
123  }
124 
125  const ClipRect &top = mClipStack.top();
126  const SDL_Rect &bounds = image->mBounds;
127 
128  SDL_Surface *const src = image->mSDLSurface;
129 
130  int srcX = bounds.x;
131  int srcY = bounds.y;
132  dstX += top.xOffset;
133  dstY += top.yOffset;
134 
135  int w = bounds.w;
136  int h = bounds.h;
137  if (srcX < 0)
138  {
139  w += srcX;
140  dstX -= CAST_S16(srcX);
141  srcX = 0;
142  }
143  const int maxw = src->w - srcX;
144  if (maxw < w)
145  w = maxw;
146 
147  if (srcY < 0)
148  {
149  h += srcY;
150  dstY -= CAST_S16(srcY);
151  srcY = 0;
152  }
153  const int maxh = src->h - srcY;
154  if (maxh < h)
155  h = maxh;
156 
157  const SDL_Rect *const clip = &mWindow->clip_rect;
158  const int clipX = clip->x;
159  const int clipY = clip->y;
160  int dx = clipX - dstX;
161  if (dx > 0)
162  {
163  w -= dx;
164  dstX += CAST_S16(dx);
165  srcX += dx;
166  }
167  dx = dstX + w - clipX - clip->w;
168  if (dx > 0)
169  w -= dx;
170 
171  int dy = clipY - dstY;
172  if (dy > 0)
173  {
174  h -= dy;
175  dstY += CAST_S16(dy);
176  srcY += dy;
177  }
178  dy = dstY + h - clipY - clip->h;
179  if (dy > 0)
180  h -= dy;
181 
182  if (w > 0 && h > 0)
183  {
184  SDL_Rect srcRect =
185  {
186  CAST_S16(srcX),
187  CAST_S16(srcY),
188  CAST_U16(w),
189  CAST_U16(h)
190  };
191 
192  SDL_Rect dstRect =
193  {
194  CAST_S16(dstX),
195  CAST_S16(dstY),
196  CAST_U16(w),
197  CAST_U16(h)
198  };
199 
200  SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
201  }
202 }
203 
204 void SDLGraphics::copyImage(const Image *restrict const image,
205  int dstX, int dstY) restrict2
206 {
207  drawImageInline(image, dstX, dstY);
208 }
209 
211  int x, int y) restrict2
212 {
213  FUNC_BLOCK("Graphics::drawImageCached", 1)
214  // Check that preconditions for blitting are met.
215  if (mWindow == nullptr ||
216  image == nullptr ||
217  image->mSDLSurface == nullptr)
218  {
219  return;
220  }
221 
222  const ClipRect &top = mClipStack.top();
223  const SDL_Rect &bounds = image->mBounds;
224 
225  SDL_Surface *const src = image->mSDLSurface;
226 
227  int srcX = bounds.x;
228  int srcY = bounds.y;
229  x += top.xOffset;
230  y += top.yOffset;
231 
232  int w = bounds.w;
233  int h = bounds.h;
234  if (srcX < 0)
235  {
236  w += srcX;
237  x -= CAST_S16(srcX);
238  srcX = 0;
239  }
240  const int maxw = src->w - srcX;
241  if (maxw < w)
242  w = maxw;
243 
244  if (srcY < 0)
245  {
246  h += srcY;
247  y -= CAST_S16(srcY);
248  srcY = 0;
249  }
250  const int maxh = src->h - srcY;
251  if (maxh < h)
252  h = maxh;
253 
254  const SDL_Rect *const clip = &mWindow->clip_rect;
255  const int clipX = clip->x;
256  const int clipY = clip->y;
257  int dx = clipX - x;
258  if (dx > 0)
259  {
260  w -= dx;
261  x += CAST_S16(dx);
262  srcX += dx;
263  }
264  dx = x + w - clipX - clip->w;
265  if (dx > 0)
266  w -= dx;
267 
268  int dy = clipY - y;
269  if (dy > 0)
270  {
271  h -= dy;
272  y += CAST_S16(dy);
273  srcY += dy;
274  }
275  dy = y + h - clipY - clip->h;
276  if (dy > 0)
277  h -= dy;
278 
279  if (w > 0 && h > 0)
280  {
281  SDL_Rect srcRect =
282  {
283  CAST_S16(srcX),
284  CAST_S16(srcY),
285  CAST_U16(w),
286  CAST_U16(h)
287  };
288 
289  SDL_Rect dstRect =
290  {
291  CAST_S16(x),
292  CAST_S16(y),
293  CAST_U16(w),
294  CAST_U16(h)
295  };
296 
297  SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
298  }
299 }
300 
302  const int x, const int y,
303  const int w, const int h) restrict2
304 {
305  FUNC_BLOCK("Graphics::drawPatternCached", 1)
306  // Check that preconditions for blitting are met.
307  if ((mWindow == nullptr) || (image == nullptr))
308  return;
309  if (image->mSDLSurface == nullptr)
310  return;
311 
312  const SDL_Rect &bounds = image->mBounds;
313  const int iw = bounds.w;
314  const int ih = bounds.h;
315  if (iw == 0 || ih == 0)
316  return;
317 
318  const ClipRect &top = mClipStack.top();
319  const int xOffset = top.xOffset + x;
320  const int yOffset = top.yOffset + y;
321  const int srcX = bounds.x;
322  const int srcY = bounds.y;
323  SDL_Surface *const src = image->mSDLSurface;
324  const SDL_Rect *const clip = &mWindow->clip_rect;
325  const int clipX = clip->x;
326  const int clipY = clip->y;
327 
328  for (int py = 0; py < h; py += ih)
329  {
330  const int dh = (py + ih >= h) ? h - py : ih;
331  int dstY = py + yOffset;
332  int y2 = srcY;
333  int h2 = dh;
334  if (y2 < 0)
335  {
336  h2 += y2;
337  dstY -= CAST_S16(y2);
338  y2 = 0;
339  }
340  const int maxh = src->h - y2;
341  if (maxh < h2)
342  h2 = maxh;
343 
344  int dy = clipY - dstY;
345  if (dy > 0)
346  {
347  h2 -= dy;
348  dstY += CAST_S16(dy);
349  y2 += dy;
350  }
351  dy = dstY + h2 - clipY - clip->h;
352  if (dy > 0)
353  h2 -= dy;
354 
355  if (h2 > 0)
356  {
357  for (int px = 0; px < w; px += iw)
358  {
359  const int dw = (px + iw >= w) ? w - px : iw;
360  int dstX = px + xOffset;
361  int x2 = srcX;
362  int w2 = dw;
363  if (x2 < 0)
364  {
365  w2 += x2;
366  dstX -= CAST_S16(x2);
367  x2 = 0;
368  }
369  const int maxw = src->w - x2;
370  if (maxw < w2)
371  w2 = maxw;
372 
373  int dx = clipX - dstX;
374  if (dx > 0)
375  {
376  w2 -= dx;
377  dstX += CAST_S16(dx);
378  x2 += dx;
379  }
380  dx = dstX + w2 - clipX - clip->w;
381  if (dx > 0)
382  w2 -= dx;
383 
384  if (w2 > 0)
385  {
386  SDL_Rect srcRect =
387  {
388  CAST_S16(x2),
389  CAST_S16(y2),
390  CAST_U16(w2),
391  CAST_U16(h2)
392  };
393 
394  SDL_Rect dstRect =
395  {
396  CAST_S16(dstX),
397  CAST_S16(dstY),
398  CAST_U16(w2),
399  CAST_U16(h2)
400  };
401 
402  SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
403  }
404 
405 // SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
406  }
407  }
408  }
409 }
410 
412 {
413 }
414 
415 void SDLGraphics::drawPattern(const Image *restrict const image,
416  const int x, const int y,
417  const int w, const int h) restrict2
418 {
419  drawPatternInline(image, x, y, w, h);
420 }
421 
423  const int x, const int y,
424  const int w, const int h) restrict2
425 {
426  FUNC_BLOCK("Graphics::drawPattern", 1)
427  // Check that preconditions for blitting are met.
428  if ((mWindow == nullptr) || (image == nullptr))
429  return;
430  if (image->mSDLSurface == nullptr)
431  return;
432 
433  const SDL_Rect &bounds = image->mBounds;
434  const int iw = bounds.w;
435  const int ih = bounds.h;
436  if (iw == 0 || ih == 0)
437  return;
438 
439  const ClipRect &top = mClipStack.top();
440  const int xOffset = top.xOffset + x;
441  const int yOffset = top.yOffset + y;
442  const int srcX = bounds.x;
443  const int srcY = bounds.y;
444  SDL_Surface *const src = image->mSDLSurface;
445  const SDL_Rect *const clip = &mWindow->clip_rect;
446  const int clipX = clip->x;
447  const int clipY = clip->y;
448 
449  for (int py = 0; py < h; py += ih)
450  {
451  const int dh = (py + ih >= h) ? h - py : ih;
452  int dstY = py + yOffset;
453  int y2 = srcY;
454  int h2 = dh;
455  if (y2 < 0)
456  {
457  h2 += y2;
458  dstY -= CAST_S16(y2);
459  y2 = 0;
460  }
461  const int maxh = src->h - y2;
462  if (maxh < h2)
463  h2 = maxh;
464 
465  int dy = clipY - dstY;
466  if (dy > 0)
467  {
468  h2 -= dy;
469  dstY += CAST_S16(dy);
470  y2 += dy;
471  }
472  dy = dstY + h2 - clipY - clip->h;
473  if (dy > 0)
474  h2 -= dy;
475 
476  if (h2 > 0)
477  {
478  for (int px = 0; px < w; px += iw)
479  {
480  const int dw = (px + iw >= w) ? w - px : iw;
481  int dstX = px + xOffset;
482  int x2 = srcX;
483  int w2 = dw;
484  if (x2 < 0)
485  {
486  w2 += x2;
487  dstX -= CAST_S16(x2);
488  x2 = 0;
489  }
490  const int maxw = src->w - x2;
491  if (maxw < w2)
492  w2 = maxw;
493 
494  int dx = clipX - dstX;
495  if (dx > 0)
496  {
497  w2 -= dx;
498  dstX += CAST_S16(dx);
499  x2 += dx;
500  }
501  dx = dstX + w2 - clipX - clip->w;
502  if (dx > 0)
503  w2 -= dx;
504 
505  if (w2 > 0)
506  {
507  SDL_Rect srcRect =
508  {
509  CAST_S16(x2),
510  CAST_S16(y2),
511  CAST_U16(w2),
512  CAST_U16(h2)
513  };
514 
515  SDL_Rect dstRect =
516  {
517  CAST_S16(dstX),
518  CAST_S16(dstY),
519  CAST_U16(w2),
520  CAST_U16(h2)
521  };
522 
523  SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
524  }
525 
526 // SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
527  }
528  }
529  }
530 }
531 
533  const int x, const int y,
534  const int w, const int h,
535  const int scaledWidth,
536  const int scaledHeight) restrict2
537 {
538  // Check that preconditions for blitting are met.
539  if ((mWindow == nullptr) || (image == nullptr))
540  return;
541  if (image->mSDLSurface == nullptr)
542  return;
543 
544  if (scaledHeight == 0 || scaledWidth == 0)
545  return;
546 
547  Image *const tmpImage = image->SDLgetScaledImage(
548  scaledWidth, scaledHeight);
549  if (tmpImage == nullptr)
550  return;
551 
552  const SDL_Rect &bounds = tmpImage->mBounds;
553  const int iw = bounds.w;
554  const int ih = bounds.h;
555  if (iw == 0 || ih == 0)
556  return;
557 
558  const ClipRect &top = mClipStack.top();
559  const int xOffset = top.xOffset + x;
560  const int yOffset = top.yOffset + y;
561  const int srcX = bounds.x;
562  const int srcY = bounds.y;
563 
564  for (int py = 0; py < h; py += ih) // Y position on pattern plane
565  {
566  const int dh = (py + ih >= h) ? h - py : ih;
567  const int dstY = py + yOffset;
568 
569  for (int px = 0; px < w; px += iw) // X position on pattern plane
570  {
571  const int dw = (px + iw >= w) ? w - px : iw;
572  const int dstX = px + xOffset;
573 
574  SDL_Rect srcRect =
575  {
576  CAST_S16(srcX),
577  CAST_S16(srcY),
578  CAST_U16(dw),
579  CAST_U16(dh)
580  };
581 
582  SDL_Rect dstRect =
583  {
584  CAST_S16(dstX),
585  CAST_S16(dstY),
586  0,
587  0
588  };
589 
590  SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect,
591  mWindow, &dstRect);
592  }
593  }
594 
595  delete tmpImage;
596 }
597 
599  const Image *restrict const image,
600  const int x, const int y,
601  const int w, const int h) const restrict2
602 {
603  calcPatternInline(vert, image, x, y, w, h);
604 }
605 
607  const Image *restrict const image,
608  const int x, const int y,
609  const int w, const int h) const restrict2
610 {
611  // Check that preconditions for blitting are met.
612  if (vert == nullptr ||
613  mWindow == nullptr ||
614  image == nullptr ||
615  image->mSDLSurface == nullptr)
616  {
617  return;
618  }
619 
620  const SDL_Rect &bounds = image->mBounds;
621  const int iw = bounds.w;
622  const int ih = bounds.h;
623  if (iw == 0 || ih == 0)
624  return;
625 
626  const ClipRect &top = mClipStack.top();
627  const int xOffset = top.xOffset + x;
628  const int yOffset = top.yOffset + y;
629  const int srcX = bounds.x;
630  const int srcY = bounds.y;
631 
632  for (int py = 0; py < h; py += ih) // Y position on pattern plane
633  {
634  const int dh = (py + ih >= h) ? h - py : ih;
635  const int dstY = py + yOffset;
636 
637  for (int px = 0; px < w; px += iw) // X position on pattern plane
638  {
639  const int dw = (px + iw >= w) ? w - px : iw;
640  const int dstX = px + xOffset;
641 
642  DoubleRect *const r = new DoubleRect;
643  SDL_Rect &srcRect = r->src;
644  srcRect.x = CAST_S16(srcX);
645  srcRect.y = CAST_S16(srcY);
646  srcRect.w = CAST_U16(dw);
647  srcRect.h = CAST_U16(dh);
648  SDL_Rect &dstRect = r->dst;
649  dstRect.x = CAST_S16(dstX);
650  dstRect.y = CAST_S16(dstY);
651 
652  if (SDL_FakeUpperBlit(image->mSDLSurface, &srcRect,
653  mWindow, &dstRect) == 1)
654  {
655  vert->sdl.push_back(r);
656  }
657  else
658  {
659  delete r;
660  }
661  }
662  }
663 }
664 
666  const Image *restrict const image,
667  const int x, const int y,
668  const int w, const int h) const restrict2
669 {
670  if (vertCol == nullptr || image == nullptr)
671  return;
672 
673  ImageVertexes *vert = nullptr;
674  if (vertCol->currentImage != image)
675  {
676  vert = new ImageVertexes;
677  vertCol->currentImage = image;
678  vertCol->currentVert = vert;
679  vert->image = image;
680  vertCol->draws.push_back(vert);
681  }
682  else
683  {
684  vert = vertCol->currentVert;
685  }
686 
687  calcPatternInline(vert, image, x, y, w, h);
688 }
689 
691  const Image *restrict const image,
692  int x, int y) const restrict2
693 {
694  vert->image = image;
695  calcTileSDL(vert, x, y);
696 }
697 
699  const Image *restrict const image,
700  int x, int y) const restrict2
701 {
702  vert->image = image;
703  calcTileSDL(vert, x, y);
704 }
705 
707  int x, int y) const restrict2
708 {
709  // Check that preconditions for blitting are met.
710  if (vert == nullptr ||
711  vert->image == nullptr ||
712  vert->image->mSDLSurface == nullptr)
713  {
714  return;
715  }
716 
717  const Image *const image = vert->image;
718  const ClipRect &top = mClipStack.top();
719  const SDL_Rect &bounds = image->mBounds;
720 
721  DoubleRect *rect = new DoubleRect;
722  rect->src.x = CAST_S16(bounds.x);
723  rect->src.y = CAST_S16(bounds.y);
724  rect->src.w = CAST_U16(bounds.w);
725  rect->src.h = CAST_U16(bounds.h);
726  rect->dst.x = CAST_S16(x + top.xOffset);
727  rect->dst.y = CAST_S16(y + top.yOffset);
728  if (SDL_FakeUpperBlit(image->mSDLSurface, &rect->src,
729  mWindow, &rect->dst) == 1)
730  {
731  vert->sdl.push_back(rect);
732  }
733  else
734  {
735  delete rect;
736  }
737 }
738 
740  const Image *restrict const image,
741  int x, int y) restrict2
742 {
743  if (vertCol == nullptr)
744  return;
745  if (vertCol->currentImage != image)
746  {
747  ImageVertexes *const vert = new ImageVertexes;
748  vertCol->currentImage = image;
749  vertCol->currentVert = vert;
750  vert->image = image;
751  vertCol->draws.push_back(vert);
752  calcTileSDL(vert, x, y);
753  }
754  else
755  {
756  calcTileSDL(vertCol->currentVert, x, y);
757  }
758 }
759 
761  *restrict const vertCol) restrict2
762 {
763  const ImageVertexesVector &draws = vertCol->draws;
764  const ImageCollectionCIter it_end = draws.end();
765  for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
766  {
767  const ImageVertexes *const vert = *it;
768  const Image *const img = vert->image;
769  const DoubleRects *const rects = &vert->sdl;
770  DoubleRects::const_iterator it2 = rects->begin();
771  const DoubleRects::const_iterator it2_end = rects->end();
772  while (it2 != it2_end)
773  {
774  SDL_LowerBlit(img->mSDLSurface, &(*it2)->src,
775  mWindow, &(*it2)->dst);
776  ++ it2;
777  }
778  }
779 }
780 
782  restrict const vert) restrict2
783 {
784  if (vert == nullptr)
785  return;
786  // vert and img must be != 0
787  const Image *const img = vert->image;
788  const DoubleRects *const rects = &vert->sdl;
789  DoubleRects::const_iterator it = rects->begin();
790  const DoubleRects::const_iterator it_end = rects->end();
791  while (it != it_end)
792  {
793  SDL_LowerBlit(img->mSDLSurface, &(*it)->src, mWindow, &(*it)->dst);
794  ++ it;
795  }
796 }
797 
799 {
800  BLOCK_START("Graphics::updateScreen")
801  if (mDoubleBuffer)
802  {
803  SDL_Flip(mWindow);
804  }
805  else
806  {
807  SDL_UpdateRects(mWindow, 1, &mRect);
808 // SDL_UpdateRect(mWindow, 0, 0, 0, 0);
809  }
810  BLOCK_END("Graphics::updateScreen")
811 }
812 
814  const int x, const int y,
815  const int w, const int h,
816  const ImageRect &restrict imgRect) restrict2
817 {
818  ImageVertexes *vert = nullptr;
819  Image *const image = imgRect.grid[4];
820  if (image == nullptr)
821  return;
822  if (vertCol->currentImage != image)
823  {
824  vert = new ImageVertexes;
825  vertCol->currentImage = image;
826  vertCol->currentVert = vert;
827  vert->image = image;
828  vertCol->draws.push_back(vert);
829  }
830  else
831  {
832  vert = vertCol->currentVert;
833  }
834  calcImageRect(vert, x, y, w, h, imgRect);
835 }
836 
837 int SDLGraphics::SDL_FakeUpperBlit(const SDL_Surface *restrict const src,
838  SDL_Rect *restrict const srcrect,
839  const SDL_Surface *restrict const dst,
840  SDL_Rect *restrict dstrect) const restrict2
841 {
842  int srcx;
843  int srcy;
844  int w;
845  int h;
846 
847  // Make sure the surfaces aren't locked
848  if ((src == nullptr) || (dst == nullptr))
849  return -1;
850 
851  if ((srcrect == nullptr) || (dstrect == nullptr))
852  return -1;
853 
854  srcx = srcrect->x;
855  w = srcrect->w;
856  if (srcx < 0)
857  {
858  w += srcx;
859  dstrect->x -= CAST_S16(srcx);
860  srcx = 0;
861  }
862  int maxw = src->w - srcx;
863  if (maxw < w)
864  w = maxw;
865 
866  srcy = srcrect->y;
867  h = srcrect->h;
868  if (srcy < 0)
869  {
870  h += srcy;
871  dstrect->y -= CAST_S16(srcy);
872  srcy = 0;
873  }
874  int maxh = src->h - srcy;
875  if (maxh < h)
876  h = maxh;
877 
878  const SDL_Rect *const clip = &dst->clip_rect;
879  const int clipX = clip->x;
880  const int clipY = clip->y;
881  int dx = clipX - dstrect->x;
882  if (dx > 0)
883  {
884  w -= dx;
885  dstrect->x += CAST_S16(dx);
886  srcx += dx;
887  }
888  dx = dstrect->x + w - clipX - clip->w;
889  if (dx > 0)
890  w -= dx;
891 
892  int dy = clipY - dstrect->y;
893  if (dy > 0)
894  {
895  h -= dy;
896  dstrect->y += CAST_S16(dy);
897  srcy += dy;
898  }
899  dy = dstrect->y + h - clipY - clip->h;
900  if (dy > 0)
901  h -= dy;
902 
903  if (w > 0 && h > 0)
904  {
905  srcrect->x = CAST_S16(srcx);
906  srcrect->y = CAST_S16(srcy);
907  srcrect->w = CAST_S16(w);
908  srcrect->h = CAST_S16(h);
909  dstrect->w = CAST_S16(w);
910  dstrect->h = CAST_S16(h);
911 
912  return 1;
913 // return SDL_LowerBlit(src, &sr, dst, dstrect);
914  }
915  dstrect->w = dstrect->h = 0;
916  return 0;
917 }
918 
920 {
921  FUNC_BLOCK("Graphics::fillRectangle", 1)
922  if (mClipStack.empty())
923  return;
924 
925  const ClipRect &restrict top = mClipStack.top();
926 
927  Rect area = rectangle;
928  area.x += top.xOffset;
929  area.y += top.yOffset;
930 
931  if (!area.isIntersecting(top))
932  return;
933 
934  if (mAlpha)
935  {
936  const int x1 = area.x > top.x ? area.x : top.x;
937  const int y1 = area.y > top.y ? area.y : top.y;
938  const int x2 = area.x + area.width < top.x + top.width ?
939  area.x + area.width : top.x + top.width;
940  const int y2 = area.y + area.height < top.y + top.height ?
941  area.y + area.height : top.y + top.height;
942 
943  SDL_LockSurface(mWindow);
944 
945  const int bpp = mWindow->format->BytesPerPixel;
946  const uint32_t pixel = SDL_MapRGB(mWindow->format,
948  CAST_U8(mColor.b));
949 
950  switch (bpp)
951  {
952  case 1:
953  for (int y = y1; y < y2; y++)
954  {
955  uint8_t *const p = static_cast<uint8_t *>(mWindow->pixels)
956  + CAST_SIZE(y * mWindow->pitch);
957  for (int x = x1; x < x2; x++)
958  {
959  *(p + CAST_SIZE(x))
960  = CAST_U8(pixel);
961  }
962  }
963  break;
964  case 2:
965  for (int y = y1; y < y2; y++)
966  {
967  uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
968  + CAST_SIZE(y * mWindow->pitch);
969  for (int x = x1; x < x2; x++)
970  {
971  uint8_t *const p = p0 + CAST_SIZE(x * 2);
972  *reinterpret_cast<uint16_t *>(p) = SDLAlpha16(
973  CAST_U16(pixel),
974  *reinterpret_cast<uint16_t *>(p),
975  CAST_U8(mColor.a), mWindow->format);
976  }
977  }
978  break;
979  case 3:
980  {
981  const int ca = 255 - mColor.a;
982  const int cr = mColor.r * mColor.a;
983  const int cg = mColor.g * mColor.a;
984  const int cb = mColor.b * mColor.a;
985 
986  for (int y = y1; y < y2; y++)
987  {
988  uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
989  + CAST_SIZE(y * mWindow->pitch);
990  for (int x = x1; x < x2; x++)
991  {
992  uint8_t *const p = p0 + CAST_SIZE(x * 3);
993 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
994  p[2] = CAST_U8((p[2] * ca + cb) >> 8);
995  p[1] = CAST_U8((p[1] * ca + cg) >> 8);
996  p[0] = CAST_U8((p[0] * ca + cr) >> 8);
997 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
998  p[0] = CAST_U8((p[0] * ca + cb) >> 8);
999  p[1] = CAST_U8((p[1] * ca + cg) >> 8);
1000  p[2] = CAST_U8((p[2] * ca + cr) >> 8);
1001 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
1002  }
1003  }
1004  break;
1005  }
1006  case 4:
1007  {
1008 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1009  const unsigned pb = (pixel & 0xff) * mColor.a;
1010  const unsigned pg = (pixel & 0xff00) * mColor.a;
1011  const unsigned pr = (pixel & 0xff0000) * mColor.a;
1012  const unsigned a1 = (255 - mColor.a);
1013 
1014  for (int y = y1; y < y2; y++)
1015  {
1016  uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
1017  + y * mWindow->pitch;
1018  for (int x = x1; x < x2; x++)
1019  {
1020  uint8_t *p = p0 + x * 4;
1021  uint32_t dst = *reinterpret_cast<uint32_t *>(p);
1022  const unsigned int b = (pb + (dst & 0xff) * a1) >> 8;
1023  const unsigned int g = (pg + (dst & 0xff00) * a1) >> 8;
1024  const unsigned int r = (pr
1025  + (dst & 0xff0000) * a1) >> 8;
1026 
1027  *reinterpret_cast<uint32_t *>(p) = ((b & 0xff)
1028  | (g & 0xff00) | (r & 0xff0000));
1029  }
1030  }
1031 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
1032  if (cR == nullptr)
1033  {
1034  cR = new unsigned int[0x100];
1035  cG = new unsigned int[0x100];
1036  cB = new unsigned int[0x100];
1037  mOldPixel = 0;
1038  mOldAlpha = mColor.a;
1039  }
1040 
1041  const SDL_PixelFormat * const format = mWindow->format;
1042  const unsigned rMask = format->Rmask;
1043  const unsigned gMask = format->Gmask;
1044  const unsigned bMask = format->Bmask;
1045 // const unsigned aMask = format->Amask;
1046  unsigned rShift = rMask / 0xff;
1047  unsigned gShift = gMask / 0xff;
1048  unsigned bShift = bMask / 0xff;
1049  if (rShift == 0U)
1050  rShift = 1;
1051  if (gShift == 0U)
1052  gShift = 1;
1053  if (bShift == 0U)
1054  bShift = 1;
1055  if (pixel != mOldPixel || mColor.a != mOldAlpha)
1056  {
1057  const unsigned pb = (pixel & bMask) * mColor.a;
1058  const unsigned pg = (pixel & gMask) * mColor.a;
1059  const unsigned pr = (pixel & rMask) * mColor.a;
1060  const unsigned a0 = 255 - mColor.a;
1061 
1062  const unsigned int a1 = a0 * bShift;
1063  const unsigned int a2 = a0 * gShift;
1064  const unsigned int a3 = a0 * rShift;
1065 
1066  for (int f = 0; f <= 0xff; f ++)
1067  {
1068  cB[f] = ((pb + f * a1) >> 8) & bMask;
1069  cG[f] = ((pg + f * a2) >> 8) & gMask;
1070  cR[f] = ((pr + f * a3) >> 8) & rMask;
1071  }
1072 
1073  mOldPixel = pixel;
1074  mOldAlpha = mColor.a;
1075  }
1076 
1077  for (int y = y1; y < y2; y++)
1078  {
1079  uint32_t *const p0 = reinterpret_cast<uint32_t*>(
1080  static_cast<uint8_t*>(mWindow->pixels)
1081  + CAST_SIZE(y * mWindow->pitch));
1082  for (int x = x1; x < x2; x++)
1083  {
1084  uint32_t *const p = p0 + CAST_SIZE(x);
1085  const uint32_t dst = *p;
1086  *p = cB[dst & bMask / bShift]
1087  | cG[(dst & gMask) / gShift]
1088  | cR[(dst & rMask) / rShift];
1089  }
1090  }
1091 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
1092  break;
1093  }
1094  default:
1095  break;
1096  }
1097 
1098  SDL_UnlockSurface(mWindow);
1099  }
1100  else
1101  {
1102  SDL_Rect rect =
1103  {
1104  CAST_S16(area.x),
1105  CAST_S16(area.y),
1106  CAST_U16(area.width),
1107  CAST_U16(area.height)
1108  };
1109 
1110  const uint32_t color = SDL_MapRGBA(mWindow->format,
1111  CAST_S8(mColor.r),
1112  CAST_S8(mColor.g),
1113  CAST_S8(mColor.b),
1114  CAST_S8(mColor.a));
1115  SDL_FillRect(mWindow, &rect, color);
1116  }
1117 }
1118 
1120 {
1121  pushClipArea(Rect(0, 0, mRect.w, mRect.h));
1122 }
1123 
1125 {
1126  popClipArea();
1127 }
1128 
1130 {
1131  Graphics::pushClipArea(area);
1132  const ClipRect &restrict carea = mClipStack.top();
1133  const SDL_Rect rect =
1134  {
1135  CAST_S16(carea.x),
1136  CAST_S16(carea.y),
1137  CAST_U16(carea.width),
1138  CAST_U16(carea.height)
1139  };
1140  SDL_SetClipRect(mWindow, &rect);
1141 }
1142 
1144 {
1146 
1147  if (mClipStack.empty())
1148  return;
1149 
1150  const ClipRect &restrict carea = mClipStack.top();
1151  const SDL_Rect rect =
1152  {
1153  CAST_S16(carea.x),
1154  CAST_S16(carea.y),
1155  CAST_U16(carea.width),
1156  CAST_U16(carea.height)
1157  };
1158 
1159  SDL_SetClipRect(mWindow, &rect);
1160 }
1161 
1163 {
1164  if (mClipStack.empty())
1165  return;
1166 
1167  const ClipRect& top = mClipStack.top();
1168 
1169  x += top.xOffset;
1170  y += top.yOffset;
1171 
1172  if (!top.isPointInRect(x, y))
1173  return;
1174 
1175  if (mAlpha)
1177  else
1179 }
1180 
1181 void SDLGraphics::drawHLine(int x1, int y, int x2) restrict2
1182 {
1183  if (mClipStack.empty())
1184  return;
1185 
1186  const ClipRect& top = mClipStack.top();
1187 
1188  const int xOffset = top.xOffset;
1189  x1 += xOffset;
1190  y += top.yOffset;
1191  x2 += xOffset;
1192 
1193  const int topY = top.y;
1194  if (y < topY || y >= topY + top.height)
1195  return;
1196 
1197  if (x1 > x2)
1198  {
1199  x1 ^= x2;
1200  x2 ^= x1;
1201  x1 ^= x2;
1202  }
1203 
1204  const int topX = top.x;
1205  if (topX > x1)
1206  {
1207  if (topX > x2)
1208  return;
1209 
1210  x1 = topX;
1211  }
1212 
1213  const int sumX = topX + top.width;
1214  if (sumX <= x2)
1215  {
1216  if (sumX <= x1)
1217  return;
1218 
1219  x2 = sumX -1;
1220  }
1221 
1222  const int bpp = mWindow->format->BytesPerPixel;
1223 
1224  SDL_LockSurface(mWindow);
1225 
1226  uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1227  + CAST_SIZE(y * mWindow->pitch + x1 * bpp);
1228 
1229  const uint32_t pixel = SDL_MapRGB(mWindow->format,
1230  CAST_U8(mColor.r),
1231  CAST_U8(mColor.g),
1232  CAST_U8(mColor.b));
1233  switch (bpp)
1234  {
1235  case 1:
1236  for (; x1 <= x2; ++x1)
1237  *(p++) = CAST_U8(pixel);
1238  break;
1239 
1240  case 2:
1241  {
1242  uint16_t* q = reinterpret_cast<uint16_t*>(p);
1243  const uint16_t pixel1 = CAST_U16(pixel);
1244  for (; x1 <= x2; ++x1)
1245  *(q++) = pixel1;
1246  break;
1247  }
1248 
1249  case 3:
1250  {
1251  const uint8_t b0 = CAST_U8((pixel >> 16) & 0xff);
1252  const uint8_t b1 = CAST_U8((pixel >> 8) & 0xff);
1253  const uint8_t b2 = CAST_U8(pixel & 0xff);
1254 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1255  for (; x1 <= x2; ++x1)
1256  {
1257  p[0] = b0;
1258  p[1] = b1;
1259  p[2] = b2;
1260  p += 3;
1261  }
1262 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
1263  for (; x1 <= x2; ++x1)
1264  {
1265  p[0] = b2;
1266  p[1] = b1;
1267  p[2] = b0;
1268  p += 3;
1269  }
1270 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
1271  break;
1272  }
1273 
1274  case 4:
1275  {
1276  uint32_t *q = reinterpret_cast<uint32_t*>(p);
1277  if (mAlpha)
1278  {
1279  unsigned char a = CAST_U8(mColor.a);
1280  unsigned char a1 = CAST_U8(255U - a);
1281  const int b0 = (pixel & 0xff) * a;
1282  const int g0 = (pixel & 0xff00) * a;
1283  const int r0 = (pixel & 0xff0000) * a;
1284  for (; x1 <= x2; ++x1)
1285  {
1286  const unsigned int b = (b0 + (*q & 0xff) * a1) >> 8;
1287  const unsigned int g = (g0 + (*q & 0xff00) * a1) >> 8;
1288  const unsigned int r = (r0 + (*q & 0xff0000) * a1) >> 8;
1289  *q = (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1290 
1291  q++;
1292  }
1293  }
1294  else
1295  {
1296  for (; x1 <= x2; ++x1)
1297  *(q++) = pixel;
1298  }
1299  break;
1300  }
1301  default:
1302  break;
1303  } // end switch
1304 
1305  SDL_UnlockSurface(mWindow);
1306 }
1307 
1308 void SDLGraphics::drawVLine(int x, int y1, int y2) restrict2
1309 {
1310  if (mClipStack.empty())
1311  return;
1312 
1313  const ClipRect &restrict top = mClipStack.top();
1314 
1315  const int yOffset = top.yOffset;
1316  x += top.xOffset;
1317  y1 += yOffset;
1318  y2 += yOffset;
1319 
1320  if (x < top.x || x >= top.x + top.width)
1321  return;
1322 
1323  if (y1 > y2)
1324  {
1325  y1 ^= y2;
1326  y2 ^= y1;
1327  y1 ^= y2;
1328  }
1329 
1330  if (top.y > y1)
1331  {
1332  if (top.y > y2)
1333  return;
1334 
1335  y1 = top.y;
1336  }
1337 
1338  const int sumY = top.y + top.height;
1339  if (sumY <= y2)
1340  {
1341  if (sumY <= y1)
1342  return;
1343 
1344  y2 = sumY - 1;
1345  }
1346 
1347  const int bpp = mWindow->format->BytesPerPixel;
1348 
1349  SDL_LockSurface(mWindow);
1350 
1351  uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1352  + CAST_SIZE(y1 * mWindow->pitch + x * bpp);
1353 
1354  const uint32_t pixel = SDL_MapRGB(mWindow->format,
1355  CAST_U8(mColor.r),
1356  CAST_U8(mColor.g),
1357  CAST_U8(mColor.b));
1358 
1359  const int pitch = mWindow->pitch;
1360  switch (bpp)
1361  {
1362  case 1:
1363  for (; y1 <= y2; ++y1)
1364  {
1365  *p = CAST_U8(pixel);
1366  p += pitch;
1367  }
1368  break;
1369 
1370  case 2:
1371  for (; y1 <= y2; ++ y1)
1372  {
1373  *reinterpret_cast<uint16_t*>(p)
1374  = CAST_U16(pixel);
1375  p += pitch;
1376  }
1377  break;
1378 
1379  case 3:
1380  {
1381  const uint8_t b0 = CAST_U8((pixel >> 16) & 0xff);
1382  const uint8_t b1 = CAST_U8((pixel >> 8) & 0xff);
1383  const uint8_t b2 = CAST_U8(pixel & 0xff);
1384 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1385  for (; y1 <= y2; ++y1)
1386  {
1387  p[0] = b0;
1388  p[1] = b1;
1389  p[2] = b2;
1390  p += pitch;
1391  }
1392 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
1393  for (; y1 <= y2; ++y1)
1394  {
1395  p[0] = b2;
1396  p[1] = b1;
1397  p[2] = b0;
1398  p += pitch;
1399  }
1400 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
1401  break;
1402  }
1403 
1404  case 4:
1405  {
1406  if (mAlpha)
1407  {
1408  unsigned char a = CAST_U8(mColor.a);
1409  unsigned char a1 = CAST_U8(255U - a);
1410  const int b0 = (pixel & 0xff) * a;
1411  const int g0 = (pixel & 0xff00) * a;
1412  const int r0 = (pixel & 0xff0000) * a;
1413  for (; y1 <= y2; ++y1)
1414  {
1415  const unsigned int dst = *reinterpret_cast<uint32_t*>(p);
1416  const unsigned int b = (b0 + (dst & 0xff) * a1) >> 8;
1417  const unsigned int g = (g0 + (dst & 0xff00) * a1) >> 8;
1418  const unsigned int r = (r0 + (dst & 0xff0000) * a1) >> 8;
1419  *reinterpret_cast<uint32_t*>(p) =
1420  (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1421 
1422  p += pitch;
1423  }
1424  }
1425  else
1426  {
1427  for (; y1 <= y2; ++y1)
1428  {
1429  *reinterpret_cast<uint32_t*>(p) = pixel;
1430  p += pitch;
1431  }
1432  }
1433  break;
1434  }
1435 
1436  default:
1437  break;
1438  } // end switch
1439 
1440  SDL_UnlockSurface(mWindow);
1441 }
1442 
1444 {
1445  const int x1 = rectangle.x;
1446  const int x2 = x1 + rectangle.width - 1;
1447  const int y1 = rectangle.y;
1448  const int y2 = y1 + rectangle.height - 1;
1449 
1450  drawHLine(x1, y1, x2);
1451  drawHLine(x1, y2, x2);
1452 
1453  drawVLine(x1, y1, y2);
1454  drawVLine(x2, y1, y2);
1455 }
1456 
1457 void SDLGraphics::drawLine(int x1, int y1,
1458  int x2, int y2) restrict2
1459 {
1460  if (x1 == x2)
1461  {
1462  drawVLine(x1, y1, y2);
1463  return;
1464  }
1465  if (y1 == y2)
1466  {
1467  drawHLine(x1, y1, x2);
1468  return;
1469  }
1470 
1471  // other cases not implemented
1472 }
1473 
1474 bool SDLGraphics::setVideoMode(const int w, const int h,
1475  const int scale,
1476  const int bpp,
1477  const bool fs,
1478  const bool hwaccel,
1479  const bool resize,
1480  const bool noFrame,
1481  const bool allowHighDPI) restrict2
1482 {
1483  setMainFlags(w, h,
1484  scale,
1485  bpp,
1486  fs,
1487  hwaccel,
1488  resize,
1489  noFrame,
1490  allowHighDPI);
1491 
1492  if ((mWindow = graphicsManager.createWindow(w, h, bpp,
1493  getSoftwareFlags())) == nullptr)
1494  {
1495  mRect.w = 0;
1496  mRect.h = 0;
1497  return false;
1498  }
1499 
1500  mRect.w = CAST_U16(mWindow->w);
1501  mRect.h = CAST_U16(mWindow->h);
1502 
1503  return videoInfo();
1504 }
1505 
1506 void SDLGraphics::drawImageRect(const int x, const int y,
1507  const int w, const int h,
1508  const ImageRect &restrict imgRect) restrict2
1509 {
1511 }
1512 
1514  const int x, const int y,
1515  const int w, const int h,
1516  const ImageRect &restrict imgRect) restrict2
1517 {
1519 }
1520 
1521 #endif // USE_SDL2
void completeCache()
void setMainFlags(const int w, const int h, const int scale, const int bpp, const bool fs, const bool hwaccel, const bool resize, const bool noFrame, const bool allowHighDPI)
Definition: graphics.cpp:181
unsigned int mOldAlpha
Definition: sdlgraphics.h:71
void calcPattern(ImageVertexes *const vert, const Image *const image, const int x, const int y, const int w, const int h) const
int width
Definition: rect.h:218
SDL_Surface * createWindow(const int w, const int h, const int bpp, const int flags)
void drawTileCollection(const ImageCollection *const vertCol)
#define CAST_U8
Definition: cast.h:26
std::string mName
Definition: graphics.h:548
SDL_Surface * mWindow
Definition: graphics.h:522
RenderType mOpenGL
Definition: graphics.h:544
void calcPatternInline(ImageVertexes *const vert, const Image *const image, const int x, const int y, const int w, const int h) const A_INLINE
void updateScreen()
unsigned int a
Definition: color.h:250
void calcWindow(ImageCollection *const vertCol, const int x, const int y, const int w, const int h, const ImageRect &imgRect)
static unsigned int * cR
Definition: sdlgraphics.cpp:46
bool isIntersecting(const Rect &rectangle) const
Definition: rect.h:153
void copyImage(const Image *const image, int dstX, int dstY)
std::vector< ImageVertexes * > ImageVertexesVector
Definition: imagevertexes.h:55
unsigned int g
Definition: color.h:239
Definition: rect.h:72
void pushClipArea(const Rect &area)
#define BLOCK_START(name)
Definition: perfomance.h:78
const Image * image
Definition: imagevertexes.h:47
void drawRectangle(const Rect &rect)
bool isPointInRect(const int x_, const int y_) const
Definition: rect.h:196
static unsigned int * cG
Definition: sdlgraphics.cpp:47
void drawImageInline(const Image *const image, int dstX, int dstY) A_INLINE
#define BLOCK_END(name)
Definition: perfomance.h:79
int yOffset
Definition: cliprect.h:126
virtual void popClipArea()
Definition: graphics.cpp:738
const Image *restrict const top
void beginDraw()
ImageVertexesVector::const_iterator ImageCollectionCIter
Definition: imagevertexes.h:57
void drawRescaledImage(const Image *const image, int dstX, int dstY, const int desiredWidth, const int desiredHeight)
Definition: sdlgraphics.cpp:64
void drawImageRect(int x, int y, int w, int h, const ImageRect &imgRect)
Color mColor
Definition: graphics.h:552
DoubleRects sdl
Definition: imagevertexes.h:52
int x
Definition: rect.h:208
#define CAST_U16
Definition: cast.h:28
static unsigned int * cB
Definition: sdlgraphics.cpp:48
SDL_Surface * mSDLSurface
Definition: image.h:231
unsigned int b
Definition: color.h:244
void SDLputPixel(SDL_Surface *surface, int x, int y, const Color &color)
Definition: sdlpixel.h:85
void calcTileVertexes(ImageVertexes *const vert, const Image *const image, int x, int y) const
bool setVideoMode(const int w, const int h, const int scalle, const int bpp, const bool fs, const bool hwaccel, const bool resize, const bool noFrame, const bool allowHighDPI)
void fillRectangle(const Rect &rect)
void drawTileVertexes(const ImageVertexes *const vert)
int xOffset
Definition: cliprect.h:121
int y
Definition: rect.h:213
bool mAlpha
Definition: graphics.h:537
uint32_t mOldPixel
Definition: sdlgraphics.h:70
void calcImageRect(ImageVertexes *const vert, int x, int y, int w, int h, const ImageRect &imgRect) A_INLINE
void SDLputPixelAlpha(SDL_Surface *surface, int x, int y, const Color &color)
Definition: sdlpixel.h:192
#define CAST_S8
Definition: cast.h:25
int getSoftwareFlags() const
Definition: graphics.cpp:388
int height
Definition: rect.h:223
bool mDoubleBuffer
Definition: graphics.h:541
Image * SDLgetScaledImage(const int width, const int height) const
Definition: image.cpp:436
void drawVLine(int x, int y1, int y2)
SDL_Rect dst
Definition: doublerect.h:36
#define FUNC_BLOCK(name, id)
Definition: perfomance.h:80
SDL_Rect mRect
Definition: graphics.h:542
void drawHLine(int x1, int y, int x2)
void drawPatternInline(const Image *const image, const int x, const int y, const int w, const int h) A_INLINE
void drawLine(int x1, int y1, int x2, int y2)
void drawRescaledPattern(const Image *const image, const int x, const int y, const int w, const int h, const int scaledWidth, const int scaledHeight)
unsigned short SDLAlpha16(const unsigned short src, const unsigned short dst, const unsigned char a, const SDL_PixelFormat *const f)
Definition: sdlpixel.h:169
std::vector< DoubleRect * > DoubleRects
Definition: imagevertexes.h:34
void calcTileSDL(ImageVertexes *const vert, int x, int y) const
SDL_Rect src
Definition: doublerect.h:35
MStack< ClipRect > mClipStack
Definition: graphics.h:520
void drawPatternCached(const Image *const image, const int x, const int y, const int w, const int h)
Definition: image.h:61
virtual void pushClipArea(const Rect &area)
Definition: graphics.cpp:676
#define restrict
Definition: localconsts.h:164
bool videoInfo()
Definition: graphics.cpp:482
#define CAST_SIZE
Definition: cast.h:33
SDL_Rect mBounds
Definition: image.h:210
#define CAST_S16
Definition: cast.h:27
void drawPattern(const Image *const image, const int x, const int y, const int w, const int h)
void drawImageCached(const Image *const image, int x, int y)
T & top() const
Definition: mstack.h:72
void drawImage(const Image *const image, int dstX, int dstY)
int SDL_FakeUpperBlit(const SDL_Surface *const src, SDL_Rect *const srcrect, const SDL_Surface *const dst, SDL_Rect *dstrect) const
void calcTileCollection(ImageCollection *const vertCol, const Image *const image, int x, int y)
bool empty() const
Definition: mstack.h:87
void popClipArea()
GraphicsManager graphicsManager
#define restrict2
Definition: localconsts.h:165
unsigned int r
Definition: color.h:234
void calcTileVertexesInline(ImageVertexes *const vert, const Image *const image, int x, int y) const A_INLINE
void drawPoint(int x, int y)