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