GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/sdlgraphics.cpp Lines: 257 712 36.1 %
Date: 2018-11-12 Branches: 241 779 30.9 %

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-2018  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
#ifndef USE_SDL2
24
25
#include "render/sdlgraphics.h"
26
27
#include "graphicsmanager.h"
28
29
#include "utils/sdlcheckutils.h"
30
31
#include "utils/sdlpixel.h"
32
33
#include "render/vertexes/imagecollection.h"
34
35
#include "resources/imagerect.h"
36
37
#include "resources/image/image.h"
38
39
#include "debug.h"
40
41
#ifndef SDL_BIG_ENDIAN
42
#error missing SDL_endian.h
43
#endif  // SDL_BYTEORDER
44
45
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
46
static unsigned int *cR = nullptr;
47
static unsigned int *cG = nullptr;
48
static unsigned int *cB = nullptr;
49
#endif  // SDL_BYTEORDER == SDL_LIL_ENDIAN
50
51
161
SDLGraphics::SDLGraphics() :
52
    Graphics(),
53
    mOldPixel(0),
54
161
    mOldAlpha(0)
55
{
56
161
    mOpenGL = RENDER_SOFTWARE;
57
322
    mName = "Software";
58
161
}
59
60
161
SDLGraphics::~SDLGraphics()
61
{
62
161
}
63
64
void SDLGraphics::drawRescaledImage(const Image *restrict const image,
65
                                    int dstX, int dstY,
66
                                    const int desiredWidth,
67
                                    const int desiredHeight) restrict2
68
{
69
    FUNC_BLOCK("Graphics::drawRescaledImage", 1)
70
    // Check that preconditions for blitting are met.
71
    if (mWindow == nullptr ||
72
        image == nullptr ||
73
        image->mSDLSurface == nullptr)
74
    {
75
        return;
76
    }
77
78
    Image *const tmpImage = image->SDLgetScaledImage(
79
        desiredWidth, desiredHeight);
80
81
    if ((tmpImage == nullptr) || (tmpImage->mSDLSurface == nullptr))
82
        return;
83
84
    const ClipRect &top = mClipStack.top();
85
    const SDL_Rect &bounds = image->mBounds;
86
87
    SDL_Rect srcRect =
88
    {
89
        CAST_S16(bounds.x),
90
        CAST_S16(bounds.y),
91
        CAST_U16(bounds.w),
92
        CAST_U16(bounds.h)
93
    };
94
95
    SDL_Rect dstRect =
96
    {
97
        CAST_S16(dstX + top.xOffset),
98
        CAST_S16(dstY + top.yOffset),
99
        0,
100
        0
101
    };
102
103
    SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect, mWindow, &dstRect);
104
    delete tmpImage;
105
}
106
107
331
void SDLGraphics::drawImage(const Image *restrict const image,
108
                            int dstX, int dstY) restrict2
109
{
110
331
    drawImageInline(image, dstX, dstY);
111
331
}
112
113
void SDLGraphics::drawImageInline(const Image *restrict const image,
114
                                  int dstX, int dstY) restrict2
115
{
116
    FUNC_BLOCK("Graphics::drawImage", 1)
117
    // Check that preconditions for blitting are met.
118






515
    if (mWindow == nullptr ||
119



515
        image == nullptr ||
120
515
        image->mSDLSurface == nullptr)
121
    {
122
        return;
123
    }
124
125
515
    const ClipRect &top = mClipStack.top();
126
515
    const SDL_Rect &bounds = image->mBounds;
127
128
515
    SDL_Surface *const src = image->mSDLSurface;
129
130
515
    int srcX = bounds.x;
131
515
    int srcY = bounds.y;
132
515
    dstX += top.xOffset;
133
515
    dstY += top.yOffset;
134
135
515
    int w = bounds.w;
136
515
    int h = bounds.h;
137



515
    if (srcX < 0)
138
    {
139
        w += srcX;
140
        dstX -= CAST_S16(srcX);
141
        srcX = 0;
142
    }
143
515
    const int maxw = src->w - srcX;
144



515
    if (maxw < w)
145
        w = maxw;
146
147



515
    if (srcY < 0)
148
    {
149
        h += srcY;
150
        dstY -= CAST_S16(srcY);
151
        srcY = 0;
152
    }
153
515
    const int maxh = src->h - srcY;
154



515
    if (maxh < h)
155
        h = maxh;
156
157
515
    const SDL_Rect *const clip = &mWindow->clip_rect;
158
515
    const int clipX = clip->x;
159
515
    const int clipY = clip->y;
160
515
    int dx = clipX - dstX;
161



515
    if (dx > 0)
162
    {
163
69
        w -= dx;
164
69
        dstX += CAST_S16(dx);
165
69
        srcX += dx;
166
    }
167
515
    dx = dstX + w - clipX - clip->w;
168



515
    if (dx > 0)
169
514
        w -= dx;
170
171
515
    int dy = clipY - dstY;
172



515
    if (dy > 0)
173
    {
174
67
        h -= dy;
175
67
        dstY += CAST_S16(dy);
176
67
        srcY += dy;
177
    }
178
515
    dy = dstY + h - clipY - clip->h;
179



515
    if (dy > 0)
180
515
        h -= dy;
181
182



515
    if (w > 0 && h > 0)
183
    {
184
        SDL_Rect srcRect =
185
        {
186
            CAST_S16(srcX),
187
            CAST_S16(srcY),
188
            CAST_U16(w),
189
            CAST_U16(h)
190
        };
191
192
        SDL_Rect dstRect =
193
        {
194
            CAST_S16(dstX),
195
            CAST_S16(dstY),
196
            CAST_U16(w),
197
            CAST_U16(h)
198
        };
199
200
        SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
201
    }
202
}
203
204
void SDLGraphics::copyImage(const Image *restrict const image,
205
                            int dstX, int dstY) restrict2
206
{
207
    drawImageInline(image, dstX, dstY);
208
}
209
210
void SDLGraphics::drawImageCached(const Image *restrict const image,
211
                                  int x, int y) restrict2
