GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/render/sdlgraphics.cpp Lines: 256 723 35.4 %
Date: 2017-11-29 Branches: 230 755 30.5 %

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-2017  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
276
SDLGraphics::SDLGraphics() :
52
    Graphics(),
53
    mOldPixel(0),
54
276
    mOldAlpha(0)
55
{
56
276
    mOpenGL = RENDER_SOFTWARE;
57
552
    mName = "Software";
58
276
}
59
60
276
SDLGraphics::~SDLGraphics()
61
{
62
276
}
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
656
void SDLGraphics::drawImage(const Image *restrict const image,
108
                            int dstX, int dstY) restrict2
109
{
110
656
    drawImageInline(image, dstX, dstY);
111
656
}
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




1016
    if (mWindow == nullptr ||
119



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



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



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



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



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



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



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



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



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



1016
    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




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



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



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



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



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



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



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



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



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



810
        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




1710
    if (vert == nullptr ||
613

2020
        mWindow == nullptr ||
614



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



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



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



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



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



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



32864
            if (SDL_FakeUpperBlit(image->mSDLSurface, &srcRect,
653
32864
                mWindow, &dstRect) == 1)
654
            {
655
                vert->sdl.push_back(r);
656
            }
657
            else
658
            {
659
32864
                delete r;
660
            }
661
        }
662
    }
663
}
664
665
80
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
80
    if (vertCol == nullptr || image == nullptr)
671
        return;
672
673
80
    ImageVertexes *vert = nullptr;
674
80
    if (vertCol->currentImage != image)
675
    {
676
80
        vert = new ImageVertexes;
677
80
        vertCol->currentImage = image;
678
80
        vertCol->currentVert = vert;
679
80
        vert->image = image;
680
80
        vertCol->draws.push_back(vert);
681
    }
682
    else
683
    {
684
        vert = vertCol->currentVert;
685
    }
686
687
160
    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
1262
    vert->image = image;
703
1262
    calcTileSDL(vert, x, y);
704
}
705
706
1386
void SDLGraphics::calcTileSDL(ImageVertexes *restrict const vert,
707
                              int x, int y) const restrict2
708
{
709
    // Check that preconditions for blitting are met.
710

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

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