GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/sdlgraphics.cpp Lines: 257 712 36.1 %
Date: 2021-03-17 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-2019  The ManaPlus Developers
6
 *  Copyright (C) 2019-2021  Andrei Karas
7
 *
8
 *  This file is part of The ManaPlus Client.
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
#ifndef USE_SDL2
25
26
#include "render/sdlgraphics.h"
27
28
#include "graphicsmanager.h"
29
30
#include "utils/sdlcheckutils.h"
31
32
#include "utils/sdlpixel.h"
33
34
#include "render/vertexes/imagecollection.h"
35
36
#include "resources/imagerect.h"
37
38
#include "resources/image/image.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
161
SDLGraphics::SDLGraphics() :
53
    Graphics(),
54
    mOldPixel(0),
55
161
    mOldAlpha(0)
56
{
57
161
    mOpenGL = RENDER_SOFTWARE;
58
322
    mName = "Software";
59
161
}
60
61
161
SDLGraphics::~SDLGraphics()
62
{
63
161
}
64
65
void SDLGraphics::drawRescaledImage(const Image *restrict const image,
66
                                    int dstX, int dstY,
67
                                    const int desiredWidth,
68
                                    const int desiredHeight) restrict2
69
{
70
    FUNC_BLOCK("Graphics::drawRescaledImage", 1)
71
    // Check that preconditions for blitting are met.
72
    if (mWindow == nullptr ||
73
        image == nullptr ||
74
        image->mSDLSurface == nullptr)
75
    {
76
        return;
77
    }
78
79
    Image *const tmpImage = image->SDLgetScaledImage(
80
        desiredWidth, desiredHeight);
81
82
    if ((tmpImage == nullptr) || (tmpImage->mSDLSurface == nullptr))
83
        return;
84
85
    const ClipRect &top = mClipStack.top();
86
    const SDL_Rect &bounds = image->mBounds;
87
88
    SDL_Rect srcRect =
89
    {
90
        CAST_S16(bounds.x),
91
        CAST_S16(bounds.y),
92
        CAST_U16(bounds.w),
93
        CAST_U16(bounds.h)
94
    };
95
96
    SDL_Rect dstRect =
97
    {
98
        CAST_S16(dstX + top.xOffset),
99
        CAST_S16(dstY + top.yOffset),
100
        0,
101
        0
102
    };
103
104
    SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect, mWindow, &dstRect);
105
    delete tmpImage;
106
}
107
108
331
void SDLGraphics::drawImage(const Image *restrict const image,
109
                            int dstX, int dstY) restrict2
110
{
111
331
    drawImageInline(image, dstX, dstY);
112
331
}
113
114
void SDLGraphics::drawImageInline(const Image *restrict const image,
115
                                  int dstX, int dstY) restrict2