212
{
213
    FUNC_BLOCK("Graphics::drawImageCached", 1)
214
    // Check that preconditions for blitting are met.
215
    if (mWindow == nullptr ||
216
        image == nullptr ||
217
        image->mSDLSurface == nullptr)
218
    {
219
        return;
220
    }
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 = &mWindow->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, mWindow, &dstRect);
298
    }
299
}
300
301
void SDLGraphics::drawPatternCached(const Image *restrict const image,
302
                                    const int x, const int y,
303
                                    const int w, const int h) restrict2
304
{
305
    FUNC_BLOCK("Graphics::drawPatternCached", 1)
306
    // Check that preconditions for blitting are met.
307
    if ((mWindow == nullptr) || (image == nullptr))
308
        return;
309
    if (image->mSDLSurface == nullptr)
310
        return;
311
312
    const SDL_Rect &bounds = image->mBounds;
313
    const int iw = bounds.w;
314
    const int ih = bounds.h;
315
    if (iw == 0 || ih == 0)
316
        return;
317
318
    const ClipRect &top = mClipStack.top();
319
    const int xOffset = top.xOffset + x;
320
    const int yOffset = top.yOffset + y;
321
    const int srcX = bounds.x;
322
    const int srcY = bounds.y;
323
    SDL_Surface *const src = image->mSDLSurface;
324
    const SDL_Rect *const clip = &mWindow->clip_rect;
325
    const int clipX = clip->x;
326
    const int clipY = clip->y;
327
328
    for (int py = 0; py < h; py += ih)
329
    {
330
        const int dh = (py + ih >= h) ? h - py : ih;
331
        int dstY = py + yOffset;
332
        int y2 = srcY;
333
        int h2 = dh;
334
        if (y2 < 0)
335
        {
336
            h2 += y2;
337
            dstY -= CAST_S16(y2);
338
            y2 = 0;
339
        }
340
        const int maxh = src->h - y2;
341
        if (maxh < h2)
342
            h2 = maxh;
343
344
        int dy = clipY - dstY;
345
        if (dy > 0)
346
        {
347
            h2 -= dy;
348
            dstY += CAST_S16(dy);
349
            y2 += dy;
350
        }
351
        dy = dstY + h2 - clipY - clip->h;
352
        if (dy > 0)
353
            h2 -= dy;
354
355
        if (h2 > 0)
356
        {
357
            for (int px = 0; px < w; px += iw)
358
            {
359
                const int dw = (px + iw >= w) ? w - px : iw;
360
                int dstX = px + xOffset;
361
                int x2 = srcX;
362
                int w2 = dw;
363
                if (x2 < 0)
364
                {
365
                    w2 += x2;
366
                    dstX -= CAST_S16(x2);
367
                    x2 = 0;
368
                }
369
                const int maxw = src->w - x2;
370
                if (maxw < w2)
371
                    w2 = maxw;
372
373
                int dx = clipX - dstX;
374
                if (dx > 0)
375
                {
376
                    w2 -= dx;
377
                    dstX += CAST_S16(dx);
378
                    x2 += dx;
379
                }
380
                dx = dstX + w2 - clipX - clip->w;
381
                if (dx > 0)
382
                    w2 -= dx;
383
384
                if (w2 > 0)
385
                {
386
                    SDL_Rect srcRect =
387
                    {
388
                        CAST_S16(x2),
389
                        CAST_S16(y2),
390
                        CAST_U16(w2),
391
                        CAST_U16(h2)
392
                    };
393
394
                    SDL_Rect dstRect =
395
                    {
396
                        CAST_S16(dstX),
397
                        CAST_S16(dstY),
398
                        CAST_U16(w2),
399
                        CAST_U16(h2)
400
                    };
401
402
                    SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
403
                }
404
405
//            SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
406
            }
407
        }
408
    }
409
}
410
411
void SDLGraphics::completeCache() restrict2
412
{
413
}
414
415
void SDLGraphics::drawPattern(const Image *restrict const image,
416
                              const int x, const int y,
417
                              const int w, const int h) restrict2
418
{
419
    drawPatternInline(image, x, y, w, h);
420
}
421
422
void SDLGraphics::drawPatternInline(const Image *restrict const image,
423
                                    const int x, const int y,
424
                                    const int w, const int h) restrict2
425
{
426
    FUNC_BLOCK("Graphics::drawPattern", 1)
427
    // Check that preconditions for blitting are met.
428






230
    if ((mWindow == nullptr) || (image == nullptr))
429
        return;
430



230
    if (image->mSDLSurface == nullptr)
431
        return;
432
433
230
    const SDL_Rect &bounds = image->mBounds;
434
230
    const int iw = bounds.w;
435
230
    const int ih = bounds.h;
436



230
    if (iw == 0 || ih == 0)
437
        return;
438
439
230
    const ClipRect &top = mClipStack.top();
440
230
    const int xOffset = top.xOffset + x;
441
230
    const int yOffset = top.yOffset + y;
442
230
    const int srcX = bounds.x;
443
230
    const int srcY = bounds.y;
444
230
    SDL_Surface *const src = image->mSDLSurface;
445
230
    const SDL_Rect *const clip = &mWindow->clip_rect;
446
230
    const int clipX = clip->x;
447
230
    const int clipY = clip->y;
448
449



230
    for (int py = 0; py < h; py += ih)
450
    {
451



413
        const int dh = (py + ih >= h) ? h - py : ih;
452
413
        int dstY = py + yOffset;
453
413
        int y2 = srcY;
454
413
        int h2 = dh;
455



413
        if (y2 < 0)
456
        {
457
            h2 += y2;
458
            dstY -= CAST_S16(y2);
459
            y2 = 0;
460
        }
461
413
        const int maxh = src->h - y2;
462



413
        if (maxh < h2)
463
            h2 = maxh;
464
465
413
        int dy = clipY - dstY;
466



413
        if (dy > 0)
467
        {
468
            h2 -= dy;
469
            dstY += CAST_S16(dy);
470
            y2 += dy;
471
        }
472
413
        dy = dstY + h2 - clipY - clip->h;
473



413
        if (dy > 0)
474
413
            h2 -= dy;
475
476



413
        if (h2 > 0)
477
        {
478
            for (int px = 0; px < w; px += iw)
479
            {
480
                const int dw = (px + iw >= w) ? w - px : iw;
481
                int dstX = px + xOffset;
482
                int x2 = srcX;
483
                int w2 = dw;
484
                if (x2 < 0)
485
                {
486
                    w2 += x2;
487
                    dstX -= CAST_S16(x2);
488
                    x2 = 0;
489
                }
490
                const int maxw = src->w - x2;
491
                if (maxw < w2)
492
                    w2 = maxw;
493
494
                int dx = clipX - dstX;
495
                if (dx > 0)
496
                {
497
                    w2 -= dx;
498
                    dstX += CAST_S16(dx);
499
                    x2 += dx;
500
                }
501
                dx = dstX + w2 - clipX - clip->w;
502
                if (dx > 0)
503
                    w2 -= dx;
504
505
                if (w2 > 0)
506
                {
507
                    SDL_Rect srcRect =
508
                    {
509
                        CAST_S16(x2),
510
                        CAST_S16(y2),
511
                        CAST_U16(w2),
512
                        CAST_U16(h2)
513
                    };
514
515
                    SDL_Rect dstRect =
516
                    {
517
                        CAST_S16(dstX),
518
                        CAST_S16(dstY),
519
                        CAST_U16(w2),
520
                        CAST_U16(h2)
521
                    };
522
523
                    SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
524
                }
525
526
//            SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
527
            }
528
        }
529
    }
530
}
531
532
void SDLGraphics::drawRescaledPattern(const Image *restrict const image,
533
                                      const int x, const int y,
534
                                      const int w, const int h,
535
                                      const int scaledWidth,
536
                                      const int scaledHeight) restrict2
