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