GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/sdl2graphics.cpp Lines: 114 316 36.1 %
Date: 2019-08-19 Branches: 68 426 16.0 %

Line Branch Exec Source
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
 *
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
/*      _______   __   __   __   ______   __   __   _______   __   __
24
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
25
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
26
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
27
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
28
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
29
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
30
 *
31
 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
32
 *
33
 *
34
 * Per Larsson a.k.a finalman
35
 * Olof Naessén a.k.a jansem/yakslem
36
 *
37
 * Visit: http://guichan.sourceforge.net
38
 *
39
 * License: (BSD)
40
 * Redistribution and use in source and binary forms, with or without
41
 * modification, are permitted provided that the following conditions
42
 * are met:
43
 * 1. Redistributions of source code must retain the above copyright
44
 *    notice, this list of conditions and the following disclaimer.
45
 * 2. Redistributions in binary form must reproduce the above copyright
46
 *    notice, this list of conditions and the following disclaimer in
47
 *    the documentation and/or other materials provided with the
48
 *    distribution.
49
 * 3. Neither the name of Guichan nor the names of its contributors may
50
 *    be used to endorse or promote products derived from this software
51
 *    without specific prior written permission.
52
 *
53
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
54
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
56
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
57
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
59
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
60
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
61
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64
 */
65
66
#ifdef USE_SDL2
67
68
#include "render/sdl2graphics.h"
69
70
#include "graphicsmanager.h"
71
72
#include "render/vertexes/imagecollection.h"
73
74
#include "resources/imagerect.h"
75
#include "resources/sdl2imagehelper.h"
76
77
#include "resources/image/image.h"
78
79
#include "utils/sdlcheckutils.h"
80
81
#include "debug.h"
82
83
#ifdef DEBUG_SDL_SURFACES
84
85
#define MSDL_RenderCopy(render, texture, src, dst) \
86
    FakeSDL_RenderCopy(render, texture, src, dst)
87
88
static int FakeSDL_RenderCopy(SDL_Renderer *restrict const renderer,
89
                              SDL_Texture *restrict const texture,
90
                              const SDL_Rect *restrict const srcrect,
91
                              const SDL_Rect *restrict const dstrect)
92
{
93
    int ret = SDL_RenderCopy(renderer, texture, srcrect, dstrect);
94
    if (ret)
95
    {
96
        logger->log("rendering error in texture %p: %s",
97
            static_cast<void*>(texture), SDL_GetError());
98
    }
99
    return ret;
100
}
101
102
#else  // DEBUG_SDL_SURFACES
103
104
#define MSDL_RenderCopy(render, texture, src, dst) \
105
    SDL_RenderCopy(render, texture, src, dst)
106
107
#endif  // DEBUG_SDL_SURFACES
108
109
#define setRenderDrawColor(mColor) \
110
    SDL_SetRenderDrawColor(mRenderer, \
111
        CAST_U8(mColor.r), \
112
        CAST_U8(mColor.g), \
113
        CAST_U8(mColor.b), \
114
        CAST_U8(mColor.a))
115
116
#define defRectFromArea(rect, area) \
117
    const SDL_Rect rect = \
118
    { \
119
        CAST_S32(area.x), \
120
        CAST_S32(area.y), \
121
        CAST_S32(area.width), \
122
        CAST_S32(area.height) \
123
    }
124
125
150
SDLGraphics::SDLGraphics() :
126
    Graphics(),
127
    mRendererFlags(SDL_RENDERER_SOFTWARE),
128
    mOldPixel(0),
129
150
    mOldAlpha(0)
130
{
131
150
    mOpenGL = RENDER_SDL2_DEFAULT;
132
300
    mName = "SDL2 default";
133
150
}
134
135
150
SDLGraphics::~SDLGraphics()
136
{
137
150
}
138
139
void SDLGraphics::drawRescaledImage(const Image *restrict const image,
140
                                    int dstX, int dstY,
141
                                    const int desiredWidth,
142
                                    const int desiredHeight) restrict2