537
{
538
    // Check that preconditions for blitting are met.
539
    if ((mWindow == nullptr) || (image == nullptr))
540
        return;
541
    if (image->mSDLSurface == nullptr)
542
        return;
543
544
    if (scaledHeight == 0 || scaledWidth == 0)
545
        return;
546
547
    Image *const tmpImage = image->SDLgetScaledImage(
548
        scaledWidth, scaledHeight);
549
    if (tmpImage == nullptr)
550
        return;
551
552
    const SDL_Rect &bounds = tmpImage->mBounds;
553
    const int iw = bounds.w;
554
    const int ih = bounds.h;
555
    if (iw == 0 || ih == 0)
556
        return;
557
558
    const ClipRect &top = mClipStack.top();
559
    const int xOffset = top.xOffset + x;
560
    const int yOffset = top.yOffset + y;
561
    const int srcX = bounds.x;
562
    const int srcY = bounds.y;
563
564
    for (int py = 0; py < h; py += ih)  // Y position on pattern plane
565
    {
566
        const int dh = (py + ih >= h) ? h - py : ih;
567
        const int dstY = py + yOffset;
568
569
        for (int px = 0; px < w; px += iw)  // X position on pattern plane
570
        {
571
            const int dw = (px + iw >= w) ? w - px : iw;
572
            const int dstX = px + xOffset;
573
574
            SDL_Rect srcRect =
575
            {
576
                CAST_S16(srcX),
577
                CAST_S16(srcY),
578
                CAST_U16(dw),
579
                CAST_U16(dh)
580
            };
581
582
            SDL_Rect dstRect =
583
            {
584
                CAST_S16(dstX),
585
                CAST_S16(dstY),
586
                0,
587
                0
588
            };
589
590
            SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect,
591
                            mWindow, &dstRect);
592
        }
593
    }
594
595
    delete tmpImage;
596
}
597
598
void SDLGraphics::calcPattern(ImageVertexes *restrict const vert,
599
                              const Image *restrict const image,
600
                              const int x, const int y,
601
                              const int w, const int h) const restrict2
602
{
603
    calcPatternInline(vert, image, x, y, w, h);
604
}
605
606
void SDLGraphics::calcPatternInline(ImageVertexes *restrict const vert,
607
                                    const Image *restrict const image,
608
                                    const int x, const int y,
609
                                    const int w, const int h) const restrict2
610
{
611
    // Check that preconditions for blitting are met.
612




860
    if (vert == nullptr ||
613



1640
        mWindow == nullptr ||
614



820
        image == nullptr ||
615
820
        image->mSDLSurface == nullptr)
616
    {
617
        return;
618
    }
619
620
820
    const SDL_Rect &bounds = image->mBounds;
621
820
    const int iw = bounds.w;
622
820
    const int ih = bounds.h;
623



820
    if (iw == 0 || ih == 0)
624
        return;
625
626
820
    const ClipRect &top = mClipStack.top();
627
820
    const int xOffset = top.xOffset + x;
628
820
    const int yOffset = top.yOffset + y;
629
820
    const int srcX = bounds.x;
630
820
    const int srcY = bounds.y;
631
632



820
    for (int py = 0; py < h; py += ih)  // Y position on pattern plane
633
    {
634



3748
        const int dh = (py + ih >= h) ? h - py : ih;
635
3748
        const int dstY = py + yOffset;
636
637



20241
        for (int px = 0; px < w; px += iw)  // X position on pattern plane
638
        {
639



16493
            const int dw = (px + iw >= w) ? w - px : iw;
640
16493
            const int dstX = px + xOffset;
641
642
16493
            DoubleRect *const r = new DoubleRect;
643
16493
            SDL_Rect &srcRect = r->src;
644
16493
            srcRect.x = CAST_S16(srcX);
645
16493
            srcRect.y = CAST_S16(srcY);
646
16493
            srcRect.w = CAST_U16(dw);
647
16493
            srcRect.h = CAST_U16(dh);
648
16493
            SDL_Rect &dstRect = r->dst;
649
16493
            dstRect.x = CAST_S16(dstX);
650
16493
            dstRect.y = CAST_S16(dstY);
651
652



16493
            if (SDL_FakeUpperBlit(image->mSDLSurface, &srcRect,
653
16493
                mWindow, &dstRect) == 1)
654
            {
655
                vert->sdl.push_back(r);
656
            }
657
            else
658
            {
659
16493
                delete r;
660
            }
661
        }
662
    }
663
}
664
665
40
void SDLGraphics::calcPattern(ImageCollection *restrict const vertCol,
666
                              const Image *restrict const image,
667
                              const int x, const int y,
668
                              const int w, const int h) const restrict2
