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