143
{
144
    FUNC_BLOCK("Graphics::drawRescaledImage", 1)
145
    // Check that preconditions for blitting are met.
146
    if (!mWindow || !image || !image->mTexture)
147
        return;
148
149
    const ClipRect &top = mClipStack.top();
150
    const SDL_Rect &bounds = image->mBounds;
151
    const SDL_Rect srcRect =
152
    {
153
        CAST_S32(bounds.x),
154
        CAST_S32(bounds.y),
155
        CAST_S32(bounds.w),
156
        CAST_S32(bounds.h)
157
    };
158
    const SDL_Rect dstRect =
159
    {
160
        CAST_S32(dstX + top.xOffset),
161
        CAST_S32(dstY + top.yOffset),
162
        CAST_S32(desiredWidth),
163
        CAST_S32(desiredHeight)
164
    };
165
166
    MSDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
167
}
168
169
331
void SDLGraphics::drawImage(const Image *restrict const image,
170
                            int dstX, int dstY) restrict2
171
{
172
331
    drawImageInline(image, dstX, dstY);
173
331
}
174
175
void SDLGraphics::drawImageInline(const Image *restrict const image,
176
                                  int dstX, int dstY) restrict2
177
{
178
    FUNC_BLOCK("Graphics::drawImage", 1)
179
    // Check that preconditions for blitting are met.
180









515
    if (!mWindow || !image || !image->mTexture)
181
515
        return;
182
183
245
    const ClipRect &top = mClipStack.top();
184






245
    if (!top.width || !top.height)
185
        return;
186
187
    const SDL_Rect &bounds = image->mBounds;
188
    const SDL_Rect srcRect =
189
    {
190
        CAST_S32(bounds.x),
191
        CAST_S32(bounds.y),
192
        CAST_S32(bounds.w),
193
        CAST_S32(bounds.h)
194
    };
195
196
    const SDL_Rect dstRect =
197
    {
198
        CAST_S32(dstX + top.xOffset),
199
        CAST_S32(dstY + top.yOffset),
200
        CAST_S32(bounds.w),
201
        CAST_S32(bounds.h)
202
    };
203
204
    MSDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
205
}
206
207
void SDLGraphics::copyImage(const Image *restrict const image,
208
                            int dstX, int dstY) restrict2
209
{
210
    drawImageInline(image, dstX, dstY);
211
}
212
213
void SDLGraphics::drawImageCached(const Image *restrict const image,
214
                                  int x, int y) restrict2
215
{
216
    FUNC_BLOCK("Graphics::drawImageCached", 1)
217
    // Check that preconditions for blitting are met.
218
    if (!mWindow || !image || !image->mTexture)
219
        return;
220
221
    const ClipRect &top = mClipStack.top();
222
    if (!top.width || !top.height)
223
        return;
224
225
    const SDL_Rect &bounds = image->mBounds;
226
    const SDL_Rect srcRect =
227
    {
228
        CAST_S32(bounds.x),
229
        CAST_S32(bounds.y),
230
        CAST_S32(bounds.w),
231
        CAST_S32(bounds.h)
232
    };
233
234
    const SDL_Rect dstRect =
235
    {
236
        CAST_S32(x + top.xOffset),
237
        CAST_S32(y + top.yOffset),
238
        CAST_S32(bounds.w),
239
        CAST_S32(bounds.h)
240
    };
241
242
    MSDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
243
}
244
245
void SDLGraphics::drawPatternCached(const Image *restrict const image,
246
                                    const int x, const int y,
247
                                    const int w, const int h) restrict2
248
{
249
    FUNC_BLOCK("Graphics::drawPatternCached", 1)
250
    // Check that preconditions for blitting are met.
251
    if (!mWindow || !image)
252
        return;
253
    if (!image->mTexture)
254
        return;
255
256
    const ClipRect &top = mClipStack.top();
257
    if (!top.width || !top.height)
258
        return;
259
260
    const SDL_Rect &bounds = image->mBounds;
261
    const int iw = bounds.w;
262
    const int ih = bounds.h;
263
    if (iw == 0 || ih == 0)
264
        return;
265
266
    const int xOffset = top.xOffset + x;
267
    const int yOffset = top.yOffset + y;
268
269
    SDL_Rect dstRect;
270
    SDL_Rect srcRect;
271
    srcRect.x = CAST_S32(bounds.x);
272
    srcRect.y = CAST_S32(bounds.y);
273
    for (int py = 0; py < h; py += ih)
274
    {
275
        const int dh = (py + ih >= h) ? h - py : ih;
276
        dstRect.y = CAST_S32(py + yOffset);
277
        srcRect.h = CAST_S32(dh);
278
        dstRect.h = CAST_S32(dh);
279
280
        for (int px = 0; px < w; px += iw)
281
        {
282
            const int dw = (px + iw >= w) ? w - px : iw;
283
            dstRect.x = CAST_S32(px + xOffset);
284
            srcRect.w = CAST_S32(dw);
285
            dstRect.w = CAST_S32(dw);
286
287
            MSDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
288
        }
289
    }
290
}
291
292
void SDLGraphics::completeCache() restrict2
293
{
294
}
295
296
void SDLGraphics::drawPattern(const Image *restrict const image,
297
                              const int x, const int y,
298
                              const int w, const int h) restrict2