116
{
117
    FUNC_BLOCK("Graphics::drawImage", 1)
118
    // Check that preconditions for blitting are met.
119






515
    if (mWindow == nullptr ||
120



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



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



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



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



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



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



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



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



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



515
    if (w > 0 && h > 0)
184
    {
185
        SDL_Rect srcRect =
186
        {
187
            CAST_S16(srcX),
188
            CAST_S16(srcY),
189
            CAST_U16(w),
190
            CAST_U16(h)
191
        };
192
193
        SDL_Rect dstRect =
194
        {
195
            CAST_S16(dstX),
196
            CAST_S16(dstY),
197
            CAST_U16(w),
198
            CAST_U16(h)
199
        };
200
201
        SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
202
    }
203
}
204
205
void SDLGraphics::copyImage(const Image *restrict const image,
206
                            int dstX, int dstY) restrict2
207
{
208
    drawImageInline(image, dstX, dstY);
209
}
210
211
void SDLGraphics::drawImageCached(const Image *restrict const image,
212
                                  int x, int y) restrict2
213
{
214
    FUNC_BLOCK("Graphics::drawImageCached", 1)
215
    // Check that preconditions for blitting are met.
216
    if (mWindow == nullptr ||
217
        image == nullptr ||
218
        image->mSDLSurface == nullptr)
219
    {
220
        return;
221
    }
222
223
    const ClipRect &top = mClipStack.top();
224
    const SDL_Rect &bounds = image->mBounds;
225
226
    SDL_Surface *const src = image->mSDLSurface;
227
228
    int srcX = bounds.x;
229
    int srcY = bounds.y;
230
    x += top.xOffset;
231
    y += top.yOffset;
232
233
    int w = bounds.w;
234
    int h = bounds.h;
235
    if (srcX < 0)
236
    {
237
        w += srcX;
238
        x -= CAST_S16(srcX);
239
        srcX = 0;
240
    }
241
    const int maxw = src->w - srcX;
242
    if (maxw < w)
243
        w = maxw;
244
245
    if (srcY < 0)
246
    {
247
        h += srcY;
248
        y -= CAST_S16(srcY);
249
        srcY = 0;
250
    }
251
    const int maxh = src->h - srcY;
252
    if (maxh < h)
253
        h = maxh;
254
255
    const SDL_Rect *const clip = &mWindow->clip_rect;
256
    const int clipX = clip->x;
257
    const int clipY = clip->y;
258
    int dx = clipX - x;
259
    if (dx > 0)
260
    {
261
        w -= dx;
262
        x += CAST_S16(dx);
263
        srcX += dx;
264
    }
265
    dx = x + w - clipX - clip->w;
266
    if (dx > 0)
267
        w -= dx;
268
269
    int dy = clipY - y;
270
    if (dy > 0)
271
    {
272
        h -= dy;
273
        y += CAST_S16(dy);
274
        srcY += dy;
275
    }
276
    dy = y + h - clipY - clip->h;
277
    if (dy > 0)
278
        h -= dy;
279
280
    if (w > 0 && h > 0)
281
    {
282
        SDL_Rect srcRect =
283
        {
284
            CAST_S16(srcX),
285
            CAST_S16(srcY),
286
            CAST_U16(w),
287
            CAST_U16(h)
288
        };
289
290
        SDL_Rect dstRect =
291
        {
292
            CAST_S16(x),
293
            CAST_S16(y),
294
            CAST_U16(w),
295
            CAST_U16(h)
296
        };
297
298
        SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
299
    }
300
}
301
302
void SDLGraphics::drawPatternCached(const Image *restrict const image,
303
                                    const int x, const int y,
304
                                    const int w, const int h) restrict2
305
{
306
    FUNC_BLOCK("Graphics::drawPatternCached", 1)
307
    // Check that preconditions for blitting are met.
308
    if ((mWindow == nullptr) || (image == nullptr))
309
        return;
310
    if (image->mSDLSurface == nullptr)
311
        return;
312
313
    const SDL_Rect &bounds = image->mBounds;
314
    const int iw = bounds.w;
315
    const int ih = bounds.h;
316
    if (iw == 0 || ih == 0)
317
        return;
318
319
    const ClipRect &top = mClipStack.top();
320
    const int xOffset = top.xOffset + x;
321
    const int yOffset = top.yOffset + y;
322
    const int srcX = bounds.x;
323
    const int srcY = bounds.y;
324
    SDL_Surface *const src = image->mSDLSurface;
325
    const SDL_Rect *const clip = &mWindow->clip_rect;
326
    const int clipX = clip->x;
327
    const int clipY = clip->y;
328
329
    for (int py = 0; py < h; py += ih)
330
    {
331
        const int dh = (py + ih >= h) ? h - py : ih;
332
        int dstY = py + yOffset;
333
        int y2 = srcY;
334
        int h2 = dh;
335
        if (y2 < 0)
336
        {
337
            h2 += y2;
338
            dstY -= CAST_S16(y2);
339
            y2 = 0;
340
        }
341
        const int maxh = src->h - y2;
342
        if (maxh < h2)
343
            h2 = maxh;
344
345
        int dy = clipY - dstY;
346
        if (dy > 0)
347
        {
348
            h2 -= dy;
349
            dstY += CAST_S16(dy);
350
            y2 += dy;
351
        }
352
        dy = dstY + h2 - clipY - clip->h;
353
        if (dy > 0)
354
            h2 -= dy;
355
356
        if (h2 > 0)
357
        {
358
            for (int px = 0; px < w; px += iw)
359
            {
360
                const int dw = (px + iw >= w) ? w - px : iw;
361
                int dstX = px + xOffset;
362
                int x2 = srcX;
363
                int w2 = dw;
364
                if (x2 < 0)
365
                {
366
                    w2 += x2;
367
                    dstX -= CAST_S16(x2);
368
                    x2 = 0;
369
                }
370
                const int maxw = src->w - x2;
371
                if (maxw < w2)
372
                    w2 = maxw;
373
374
                int dx = clipX - dstX;
375
                if (dx > 0)
376
                {
377
                    w2 -= dx;
378
                    dstX += CAST_S16(dx);
379
                    x2 += dx;
380
                }
381
                dx = dstX + w2 - clipX - clip->w;
382
                if (dx > 0)
383
                    w2 -= dx;
384
385
                if (w2 > 0)
386
                {
387
                    SDL_Rect srcRect =
388
                    {
389
                        CAST_S16(x2),
390
                        CAST_S16(y2),
391
                        CAST_U16(w2),
392
                        CAST_U16(h2)
393
                    };
394
395
                    SDL_Rect dstRect =
396
                    {
397
                        CAST_S16(dstX),
398
                        CAST_S16(dstY),
399
                        CAST_U16(w2),
400
                        CAST_U16(h2)
401
                    };
402
403
                    SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
404
                }
405
406
//            SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
407
            }
408
        }
409
    }
410
}
411
412
void SDLGraphics::completeCache() restrict2
413
{
414
}
415
416
void SDLGraphics::drawPattern(const Image *restrict const image,
417
                              const int x, const int y,
418
                              const int w, const int h) restrict2
419
{
420
    drawPatternInline(image, x, y, w, h);
421
}
422
423
void SDLGraphics::drawPatternInline(const Image *restrict const image,
424
                                    const int x, const int y,
425
                                    const int w, const int h) restrict2
426
{
427
    FUNC_BLOCK("Graphics::drawPattern", 1)
428
    // Check that preconditions for blitting are met.
429






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



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



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



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



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



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



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



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



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



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




860
    if (vert == nullptr ||
614



1640
        mWindow == nullptr ||
615



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



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



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



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



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



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



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

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

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