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