299
{
300
    drawPatternInline(image, x, y, w, h);
301
}
302
303
void SDLGraphics::drawPatternInline(const Image *restrict const image,
304
                                    const int x, const int y,
305
                                    const int w, const int h) restrict2
306
{
307
    FUNC_BLOCK("Graphics::drawPattern", 1)
308
    // Check that preconditions for blitting are met.
309






230
    if (!mWindow || !image)
310
230
        return;
311



230
    if (!image->mTexture)
312
        return;
313
314
    const ClipRect &top = mClipStack.top();
315
    if (!top.width || !top.height)
316
        return;
317
318
    const SDL_Rect &bounds = image->mBounds;
319
    const int iw = bounds.w;
320
    const int ih = bounds.h;
321
    if (iw == 0 || ih == 0)
322
        return;
323
324
    const int xOffset = top.xOffset + x;
325
    const int yOffset = top.yOffset + y;
326
327
    SDL_Rect dstRect;
328
    SDL_Rect srcRect;
329
    srcRect.x = CAST_S32(bounds.x);
330
    srcRect.y = CAST_S32(bounds.y);
331
    for (int py = 0; py < h; py += ih)
332
    {
333
        const int dh = (py + ih >= h) ? h - py : ih;
334
        dstRect.y = CAST_S32(py + yOffset);
335
        srcRect.h = CAST_S32(dh);
336
        dstRect.h = CAST_S32(dh);
337
338
        for (int px = 0; px < w; px += iw)
339
        {
340
            const int dw = (px + iw >= w) ? w - px : iw;
341
            dstRect.x = CAST_S32(px + xOffset);
342
            srcRect.w = CAST_S32(dw);
343
            dstRect.w = CAST_S32(dw);
344
345
            MSDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
346
        }
347
    }
348
}
349
350
void SDLGraphics::drawRescaledPattern(const Image *restrict const image,
351
                                      const int x, const int y,
352
                                      const int w, const int h,
353
                                      const int scaledWidth,
354
                                      const int scaledHeight) restrict2
355
{
356
    // Check that preconditions for blitting are met.
357
    if (!mWindow || !image)
358
        return;
359
    if (!image->mTexture)
360
        return;
361
362
    if (scaledHeight == 0 || scaledWidth == 0)
363
        return;
364
365
    const ClipRect &top = mClipStack.top();
366
    if (!top.width || !top.height)
367
        return;
368
369
    Image *const tmpImage = image->SDLgetScaledImage(
370
        scaledWidth, scaledHeight);
371
    if (!tmpImage)
372
        return;
373
374
    const SDL_Rect &bounds = tmpImage->mBounds;
375
    const int iw = bounds.w;
376
    const int ih = bounds.h;
377
    if (iw == 0 || ih == 0)
378
        return;
379
380
    const int xOffset = top.xOffset + x;
381
    const int yOffset = top.yOffset + y;
382
383
    SDL_Rect dstRect;
384
    SDL_Rect srcRect;
385
    srcRect.x = CAST_S32(bounds.x);
386
    srcRect.y = CAST_S32(bounds.y);
387
    for (int py = 0; py < h; py += ih)
388
    {
389
        const int dh = (py + ih >= h) ? h - py : ih;
390
        dstRect.y = CAST_S32(py + yOffset);
391
        srcRect.h = CAST_S32(dh);
392
        dstRect.h = CAST_S32(dh);
393
394
        for (int px = 0; px < w; px += iw)
395
        {
396
            const int dw = (px + iw >= w) ? w - px : iw;
397
            dstRect.x = CAST_S32(px + xOffset);
398
            srcRect.w = CAST_S32(dw);
399
            dstRect.w = CAST_S32(dw);
400
401
            MSDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
402
        }
403
    }
404
405
    delete tmpImage;
406
}
407
408
void SDLGraphics::calcPattern(ImageVertexes *restrict const vert,
409
                              const Image *restrict const image,
410
                              const int x, const int y,
411
                              const int w, const int h) const restrict2