669
{
670
40
    if (vertCol == nullptr || image == nullptr)
671
        return;
672
673
40
    ImageVertexes *vert = nullptr;
674
40
    if (vertCol->currentImage != image)
675
    {
676
40
        vert = new ImageVertexes;
677
40
        vertCol->currentImage = image;
678
40
        vertCol->currentVert = vert;
679
40
        vert->image = image;
680
40
        vertCol->draws.push_back(vert);
681
    }
682
    else
683
    {
684
        vert = vertCol->currentVert;
685
    }
686
687
80
    calcPatternInline(vert, image, x, y, w, h);
688
}
689
690
void SDLGraphics::calcTileVertexes(ImageVertexes *restrict const vert,
691
                                   const Image *restrict const image,
692
                                   int x, int y) const restrict2
693
{
694
    vert->image = image;
695
    calcTileSDL(vert, x, y);
696
}
697
698
void SDLGraphics::calcTileVertexesInline(ImageVertexes *restrict const vert,
699
                                         const Image *restrict const image,
700
                                         int x, int y) const restrict2
701
{
702
635
    vert->image = image;
703
635
    calcTileSDL(vert, x, y);
704
}
705
706
697
void SDLGraphics::calcTileSDL(ImageVertexes *restrict const vert,
707
                              int x, int y) const restrict2
708
{
709
    // Check that preconditions for blitting are met.
710

1394
    if (vert == nullptr ||
711
1394
        vert->image == nullptr ||
712
697
        vert->image->mSDLSurface == nullptr)
713
    {
714
        return;
715
    }
716
717
697
    const Image *const image = vert->image;
718
697
    const ClipRect &top = mClipStack.top();
719
697
    const SDL_Rect &bounds = image->mBounds;
720
721
697
    DoubleRect *rect = new DoubleRect;
722
697
    rect->src.x = CAST_S16(bounds.x);
723
697
    rect->src.y = CAST_S16(bounds.y);
724
697
    rect->src.w = CAST_U16(bounds.w);
725
697
    rect->src.h = CAST_U16(bounds.h);
726
697
    rect->dst.x = CAST_S16(x + top.xOffset);
727
697
    rect->dst.y = CAST_S16(y + top.yOffset);
728
1394
    if (SDL_FakeUpperBlit(image->mSDLSurface, &rect->src,
729
697
        mWindow, &rect->dst) == 1)
730
    {
731
        vert->sdl.push_back(rect);
732
    }
733
    else
734
    {
735
697
        delete rect;
736
    }
737
}
738
739
62
void SDLGraphics::calcTileCollection(ImageCollection *restrict const vertCol,
740
                                     const Image *restrict const image,
741
                                     int x, int y) restrict2
742
{
743
62
    if (vertCol == nullptr)
744
        return;
745
62
    if (vertCol->currentImage != image)
746
    {
747
62
        ImageVertexes *const vert = new ImageVertexes;
748
62
        vertCol->currentImage = image;
749
62
        vertCol->currentVert = vert;
750
62
        vert->image = image;
751
62
        vertCol->draws.push_back(vert);
752
62
        calcTileSDL(vert, x, y);
753
    }
754
    else
755
    {
756
        calcTileSDL(vertCol->currentVert, x, y);
757
    }
758
}
759
760
241
void SDLGraphics::drawTileCollection(const ImageCollection
761
                                     *restrict const vertCol) restrict2
762
{
763
241
    const ImageVertexesVector &draws = vertCol->draws;
764
482
    const ImageCollectionCIter it_end = draws.end();
765
992
    for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
766
    {
767
269
        const ImageVertexes *const vert = *it;
768
269
        const Image *const img = vert->image;
769
269
        const DoubleRects *const rects = &vert->sdl;
770
538
        DoubleRects::const_iterator it2 = rects->begin();
771
538
        const DoubleRects::const_iterator it2_end = rects->end();
772
269
        while (it2 != it2_end)
773
        {
774
            SDL_LowerBlit(img->mSDLSurface, &(*it2)->src,
775
                mWindow, &(*it2)->dst);
776
            ++ it2;
777
        }
778
    }
779
241
}
780
781
void SDLGraphics::drawTileVertexes(const ImageVertexes *
782
                                   restrict const vert) restrict2
783
{
784
    if (vert == nullptr)
785
        return;
786
    // vert and img must be != 0
787
    const Image *const img = vert->image;
788
    const DoubleRects *const rects = &vert->sdl;
789
    DoubleRects::const_iterator it = rects->begin();
790
    const DoubleRects::const_iterator it_end = rects->end();
791
    while (it != it_end)
792
    {
793
        SDL_LowerBlit(img->mSDLSurface, &(*it)->src, mWindow, &(*it)->dst);
794
        ++ it;
795
    }
796
}
797
798
67
void SDLGraphics::updateScreen() restrict2
799
{
800
    BLOCK_START("Graphics::updateScreen")
801
67
    if (mDoubleBuffer)
802
    {
803
        SDL_Flip(mWindow);
804
    }
805
    else
806
    {
807
67
        SDL_UpdateRects(mWindow, 1, &mRect);
808
//        SDL_UpdateRect(mWindow, 0, 0, 0, 0);
809
    }
810
    BLOCK_END("Graphics::updateScreen")
811
67
}
812
813
167
void SDLGraphics::calcWindow(ImageCollection *restrict const vertCol,
814
                             const int x, const int y,
815
                             const int w, const int h,
816
                             const ImageRect &restrict imgRect) restrict2
817
{
818
167
    ImageVertexes *vert = nullptr;
819
167
    Image *const image = imgRect.grid[4];
820
167
    if (image == nullptr)
821
        return;
822
167
    if (vertCol->currentImage != image)
823
    {
824
167
        vert = new ImageVertexes;
825
167
        vertCol->currentImage = image;
826
167
        vertCol->currentVert = vert;
827
167
        vert->image = image;
828
167
        vertCol->draws.push_back(vert);
829
    }
830
    else
831
    {
832
        vert = vertCol->currentVert;
833
    }
834
334
    calcImageRect(vert, x, y, w, h, imgRect);
835
}
836
837
17190
int SDLGraphics::SDL_FakeUpperBlit(const SDL_Surface *restrict const src,
838
                                   SDL_Rect *restrict const srcrect,
839
                                   const SDL_Surface *restrict const dst,
840
                                   SDL_Rect *restrict dstrect) const restrict2
