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, srcy, w, h;
843 
844  // Make sure the surfaces aren't locked
845  if ((src == nullptr) || (dst == nullptr))
846  return -1;
847 
848  if ((srcrect == nullptr) || (dstrect == nullptr))
849  return -1;
850 
851  srcx = srcrect->x;
852  w = srcrect->w;
853  if (srcx < 0)
854  {
855  w += srcx;
856  dstrect->x -= CAST_S16(srcx);
857  srcx = 0;
858  }
859  int maxw = src->w - srcx;
860  if (maxw < w)
861  w = maxw;
862 
863  srcy = srcrect->y;
864  h = srcrect->h;
865  if (srcy < 0)
866  {
867  h += srcy;
868  dstrect->y -= CAST_S16(srcy);
869  srcy = 0;
870  }
871  int maxh = src->h - srcy;
872  if (maxh < h)
873  h = maxh;
874 
875  const SDL_Rect *const clip = &dst->clip_rect;
876  const int clipX = clip->x;
877  const int clipY = clip->y;
878  int dx = clipX - dstrect->x;
879  if (dx > 0)
880  {
881  w -= dx;
882  dstrect->x += CAST_S16(dx);
883  srcx += dx;
884  }
885  dx = dstrect->x + w - clipX - clip->w;
886  if (dx > 0)
887  w -= dx;
888 
889  int dy = clipY - dstrect->y;
890  if (dy > 0)
891  {
892  h -= dy;
893  dstrect->y += CAST_S16(dy);
894  srcy += dy;
895  }
896  dy = dstrect->y + h - clipY - clip->h;
897  if (dy > 0)
898  h -= dy;
899 
900  if (w > 0 && h > 0)
901  {
902  srcrect->x = CAST_S16(srcx);
903  srcrect->y = CAST_S16(srcy);
904  srcrect->w = CAST_S16(w);
905  srcrect->h = CAST_S16(h);
906  dstrect->w = CAST_S16(w);
907  dstrect->h = CAST_S16(h);
908 
909  return 1;
910 // return SDL_LowerBlit(src, &sr, dst, dstrect);
911  }
912  dstrect->w = dstrect->h = 0;
913  return 0;
914 }
915 
917 {
918  FUNC_BLOCK("Graphics::fillRectangle", 1)
919  if (mClipStack.empty())
920  return;
921 
922  const ClipRect &restrict top = mClipStack.top();
923 
924  Rect area = rectangle;
925  area.x += top.xOffset;
926  area.y += top.yOffset;
927 
928  if (!area.isIntersecting(top))
929  return;
930 
931  if (mAlpha)
932  {
933  const int x1 = area.x > top.x ? area.x : top.x;
934  const int y1 = area.y > top.y ? area.y : top.y;
935  const int x2 = area.x + area.width < top.x + top.width ?
936  area.x + area.width : top.x + top.width;
937  const int y2 = area.y + area.height < top.y + top.height ?
938  area.y + area.height : top.y + top.height;
939 
940  SDL_LockSurface(mWindow);
941 
942  const int bpp = mWindow->format->BytesPerPixel;
943  const uint32_t pixel = SDL_MapRGB(mWindow->format,
945  CAST_U8(mColor.b));
946 
947  switch (bpp)
948  {
949  case 1:
950  cilk_for (int y = y1; y < y2; y++)
951  {
952  uint8_t *const p = static_cast<uint8_t *>(mWindow->pixels)
953  + CAST_SIZE(y * mWindow->pitch);
954  for (int x = x1; x < x2; x++)
955  {
956  *(p + CAST_SIZE(x))
957  = CAST_U8(pixel);
958  }
959  }
960  break;
961  case 2:
962  cilk_for (int y = y1; y < y2; y++)
963  {
964  uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
965  + CAST_SIZE(y * mWindow->pitch);
966  for (int x = x1; x < x2; x++)
967  {
968  uint8_t *const p = p0 + CAST_SIZE(x * 2);
969  *reinterpret_cast<uint16_t *>(p) = SDLAlpha16(
970  CAST_U16(pixel),
971  *reinterpret_cast<uint16_t *>(p),
972  CAST_U8(mColor.a), mWindow->format);
973  }
974  }
975  break;
976  case 3:
977  {
978  const int ca = 255 - mColor.a;
979  const int cr = mColor.r * mColor.a;
980  const int cg = mColor.g * mColor.a;
981  const int cb = mColor.b * mColor.a;
982 
983  cilk_for (int y = y1; y < y2; y++)
984  {
985  uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
986  + CAST_SIZE(y * mWindow->pitch);
987  for (int x = x1; x < x2; x++)
988  {
989  uint8_t *const p = p0 + CAST_SIZE(x * 3);
990 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
991  p[2] = CAST_U8((p[2] * ca + cb) >> 8);
992  p[1] = CAST_U8((p[1] * ca + cg) >> 8);
993  p[0] = CAST_U8((p[0] * ca + cr) >> 8);
994 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
995  p[0] = CAST_U8((p[0] * ca + cb) >> 8);
996  p[1] = CAST_U8((p[1] * ca + cg) >> 8);
997  p[2] = CAST_U8((p[2] * ca + cr) >> 8);
998 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
999  }
1000  }
1001  break;
1002  }
1003  case 4:
1004  {
1005 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1006  const unsigned pb = (pixel & 0xff) * mColor.a;
1007  const unsigned pg = (pixel & 0xff00) * mColor.a;
1008  const unsigned pr = (pixel & 0xff0000) * mColor.a;
1009  const unsigned a1 = (255 - mColor.a);
1010 
1011  cilk_for (int y = y1; y < y2; y++)
1012  {
1013  uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
1014  + y * mWindow->pitch;
1015  for (int x = x1; x < x2; x++)
1016  {
1017  uint8_t *p = p0 + x * 4;
1018  uint32_t dst = *reinterpret_cast<uint32_t *>(p);
1019  const unsigned int b = (pb + (dst & 0xff) * a1) >> 8;
1020  const unsigned int g = (pg + (dst & 0xff00) * a1) >> 8;
1021  const unsigned int r = (pr
1022  + (dst & 0xff0000) * a1) >> 8;
1023 
1024  *reinterpret_cast<uint32_t *>(p) = ((b & 0xff)
1025  | (g & 0xff00) | (r & 0xff0000));
1026  }
1027  }
1028 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
1029  if (cR == nullptr)
1030  {
1031  cR = new unsigned int[0x100];
1032  cG = new unsigned int[0x100];
1033  cB = new unsigned int[0x100];
1034  mOldPixel = 0;
1035  mOldAlpha = mColor.a;
1036  }
1037 
1038  const SDL_PixelFormat * const format = mWindow->format;
1039  const unsigned rMask = format->Rmask;
1040  const unsigned gMask = format->Gmask;
1041  const unsigned bMask = format->Bmask;
1042 // const unsigned aMask = format->Amask;
1043  unsigned rShift = rMask / 0xff;
1044  unsigned gShift = gMask / 0xff;
1045  unsigned bShift = bMask / 0xff;
1046  if (rShift == 0u)
1047  rShift = 1;
1048  if (gShift == 0u)
1049  gShift = 1;
1050  if (bShift == 0u)
1051  bShift = 1;
1052  if (pixel != mOldPixel || mColor.a != mOldAlpha)
1053  {
1054  const unsigned pb = (pixel & bMask) * mColor.a;
1055  const unsigned pg = (pixel & gMask) * mColor.a;
1056  const unsigned pr = (pixel & rMask) * mColor.a;
1057  const unsigned a0 = 255 - mColor.a;
1058 
1059  const unsigned int a1 = a0 * bShift;
1060  const unsigned int a2 = a0 * gShift;
1061  const unsigned int a3 = a0 * rShift;
1062 
1063  for (int f = 0; f <= 0xff; f ++)
1064  {
1065  cB[f] = ((pb + f * a1) >> 8) & bMask;
1066  cG[f] = ((pg + f * a2) >> 8) & gMask;
1067  cR[f] = ((pr + f * a3) >> 8) & rMask;
1068  }
1069 
1070  mOldPixel = pixel;
1071  mOldAlpha = mColor.a;
1072  }
1073 
1074  cilk_for (int y = y1; y < y2; y++)
1075  {
1076  uint32_t *const p0 = reinterpret_cast<uint32_t*>(
1077  static_cast<uint8_t*>(mWindow->pixels)
1078  + CAST_SIZE(y * mWindow->pitch));
1079  for (int x = x1; x < x2; x++)
1080  {
1081  uint32_t *const p = p0 + CAST_SIZE(x);
1082  const uint32_t dst = *p;
1083  *p = cB[dst & bMask / bShift]
1084  | cG[(dst & gMask) / gShift]
1085  | cR[(dst & rMask) / rShift];
1086  }
1087  }
1088 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
1089  break;
1090  }
1091  default:
1092  break;
1093  }
1094 
1095  SDL_UnlockSurface(mWindow);
1096  }
1097  else
1098  {
1099  SDL_Rect rect =
1100  {
1101  CAST_S16(area.x),
1102  CAST_S16(area.y),
1103  CAST_U16(area.width),
1104  CAST_U16(area.height)
1105  };
1106 
1107  const uint32_t color = SDL_MapRGBA(mWindow->format,
1108  CAST_S8(mColor.r),
1109  CAST_S8(mColor.g),
1110  CAST_S8(mColor.b),
1111  CAST_S8(mColor.a));
1112  SDL_FillRect(mWindow, &rect, color);
1113  }
1114 }
1115 
1117 {
1118  pushClipArea(Rect(0, 0, mRect.w, mRect.h));
1119 }
1120 
1122 {
1123  popClipArea();
1124 }
1125 
1127 {
1128  Graphics::pushClipArea(area);
1129  const ClipRect &restrict carea = mClipStack.top();
1130  const SDL_Rect rect =
1131  {
1132  CAST_S16(carea.x),
1133  CAST_S16(carea.y),
1134  CAST_U16(carea.width),
1135  CAST_U16(carea.height)
1136  };
1137  SDL_SetClipRect(mWindow, &rect);
1138 }
1139 
1141 {
1143 
1144  if (mClipStack.empty())
1145  return;
1146 
1147  const ClipRect &restrict carea = mClipStack.top();
1148  const SDL_Rect rect =
1149  {
1150  CAST_S16(carea.x),
1151  CAST_S16(carea.y),
1152  CAST_U16(carea.width),
1153  CAST_U16(carea.height)
1154  };
1155 
1156  SDL_SetClipRect(mWindow, &rect);
1157 }
1158 
1160 {
1161  if (mClipStack.empty())
1162  return;
1163 
1164  const ClipRect& top = mClipStack.top();
1165 
1166  x += top.xOffset;
1167  y += top.yOffset;
1168 
1169  if (!top.isPointInRect(x, y))
1170  return;
1171 
1172  if (mAlpha)
1174  else
1176 }
1177 
1178 void SDLGraphics::drawHLine(int x1, int y, int x2) restrict2
1179 {
1180  if (mClipStack.empty())
1181  return;
1182 
1183  const ClipRect& top = mClipStack.top();
1184 
1185  const int xOffset = top.xOffset;
1186  x1 += xOffset;
1187  y += top.yOffset;
1188  x2 += xOffset;
1189 
1190  const int topY = top.y;
1191  if (y < topY || y >= topY + top.height)
1192  return;
1193 
1194  if (x1 > x2)
1195  {
1196  x1 ^= x2;
1197  x2 ^= x1;
1198  x1 ^= x2;
1199  }
1200 
1201  const int topX = top.x;
1202  if (topX > x1)
1203  {
1204  if (topX > x2)
1205  return;
1206 
1207  x1 = topX;
1208  }
1209 
1210  const int sumX = topX + top.width;
1211  if (sumX <= x2)
1212  {
1213  if (sumX <= x1)
1214  return;
1215 
1216  x2 = sumX -1;
1217  }
1218 
1219  const int bpp = mWindow->format->BytesPerPixel;
1220 
1221  SDL_LockSurface(mWindow);
1222 
1223  uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1224  + CAST_SIZE(y * mWindow->pitch + x1 * bpp);
1225 
1226  const uint32_t pixel = SDL_MapRGB(mWindow->format,
1227  CAST_U8(mColor.r),
1228  CAST_U8(mColor.g),
1229  CAST_U8(mColor.b));
1230  switch (bpp)
1231  {
1232  case 1:
1233  for (; x1 <= x2; ++x1)
1234  *(p++) = CAST_U8(pixel);
1235  break;
1236 
1237  case 2:
1238  {
1239  uint16_t* q = reinterpret_cast<uint16_t*>(p);
1240  const uint16_t pixel1 = CAST_U16(pixel);
1241  for (; x1 <= x2; ++x1)
1242  *(q++) = pixel1;
1243  break;
1244  }
1245 
1246  case 3:
1247  {
1248  const uint8_t b0 = CAST_U8((pixel >> 16) & 0xff);
1249  const uint8_t b1 = CAST_U8((pixel >> 8) & 0xff);
1250  const uint8_t b2 = CAST_U8(pixel & 0xff);
1251 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1252  for (; x1 <= x2; ++x1)
1253  {
1254  p[0] = b0;
1255  p[1] = b1;
1256  p[2] = b2;
1257  p += 3;
1258  }
1259 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
1260  for (; x1 <= x2; ++x1)
1261  {
1262  p[0] = b2;
1263  p[1] = b1;
1264  p[2] = b0;
1265  p += 3;
1266  }
1267 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
1268  break;
1269  }
1270 
1271  case 4:
1272  {
1273  uint32_t *q = reinterpret_cast<uint32_t*>(p);
1274  if (mAlpha)
1275  {
1276  unsigned char a = CAST_U8(mColor.a);
1277  unsigned char a1 = CAST_U8(255U - a);
1278  const int b0 = (pixel & 0xff) * a;
1279  const int g0 = (pixel & 0xff00) * a;
1280  const int r0 = (pixel & 0xff0000) * a;
1281  for (; x1 <= x2; ++x1)
1282  {
1283  const unsigned int b = (b0 + (*q & 0xff) * a1) >> 8;
1284  const unsigned int g = (g0 + (*q & 0xff00) * a1) >> 8;
1285  const unsigned int r = (r0 + (*q & 0xff0000) * a1) >> 8;
1286  *q = (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1287 
1288  q++;
1289  }
1290  }
1291  else
1292  {
1293  for (; x1 <= x2; ++x1)
1294  *(q++) = pixel;
1295  }
1296  break;
1297  }
1298  default:
1299  break;
1300  } // end switch
1301 
1302  SDL_UnlockSurface(mWindow);
1303 }
1304 
1305 void SDLGraphics::drawVLine(int x, int y1, int y2) restrict2
1306 {
1307  if (mClipStack.empty())
1308  return;
1309 
1310  const ClipRect &restrict top = mClipStack.top();
1311 
1312  const int yOffset = top.yOffset;
1313  x += top.xOffset;
1314  y1 += yOffset;
1315  y2 += yOffset;
1316 
1317  if (x < top.x || x >= top.x + top.width)
1318  return;
1319 
1320  if (y1 > y2)
1321  {
1322  y1 ^= y2;
1323  y2 ^= y1;
1324  y1 ^= y2;
1325  }
1326 
1327  if (top.y > y1)
1328  {
1329  if (top.y > y2)
1330  return;
1331 
1332  y1 = top.y;
1333  }
1334 
1335  const int sumY = top.y + top.height;
1336  if (sumY <= y2)
1337  {
1338  if (sumY <= y1)
1339  return;
1340 
1341  y2 = sumY - 1;
1342  }
1343 
1344  const int bpp = mWindow->format->BytesPerPixel;
1345 
1346  SDL_LockSurface(mWindow);
1347 
1348  uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1349  + CAST_SIZE(y1 * mWindow->pitch + x * bpp);
1350 
1351  const uint32_t pixel = SDL_MapRGB(mWindow->format,
1352  CAST_U8(mColor.r),
1353  CAST_U8(mColor.g),
1354  CAST_U8(mColor.b));
1355 
1356  const int pitch = mWindow->pitch;
1357  switch (bpp)
1358  {
1359  case 1:
1360  for (; y1 <= y2; ++y1)
1361  {
1362  *p = CAST_U8(pixel);
1363  p += pitch;
1364  }
1365  break;
1366 
1367  case 2:
1368  for (; y1 <= y2; ++ y1)
1369  {
1370  *reinterpret_cast<uint16_t*>(p)
1371  = CAST_U16(pixel);
1372  p += pitch;
1373  }
1374  break;
1375 
1376  case 3:
1377  {
1378  const uint8_t b0 = CAST_U8((pixel >> 16) & 0xff);
1379  const uint8_t b1 = CAST_U8((pixel >> 8) & 0xff);
1380  const uint8_t b2 = CAST_U8(pixel & 0xff);
1381 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1382  for (; y1 <= y2; ++y1)
1383  {
1384  p[0] = b0;
1385  p[1] = b1;
1386  p[2] = b2;
1387  p += pitch;
1388  }
1389 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
1390  for (; y1 <= y2; ++y1)
1391  {
1392  p[0] = b2;
1393  p[1] = b1;
1394  p[2] = b0;
1395  p += pitch;
1396  }
1397 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
1398  break;
1399  }
1400 
1401  case 4:
1402  {
1403  if (mAlpha)
1404  {
1405  unsigned char a = CAST_U8(mColor.a);
1406  unsigned char a1 = CAST_U8(255U - a);
1407  const int b0 = (pixel & 0xff) * a;
1408  const int g0 = (pixel & 0xff00) * a;
1409  const int r0 = (pixel & 0xff0000) * a;
1410  for (; y1 <= y2; ++y1)
1411  {
1412  const unsigned int dst = *reinterpret_cast<uint32_t*>(p);
1413  const unsigned int b = (b0 + (dst & 0xff) * a1) >> 8;
1414  const unsigned int g = (g0 + (dst & 0xff00) * a1) >> 8;
1415  const unsigned int r = (r0 + (dst & 0xff0000) * a1) >> 8;
1416  *reinterpret_cast<uint32_t*>(p) =
1417  (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1418 
1419  p += pitch;
1420  }
1421  }
1422  else
1423  {
1424  for (; y1 <= y2; ++y1)
1425  {
1426  *reinterpret_cast<uint32_t*>(p) = pixel;
1427  p += pitch;
1428  }
1429  }
1430  break;
1431  }
1432 
1433  default:
1434  break;
1435  } // end switch
1436 
1437  SDL_UnlockSurface(mWindow);
1438 }
1439 
1441 {
1442  const int x1 = rectangle.x;
1443  const int x2 = x1 + rectangle.width - 1;
1444  const int y1 = rectangle.y;
1445  const int y2 = y1 + rectangle.height - 1;
1446 
1447  drawHLine(x1, y1, x2);
1448  drawHLine(x1, y2, x2);
1449 
1450  drawVLine(x1, y1, y2);
1451  drawVLine(x2, y1, y2);
1452 }
1453 
1454 void SDLGraphics::drawLine(int x1, int y1,
1455  int x2, int y2) restrict2
1456 {
1457  if (x1 == x2)
1458  {
1459  drawVLine(x1, y1, y2);
1460  return;
1461  }
1462  if (y1 == y2)
1463  {
1464  drawHLine(x1, y1, x2);
1465  return;
1466  }
1467 
1468  // other cases not implemented
1469 }
1470 
1471 bool SDLGraphics::setVideoMode(const int w, const int h,
1472  const int scale,
1473  const int bpp,
1474  const bool fs,
1475  const bool hwaccel,
1476  const bool resize,
1477  const bool noFrame,
1478  const bool allowHighDPI) restrict2
1479 {
1480  setMainFlags(w, h,
1481  scale,
1482  bpp,
1483  fs,
1484  hwaccel,
1485  resize,
1486  noFrame,
1487  allowHighDPI);
1488 
1489  if ((mWindow = graphicsManager.createWindow(w, h, bpp,
1490  getSoftwareFlags())) == nullptr)
1491  {
1492  mRect.w = 0;
1493  mRect.h = 0;
1494  return false;
1495  }
1496 
1497  mRect.w = CAST_U16(mWindow->w);
1498  mRect.h = CAST_U16(mWindow->h);
1499 
1500  return videoInfo();
1501 }
1502 
1503 void SDLGraphics::drawImageRect(const int x, const int y,
1504  const int w, const int h,
1505  const ImageRect &restrict imgRect) restrict2
1506 {
1508 }
1509 
1511  const int x, const int y,
1512  const int w, const int h,
1513  const ImageRect &restrict imgRect) restrict2
1514 {
1516 }
1517 
1518 #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:435
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:176
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:177
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)