412
{
413
    calcPatternInline(vert, image, x, y, w, h);
414
}
415
416
void SDLGraphics::calcPatternInline(ImageVertexes *restrict const vert,
417
                                    const Image *restrict const image,
418
                                    const int x, const int y,
419
                                    const int w, const int h) const restrict2
420
{
421
    // Check that preconditions for blitting are met.
422











820
    if (!vert || !mWindow || !image || !image->mTexture)
423
        return;
424
425
    const ClipRect &top = mClipStack.top();
426
    if (!top.width || !top.height)
427
        return;
428
429
    const SDL_Rect &bounds = image->mBounds;
430
    const int iw = bounds.w;
431
    const int ih = bounds.h;
432
    if (iw == 0 || ih == 0)
433
        return;
434
435
    const int xOffset = top.xOffset + x;
436
    const int yOffset = top.yOffset + y;
437
    const int srcX = bounds.x;
438
    const int srcY = bounds.y;
439
    for (int py = 0; py < h; py += ih)
440
    {
441
        const int dh = (py + ih >= h) ? h - py : ih;
442
        const int dstY = py + yOffset;
443
444
        for (int px = 0; px < w; px += iw)
445
        {
446
            const int dw = (px + iw >= w) ? w - px : iw;
447
            const int dstX = px + xOffset;
448
449
            DoubleRect *const r = new DoubleRect;
450
            SDL_Rect &dstRect = r->dst;
451
            SDL_Rect &srcRect = r->src;
452
            srcRect.x = CAST_S32(srcX);
453
            srcRect.y = CAST_S32(srcY);
454
            srcRect.w = CAST_S32(dw);
455
            srcRect.h = CAST_S32(dh);
456
            dstRect.x = CAST_S32(dstX);
457
            dstRect.y = CAST_S32(dstY);
458
            dstRect.w = CAST_S32(dw);
459
            dstRect.h = CAST_S32(dh);
460
461
            vert->sdl.push_back(r);
462
        }
463
    }
464
}
465
466
40
void SDLGraphics::calcPattern(ImageCollection *restrict const vertCol,
467
                              const Image *restrict const image,
468
                              const int x, const int y,
469
                              const int w, const int h) const restrict2
470
{
471
40
    ImageVertexes *vert = nullptr;
472
40
    if (vertCol->currentImage != image)
473
    {
474
40
        vert = new ImageVertexes;
475
40
        vertCol->currentImage = image;
476
40
        vertCol->currentVert = vert;
477
40
        vert->image = image;
478
40
        vertCol->draws.push_back(vert);
479
    }
480
    else
481
    {
482
        vert = vertCol->currentVert;
483
    }
484
485
80
    calcPatternInline(vert, image, x, y, w, h);
486
40
}
487
488
void SDLGraphics::calcTileVertexes(ImageVertexes *restrict const vert,
489
                                   const Image *restrict const image,
490
                                   int x, int y) const restrict2
491
{
492
    vert->image = image;
493
    calcTileSDL(vert, x, y);
494
}
495
496
void SDLGraphics::calcTileVertexesInline(ImageVertexes *restrict const vert,
497
                                         const Image *restrict const image,
498
                                         int x, int y) const restrict2
499
{
500
635
    vert->image = image;
501
635
    calcTileSDL(vert, x, y);
502
}
503
504
697
void SDLGraphics::calcTileSDL(ImageVertexes *restrict const vert,
505
                              int x, int y) const restrict2
506
{
507
    // Check that preconditions for blitting are met.
508

697
    if (!vert || !vert->image || !vert->image->mTexture)
509
697
        return;
510
511
    const ClipRect &top = mClipStack.top();
512
    if (!top.width || !top.height)
513
        return;
514
515
    const Image *const image = vert->image;
516
    const SDL_Rect &bounds = image->mBounds;
517
518
    x += top.xOffset;
519
    y += top.yOffset;
520
521
    DoubleRect *rect = new DoubleRect;
522
    SDL_Rect &dstRect = rect->dst;
523
    SDL_Rect &srcRect = rect->src;
524
525
    srcRect.x = CAST_S32(bounds.x);
526
    srcRect.y = CAST_S32(bounds.y);
527
    srcRect.w = CAST_S32(bounds.w);
528
    srcRect.h = CAST_S32(bounds.h);
529
    dstRect.x = CAST_S32(x);
530
    dstRect.y = CAST_S32(y);
531
    dstRect.w = CAST_S32(bounds.w);
532
    dstRect.h = CAST_S32(bounds.h);
533
534
    vert->sdl.push_back(rect);
535
}
536
537
62
void SDLGraphics::calcTileCollection(ImageCollection *restrict const vertCol,
538
                                     const Image *restrict const image,
539
                                     int x, int y) restrict2