841
{
842
    int srcx;
843
    int srcy;
844
    int w;
845
    int h;
846
847
    // Make sure the surfaces aren't locked
848
17190
    if ((src == nullptr) || (dst == nullptr))
849
        return -1;
850
851
17190
    if ((srcrect == nullptr) || (dstrect == nullptr))
852
        return -1;
853
854
17190
    srcx = srcrect->x;
855
17190
    w = srcrect->w;
856
17190
    if (srcx < 0)
857
    {
858
        w += srcx;
859
        dstrect->x -= CAST_S16(srcx);
860
        srcx = 0;
861
    }
862
17190
    int maxw = src->w - srcx;
863
17190
    if (maxw < w)
864
        w = maxw;
865
866
17190
    srcy = srcrect->y;
867
17190
    h = srcrect->h;
868
17190
    if (srcy < 0)
869
    {
870
        h += srcy;
871
        dstrect->y -= CAST_S16(srcy);
872
        srcy = 0;
873
    }
874
17190
    int maxh = src->h - srcy;
875
17190
    if (maxh < h)
876
        h = maxh;
877
878
17190
    const SDL_Rect *const clip = &dst->clip_rect;
879
17190
    const int clipX = clip->x;
880
17190
    const int clipY = clip->y;
881
17190
    int dx = clipX - dstrect->x;
882
17190
    if (dx > 0)
883
    {
884
171
        w -= dx;
885
171
        dstrect->x += CAST_S16(dx);
886
171
        srcx += dx;
887
    }
888
17190
    dx = dstrect->x + w - clipX - clip->w;
889
17190
    if (dx > 0)
890
17028
        w -= dx;
891
892
17190
    int dy = clipY - dstrect->y;
893
17190
    if (dy > 0)
894
    {
895
1
        h -= dy;
896
1
        dstrect->y += CAST_S16(dy);
897
1
        srcy += dy;
898
    }
899
17190
    dy = dstrect->y + h - clipY - clip->h;
900
17190
    if (dy > 0)
901
17190
        h -= dy;
902
903
17190
    if (w > 0 && h > 0)
904
    {
905
        srcrect->x = CAST_S16(srcx);
906
        srcrect->y = CAST_S16(srcy);
907
        srcrect->w = CAST_S16(w);
908
        srcrect->h = CAST_S16(h);
909
        dstrect->w = CAST_S16(w);
910
        dstrect->h = CAST_S16(h);
911
912
        return 1;
913
//        return SDL_LowerBlit(src, &sr, dst, dstrect);
914
    }
915
17190
    dstrect->w = dstrect->h = 0;
916
17190
    return 0;
917
}
918
919
2
void SDLGraphics::fillRectangle(const Rect &restrict rectangle) restrict2
920
{
921
    FUNC_BLOCK("Graphics::fillRectangle", 1)
922
2
    if (mClipStack.empty())
923
2
        return;
924
925
2
    const ClipRect &restrict top = mClipStack.top();
926
927
2
    Rect area = rectangle;
928
2
    area.x += top.xOffset;
929
2
    area.y += top.yOffset;
930
931
2
    if (!area.isIntersecting(top))
932
        return;
933
934
    if (mAlpha)
935
    {
936
        const int x1 = area.x > top.x ? area.x : top.x;
937
        const int y1 = area.y > top.y ? area.y : top.y;
938
        const int x2 = area.x + area.width < top.x + top.width ?
939
            area.x + area.width : top.x + top.width;
940
        const int y2 = area.y + area.height < top.y + top.height ?
941
            area.y + area.height : top.y + top.height;
942
943
        SDL_LockSurface(mWindow);
944
945
        const int bpp = mWindow->format->BytesPerPixel;
946
        const uint32_t pixel = SDL_MapRGB(mWindow->format,
947
            CAST_U8(mColor.r), CAST_U8(mColor.g),
948
            CAST_U8(mColor.b));
949
950
        switch (bpp)
951
        {
952
            case 1:
953
                for (int y = y1; y < y2; y++)
954
                {
955
                    uint8_t *const p = static_cast<uint8_t *>(mWindow->pixels)
956
                        + CAST_SIZE(y * mWindow->pitch);
957
                    for (int x = x1; x < x2; x++)
958
                    {
959
                        *(p + CAST_SIZE(x))
960
                            = CAST_U8(pixel);
961
                    }
962
                }
963
                break;
964
            case 2:
965
                for (int y = y1; y < y2; y++)
966
                {
967
                    uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
968
                        + CAST_SIZE(y * mWindow->pitch);
969
                    for (int x = x1; x < x2; x++)
970
                    {
971
                        uint8_t *const p = p0 + CAST_SIZE(x * 2);
972
                        *reinterpret_cast<uint16_t *>(p) = SDLAlpha16(
973
                            CAST_U16(pixel),
974
                            *reinterpret_cast<uint16_t *>(p),
975
                            CAST_U8(mColor.a), mWindow->format);
976
                    }
977
                }
978
                break;
979
            case 3:
980
            {
981
                const int ca = 255 - mColor.a;
982
                const int cr = mColor.r * mColor.a;
983
                const int cg = mColor.g * mColor.a;
984
                const int cb = mColor.b * mColor.a;
985
986
                for (int y = y1; y < y2; y++)
987
                {
988
                    uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
989
                        + CAST_SIZE(y * mWindow->pitch);
990
                    for (int x = x1; x < x2; x++)
991
                    {
992
                        uint8_t *const p = p0 + CAST_SIZE(x * 3);
993
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
994
                        p[2] = CAST_U8((p[2] * ca + cb) >> 8);
995
                        p[1] = CAST_U8((p[1] * ca + cg) >> 8);
996
                        p[0] = CAST_U8((p[0] * ca + cr) >> 8);
997
#else  // SDL_BYTEORDER == SDL_BIG_ENDIAN
998
                        p[0] = CAST_U8((p[0] * ca + cb) >> 8);
999
                        p[1] = CAST_U8((p[1] * ca + cg) >> 8);
1000
                        p[2] = CAST_U8((p[2] * ca + cr) >> 8);
1001
#endif  // SDL_BYTEORDER == SDL_BIG_ENDIAN
1002
                    }
1003
                }
1004
                break;
1005
            }
1006
            case 4:
1007
            {
1008
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
1009
                const unsigned pb = (pixel & 0xff) * mColor.a;
1010
                const unsigned pg = (pixel & 0xff00) * mColor.a;
1011
                const unsigned pr = (pixel & 0xff0000) * mColor.a;
1012
                const unsigned a1 = (255 - mColor.a);
1013
1014
                for (int y = y1; y < y2; y++)
1015
                {
1016
                    uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
1017
                        + y * mWindow->pitch;
1018
                    for (int x = x1; x < x2; x++)
1019
                    {
1020
                        uint8_t *p = p0 + x * 4;
1021
                        uint32_t dst = *reinterpret_cast<uint32_t *>(p);
1022
                        const unsigned int b = (pb + (dst & 0xff) * a1) >> 8;
1023
                        const unsigned int g = (pg + (dst & 0xff00) * a1) >> 8;
1024
                        const unsigned int r = (pr
1025
                            + (dst & 0xff0000) * a1) >> 8;
1026
1027
                        *reinterpret_cast<uint32_t *>(p) = ((b & 0xff)
1028
                            | (g & 0xff00) | (r & 0xff0000));
1029
                    }
1030
                }
1031
#else  // SDL_BYTEORDER == SDL_BIG_ENDIAN
1032
                if (cR == nullptr)
1033
                {
1034
                    cR = new unsigned int[0x100];
1035
                    cG = new unsigned int[0x100];
1036
                    cB = new unsigned int[0x100];
1037
                    mOldPixel = 0;
1038
                    mOldAlpha = mColor.a;
1039
                }
1040
1041
                const SDL_PixelFormat * const format = mWindow->format;
1042
                const unsigned rMask = format->Rmask;
1043
                const unsigned gMask = format->Gmask;
1044
                const unsigned bMask = format->Bmask;
1045
//                const unsigned aMask = format->Amask;
1046
                unsigned rShift = rMask / 0xff;
1047
                unsigned gShift = gMask / 0xff;
1048
                unsigned bShift = bMask / 0xff;
1049
                if (rShift == 0U)
1050
                    rShift = 1;
1051
                if (gShift == 0U)
1052
                    gShift = 1;
1053
                if (bShift == 0U)
1054
                    bShift = 1;
1055
                if (pixel != mOldPixel || mColor.a != mOldAlpha)
1056
                {
1057
                    const unsigned pb = (pixel & bMask) * mColor.a;
1058
                    const unsigned pg = (pixel & gMask) * mColor.a;
1059
                    const unsigned pr = (pixel & rMask) * mColor.a;
1060
                    const unsigned a0 = 255 - mColor.a;
1061
1062
                    const unsigned int a1 = a0 * bShift;
1063
                    const unsigned int a2 = a0 * gShift;
1064
                    const unsigned int a3 = a0 * rShift;
1065
1066
                    for (int f = 0; f <= 0xff; f ++)
1067
                    {
1068
                        cB[f] = ((pb + f * a1) >> 8) & bMask;
1069
                        cG[f] = ((pg + f * a2) >> 8) & gMask;
1070
                        cR[f] = ((pr + f * a3) >> 8) & rMask;
1071
                    }
1072
1073
                    mOldPixel = pixel;
1074
                    mOldAlpha = mColor.a;
1075
                }
1076
1077
                for (int y = y1; y < y2; y++)
1078
                {
1079
                    uint32_t *const p0 = reinterpret_cast<uint32_t*>(
1080
                        static_cast<uint8_t*>(mWindow->pixels)
1081
                        + CAST_SIZE(y * mWindow->pitch));
1082
                    for (int x = x1; x < x2; x++)
1083
                    {
1084
                        uint32_t *const p = p0 + CAST_SIZE(x);
1085
                        const uint32_t dst = *p;
1086
                        *p = cB[dst & bMask / bShift]
1087
                            | cG[(dst & gMask) / gShift]
1088
                            | cR[(dst & rMask) / rShift];
1089
                    }
1090
                }
1091
#endif  // SDL_BYTEORDER == SDL_BIG_ENDIAN
1092
                break;
1093
            }
1094
            default:
1095
                break;
1096
        }
1097
1098
        SDL_UnlockSurface(mWindow);
1099
    }
1100
    else
1101
    {
1102
        SDL_Rect rect =
1103
        {
1104
            CAST_S16(area.x),
1105
            CAST_S16(area.y),
1106
            CAST_U16(area.width),
1107
            CAST_U16(area.height)
1108
        };
1109
1110
        const uint32_t color = SDL_MapRGBA(mWindow->format,
1111
            CAST_S8(mColor.r),
1112
            CAST_S8(mColor.g),
1113
            CAST_S8(mColor.b),
1114
            CAST_S8(mColor.a));
1115
        SDL_FillRect(mWindow, &rect, color);
1116
    }
1117
}
1118
1119
void SDLGraphics::beginDraw() restrict2
1120
{
1121
    pushClipArea(Rect(0, 0, mRect.w, mRect.h));
1122
}
1123
1124
void SDLGraphics::endDraw() restrict2
1125
{
1126
    popClipArea();
1127
}
1128
1129
571
void SDLGraphics::pushClipArea(const Rect &restrict area) restrict2
1130
{
1131
571
    Graphics::pushClipArea(area);
1132
571
    const ClipRect &restrict carea = mClipStack.top();
1133
    const SDL_Rect rect =
1134
    {
1135
571
        CAST_S16(carea.x),
1136
571
        CAST_S16(carea.y),
1137
571
        CAST_U16(carea.width),
1138
571
        CAST_U16(carea.height)
1139
2284
    };
1140
571
    SDL_SetClipRect(mWindow, &rect);
1141
571
}
1142
1143
571
void SDLGraphics::popClipArea() restrict2
1144
{
1145
571
    Graphics::popClipArea();
1146
1147
571
    if (mClipStack.empty())
1148
67
        return;
1149
1150
504
    const ClipRect &restrict carea = mClipStack.top();
1151
    const SDL_Rect rect =
1152
    {
1153
504
        CAST_S16(carea.x),
1154
504
        CAST_S16(carea.y),
1155
504
        CAST_U16(carea.width),
1156
504
        CAST_U16(carea.height)
1157
2016
    };
1158
1159
504
    SDL_SetClipRect(mWindow, &rect);
1160
}
1161
1162
void SDLGraphics::drawPoint(int x, int y) restrict2
1163
{
1164
    if (mClipStack.empty())
1165
        return;
1166
1167
    const ClipRect& top = mClipStack.top();
1168
1169
    x += top.xOffset;
1170
    y += top.yOffset;
1171
1172
    if (!top.isPointInRect(x, y))
1173
        return;
1174
1175
    if (mAlpha)
1176
        SDLputPixelAlpha(mWindow, x, y, mColor);
1177
    else
1178
        SDLputPixel(mWindow, x, y, mColor);
1179
}
1180
1181
void SDLGraphics::drawHLine(int x1, int y, int x2) restrict2
1182
{
1183
    if (mClipStack.empty())
1184
        return;
1185
1186
    const ClipRect& top = mClipStack.top();
1187
1188
    const int xOffset = top.xOffset;
1189
    x1 += xOffset;
1190
    y += top.yOffset;
1191
    x2 += xOffset;
1192
1193
    const int topY = top.y;
1194
    if (y < topY || y >= topY + top.height)
1195
        return;
1196
1197
    if (x1 > x2)
1198
    {
1199
        x1 ^= x2;
1200
        x2 ^= x1;
1201
        x1 ^= x2;
1202
    }
1203
1204
    const int topX = top.x;
1205
    if (topX > x1)
1206
    {
1207
        if (topX > x2)
1208
            return;
1209
1210
        x1 = topX;
1211
    }
1212
1213
    const int sumX = topX + top.width;
1214
    if (sumX <= x2)
1215
    {
1216
        if (sumX <= x1)
1217
            return;
1218
1219
        x2 = sumX -1;
1220
    }
1221
1222
    const int bpp = mWindow->format->BytesPerPixel;
1223
1224
    SDL_LockSurface(mWindow);
1225
1226
    uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1227
        + CAST_SIZE(y * mWindow->pitch + x1 * bpp);
1228
1229
    const uint32_t pixel = SDL_MapRGB(mWindow->format,
1230
        CAST_U8(mColor.r),
1231
        CAST_U8(mColor.g),
1232
        CAST_U8(mColor.b));
1233
    switch (bpp)
1234
    {
1235
        case 1:
1236
            for (; x1 <= x2; ++x1)
1237
                *(p++) = CAST_U8(pixel);
1238
            break;
1239
1240
        case 2:
1241
        {
1242
            uint16_t* q = reinterpret_cast<uint16_t*>(p);
1243
            const uint16_t pixel1 = CAST_U16(pixel);
1244
            for (; x1 <= x2; ++x1)
1245
                *(q++) = pixel1;
1246
            break;
1247
        }
1248
1249
        case 3:
1250
        {
1251
            const uint8_t b0 = CAST_U8((pixel >> 16) & 0xff);
1252
            const uint8_t b1 = CAST_U8((pixel >> 8) & 0xff);
1253
            const uint8_t b2 = CAST_U8(pixel & 0xff);
1254
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
1255
            for (; x1 <= x2; ++x1)
1256
            {
1257
                p[0] = b0;
1258
                p[1] = b1;
1259
                p[2] = b2;
1260
                p += 3;
1261
            }
1262
#else  // SDL_BYTEORDER == SDL_BIG_ENDIAN
1263
            for (; x1 <= x2; ++x1)
1264
            {
1265
                p[0] = b2;
1266
                p[1] = b1;
1267
                p[2] = b0;
1268
                p += 3;
1269
            }
1270
#endif  // SDL_BYTEORDER == SDL_BIG_ENDIAN
1271
            break;
1272
        }
1273
1274
        case 4:
1275
        {
1276
            uint32_t *q = reinterpret_cast<uint32_t*>(p);
1277
            if (mAlpha)
1278
            {
1279
                unsigned char a = CAST_U8(mColor.a);
1280
                unsigned char a1 = CAST_U8(255U - a);
1281
                const int b0 = (pixel & 0xff) * a;
1282
                const int g0 = (pixel & 0xff00) * a;
1283
                const int r0 = (pixel & 0xff0000) * a;
1284
                for (; x1 <= x2; ++x1)
1285
                {
1286
                    const unsigned int b = (b0 + (*q & 0xff) * a1) >> 8;
1287
                    const unsigned int g = (g0 + (*q & 0xff00) * a1) >> 8;
1288
                    const unsigned int r = (r0 + (*q & 0xff0000) * a1) >> 8;
1289
                    *q = (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1290
1291
                    q++;
1292
                }
1293
            }
1294
            else
1295
            {
1296
                for (; x1 <= x2; ++x1)
1297
                    *(q++) = pixel;
1298
            }
1299
            break;
1300
        }
1301
        default:
1302
            break;
1303
    }  // end switch
1304
1305
    SDL_UnlockSurface(mWindow);
1306
}
1307
1308
4
void SDLGraphics::drawVLine(int x, int y1, int y2) restrict2
1309
{
1310
4
    if (mClipStack.empty())
1311
        return;
1312
1313
4
    const ClipRect &restrict top = mClipStack.top();
1314
1315
4
    const int yOffset = top.yOffset;
1316
4
    x += top.xOffset;
1317
4
    y1 += yOffset;
1318
4
    y2 += yOffset;
1319
1320

4
    if (x < top.x || x >= top.x + top.width)
1321
        return;
1322
1323
    if (y1 > y2)
1324
    {
1325
        y1 ^= y2;
1326
        y2 ^= y1;
1327
        y1 ^= y2;
1328
    }
1329
1330
    if (top.y > y1)
1331
    {
1332
        if (top.y > y2)
1333
            return;
1334
1335
        y1 = top.y;
1336
    }
1337
1338
    const int sumY = top.y + top.height;
1339
    if (sumY <= y2)
1340
    {
1341
        if (sumY <= y1)
1342
            return;
1343
1344
        y2 = sumY - 1;
1345
    }
1346
1347
    const int bpp = mWindow->format->BytesPerPixel;
1348
1349
    SDL_LockSurface(mWindow);
1350
1351
    uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1352
        + CAST_SIZE(y1 * mWindow->pitch + x * bpp);
1353
1354
    const uint32_t pixel = SDL_MapRGB(mWindow->format,
1355
        CAST_U8(mColor.r),
1356
        CAST_U8(mColor.g),
1357
        CAST_U8(mColor.b));
1358
1359
    const int pitch = mWindow->pitch;
1360
    switch (bpp)
1361
    {
1362
        case 1:
1363
            for (; y1 <= y2; ++y1)
1364
            {
1365
                *p = CAST_U8(pixel);
1366
                p += pitch;
1367
            }
1368
            break;
1369
1370
        case 2:
1371
            for (; y1 <= y2; ++ y1)
1372
            {
1373
                *reinterpret_cast<uint16_t*>(p)
1374
                    = CAST_U16(pixel);
1375
                p += pitch;
1376
            }
1377
            break;
1378
1379
        case 3:
1380
        {
1381
            const uint8_t b0 = CAST_U8((pixel >> 16) & 0xff);
1382
            const uint8_t b1 = CAST_U8((pixel >> 8) & 0xff);
1383
            const uint8_t b2 = CAST_U8(pixel & 0xff);
1384
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
1385
            for (; y1 <= y2; ++y1)
1386
            {
1387
                p[0] = b0;
1388
                p[1] = b1;
1389
                p[2] = b2;
1390
                p += pitch;
1391
            }
1392
#else  // SDL_BYTEORDER == SDL_BIG_ENDIAN
1393
            for (; y1 <= y2; ++y1)
1394
            {
1395
                p[0] = b2;
1396
                p[1] = b1;
1397
                p[2] = b0;
1398
                p += pitch;
1399
            }
1400
#endif  // SDL_BYTEORDER == SDL_BIG_ENDIAN
1401
            break;
1402
        }
1403
1404
        case 4:
1405
        {
1406
            if (mAlpha)
1407
            {
1408
                unsigned char a = CAST_U8(mColor.a);
1409
                unsigned char a1 = CAST_U8(255U - a);
1410
                const int b0 = (pixel & 0xff) * a;
1411
                const int g0 = (pixel & 0xff00) * a;
1412
                const int r0 = (pixel & 0xff0000) * a;
1413
                for (; y1 <= y2; ++y1)
1414
                {
1415
                    const unsigned int dst = *reinterpret_cast<uint32_t*>(p);
1416
                    const unsigned int b = (b0 + (dst & 0xff) * a1) >> 8;
1417
                    const unsigned int g = (g0 + (dst & 0xff00) * a1) >> 8;
1418
                    const unsigned int r = (r0 + (dst & 0xff0000) * a1) >> 8;
1419
                    *reinterpret_cast<uint32_t*>(p) =
1420
                        (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1421
1422
                    p += pitch;
1423
                }
1424
            }
1425
            else
1426
            {
1427
                for (; y1 <= y2; ++y1)
1428
                {
1429
                    *reinterpret_cast<uint32_t*>(p) = pixel;
1430
                    p += pitch;
1431
                }
1432
            }
1433
            break;
1434
        }
1435
1436
        default:
1437
            break;
1438
    }  // end switch
1439
1440
    SDL_UnlockSurface(mWindow);
1441
}
1442
1443
void SDLGraphics::drawRectangle(const Rect &restrict rectangle) restrict2
1444
{
1445
    const int x1 = rectangle.x;
1446
    const int x2 = x1 + rectangle.width - 1;
1447
    const int y1 = rectangle.y;
1448
    const int y2 = y1 + rectangle.height - 1;
1449
1450
    drawHLine(x1, y1, x2);
1451
    drawHLine(x1, y2, x2);
1452
1453
    drawVLine(x1, y1, y2);
1454
    drawVLine(x2, y1, y2);
1455
}
1456
1457
4
void SDLGraphics::drawLine(int x1, int y1,
1458
                           int x2, int y2) restrict2
1459
{
1460
4
    if (x1 == x2)
1461
    {
1462
4
        drawVLine(x1, y1, y2);
1463
4
        return;
1464
    }
1465
    if (y1 == y2)
1466
    {
1467
        drawHLine(x1, y1, x2);
1468
        return;
1469
    }
1470
1471
    //  other cases not implemented
1472
}
1473
1474
77
bool SDLGraphics::setVideoMode(const int w, const int h,
1475
                               const int scale,
1476
                               const int bpp,
1477
                               const bool fs,
1478
                               const bool hwaccel,
1479
                               const bool resize,
1480
                               const bool noFrame,
1481
                               const bool allowHighDPI) restrict2
1482
{
1483
77
    setMainFlags(w, h,
1484
        scale,
1485
        bpp,
1486
        fs,
1487
        hwaccel,
1488
        resize,
1489
        noFrame,
1490
77
        allowHighDPI);
1491
1492
77
    if ((mWindow = graphicsManager.createWindow(w, h, bpp,
1493
        getSoftwareFlags())) == nullptr)
1494
    {
1495
        mRect.w = 0;
1496
        mRect.h = 0;
1497
        return false;
1498
    }
1499
1500
77
    mRect.w = CAST_U16(mWindow->w);
1501
77
    mRect.h = CAST_U16(mWindow->h);
1502
1503
77
    return videoInfo();
1504
}
1505
1506
46
void SDLGraphics::drawImageRect(const int x, const int y,
1507
                                const int w, const int h,
1508
                                const ImageRect &restrict imgRect) restrict2
1509
{
1510
    #include "render/graphics_drawImageRect.hpp"
1511
46
}
1512
1513
void SDLGraphics::calcImageRect(ImageVertexes *restrict const vert,
1514
                                const int x, const int y,
1515
                                const int w, const int h,
1516
                                const ImageRect &restrict imgRect) restrict2
1517
{
1518
    #include "render/graphics_calcImageRect.hpp"
1519
}
1520
1521
#endif  // USE_SDL2