540
{
541
62
    if (!vertCol)
542
        return;
543
62
    if (vertCol->currentImage != image)
544
    {
545
62
        ImageVertexes *const vert = new ImageVertexes;
546
62
        vertCol->currentImage = image;
547
62
        vertCol->currentVert = vert;
548
62
        vert->image = image;
549
62
        vertCol->draws.push_back(vert);
550
62
        calcTileSDL(vert, x, y);
551
    }
552
    else
553
    {
554
        calcTileSDL(vertCol->currentVert, x, y);
555
    }
556
}
557
558
241
void SDLGraphics::drawTileCollection(const ImageCollection
559
                                     *restrict const vertCol) restrict2
560
{
561
241
    const ImageVertexesVector &draws = vertCol->draws;
562
482
    const ImageCollectionCIter it_end = draws.end();
563
992
    for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
564
    {
565
269
        const ImageVertexes *const vert = *it;
566
269
        const Image *const img = vert->image;
567
269
        const DoubleRects *const rects = &vert->sdl;
568
538
        DoubleRects::const_iterator it2 = rects->begin();
569
538
        const DoubleRects::const_iterator it2_end = rects->end();
570
269
        while (it2 != it2_end)
571
        {
572
            MSDL_RenderCopy(mRenderer, img->mTexture,
573
                &(*it2)->src, &(*it2)->dst);
574
            ++ it2;
575
        }
576
    }
577
241
}
578
579
void SDLGraphics::drawTileVertexes(const ImageVertexes *restrict const vert)
580
                                   restrict2
581
{
582
    if (!vert)
583
        return;
584
    // vert and img must be != 0
585
    const Image *const img = vert->image;
586
    const DoubleRects *const rects = &vert->sdl;
587
    DoubleRects::const_iterator it = rects->begin();
588
    const DoubleRects::const_iterator it_end = rects->end();
589
    while (it != it_end)
590
    {
591
        MSDL_RenderCopy(mRenderer, img->mTexture, &(*it)->src, &(*it)->dst);
592
        ++ it;
593
    }
594
}
595
596
67
void SDLGraphics::updateScreen() restrict2
597
{
598
    BLOCK_START("Graphics::updateScreen")
599
67
    SDL_RenderPresent(mRenderer);
600
//    SDL_RenderClear(mRenderer);
601
    BLOCK_END("Graphics::updateScreen")
602
67
}
603
604
167
void SDLGraphics::calcWindow(ImageCollection *restrict const vertCol,
605
                             const int x, const int y,
606
                             const int w, const int h,
607
                             const ImageRect &restrict imgRect) restrict2
608
{
609
167
    ImageVertexes *vert = nullptr;
610
167
    Image *const image = imgRect.grid[4];
611
167
    if (!image)
612
        return;
613
167
    if (vertCol->currentImage != image)
614
    {
615
167
        vert = new ImageVertexes;
616
167
        vertCol->currentImage = image;
617
167
        vertCol->currentVert = vert;
618
167
        vert->image = image;
619
167
        vertCol->draws.push_back(vert);
620
    }
621
    else
622
    {
623
        vert = vertCol->currentVert;
624
    }
625
334
    calcImageRect(vert, x, y, w, h, imgRect);
626
}
627
628
2
void SDLGraphics::fillRectangle(const Rect &restrict rectangle) restrict2
629
{
630
2
    const ClipRect &top = mClipStack.top();
631
    const SDL_Rect rect =
632
    {
633
2
        CAST_S32(rectangle.x + top.xOffset),
634
2
        CAST_S32(rectangle.y + top.yOffset),
635
2
        CAST_S32(rectangle.width),
636
2
        CAST_S32(rectangle.height)
637
8
    };
638
639
2
    setRenderDrawColor(mColor);
640
2
    SDL_RenderFillRects(mRenderer, &rect, 1);
641
2
}
642
643
void SDLGraphics::beginDraw() restrict2
644
{
645
    pushClipArea(Rect(0, 0, mRect.w, mRect.h));
646
}
647
648
void SDLGraphics::endDraw() restrict2
649
{
650
    popClipArea();
651
}
652
653
571
void SDLGraphics::pushClipArea(const Rect &restrict area) restrict2
654
{
655
571
    Graphics::pushClipArea(area);
656
657
571
    const ClipRect &carea = mClipStack.top();
658
571
    defRectFromArea(rect, carea);
659
571
    SDL_RenderSetClipRect(mRenderer, &rect);
660
571
}
661
662
571
void SDLGraphics::popClipArea() restrict2
663
{
664
571
    Graphics::popClipArea();
665
666
571
    if (mClipStack.empty())
667
67
        return;
668
669
504
    const ClipRect &carea = mClipStack.top();
670
504
    defRectFromArea(rect, carea);
671
504
    SDL_RenderSetClipRect(mRenderer, &rect);
672
}
673
674
void SDLGraphics::drawPoint(int x, int y) restrict2
675
{
676
    if (mClipStack.empty())
677
        return;
678
679
    const ClipRect &top = mClipStack.top();
680
681
    x += top.xOffset;
682
    y += top.yOffset;
683
684
    if (!top.isPointInRect(x, y))
685
        return;
686
687
    setRenderDrawColor(mColor);
688
    const SDL_Point point =
689
    {
690
        x,
691
        y
692
    };
693
694
    SDL_RenderDrawPoints(mRenderer, &point, 1);
695
}
696
697
698
void SDLGraphics::drawRectangle(const Rect &restrict rectangle) restrict2
699
{
700
    const ClipRect &top = mClipStack.top();
701
    setRenderDrawColor(mColor);
702
703
    const int x1 = rectangle.x + top.xOffset;
704
    const int y1 = rectangle.y + top.yOffset;
705
    const int x2 = x1 + rectangle.width - 1;
706
    const int y2 = y1 + rectangle.height - 1;
707
    SDL_Point points[] =
708
    {
709
        {x1, y1},
710
        {x2, y1},
711
        {x2, y2},
712
        {x1, y2},
713
        {x1, y1}
714
    };
715
716
    SDL_RenderDrawLines(mRenderer, points, 5);
717
}
718
719
4
void SDLGraphics::drawLine(int x1, int y1,
720
                           int x2, int y2) restrict2
721
{
722
4
    const ClipRect &top = mClipStack.top();
723
4
    setRenderDrawColor(mColor);
724
725
4
    const int x0 = top.xOffset;
726
4
    const int y0 = top.yOffset;
727
728
    SDL_Point points[] =
729
    {
730
8
        {x1 + x0, y1 + y0},
731
8
        {x2 + x0, y2 + y0}
732
16
    };
733
734
4
    SDL_RenderDrawLines(mRenderer, points, 2);
735
4
}
736
737
77
bool SDLGraphics::setVideoMode(const int w, const int h,
738
                               const int scale,
739
                               const int bpp,
740
                               const bool fs,
741
                               const bool hwaccel,
742
                               const bool resize,
743
                               const bool noFrame,
744
                               const bool allowHighDPI) restrict2
745
{
746
77
    setMainFlags(w, h,
747
        scale,
748
        bpp,
749
        fs,
750
        hwaccel,
751
        resize,
752
        noFrame,
753
77
        allowHighDPI);
754
755
77
    if (!(mWindow = graphicsManager.createWindow(w, h, bpp,
756
        getSoftwareFlags())))
757
    {
758
        mRect.w = 0;
759
        mRect.h = 0;
760
        return false;
761
    }
762
763
77
    int w1 = 0;
764
77
    int h1 = 0;
765
77
    SDL_GetWindowSize(mWindow, &w1, &h1);
766
77
    mRect.w = w1;
767
77
    mRect.h = h1;
768
769
77
    mRenderer = graphicsManager.createRenderer(mWindow, mRendererFlags);
770
154
    SDLImageHelper::setRenderer(mRenderer);
771
77
    return videoInfo();
772
}
773
774
46
void SDLGraphics::drawImageRect(const int x, const int y,
775
                                const int w, const int h,
776
                                const ImageRect &restrict imgRect) restrict2
777
{
778
    #include "render/graphics_drawImageRect.hpp"
779
46
}
780
781
void SDLGraphics::calcImageRect(ImageVertexes *restrict const vert,
782
                                const int x, const int y,
783
                                const int w, const int h,
784
                                const ImageRect &restrict imgRect) restrict2
785
{
786
    #include "render/graphics_calcImageRect.hpp"
787
}
788
789
#endif  // USE_SDL2