~ubuntu-branches/ubuntu/trusty/manaplus/trusty-proposed

« back to all changes in this revision

Viewing changes to src/render/sdl2softwaregraphics.cpp

  • Committer: Package Import Robot
  • Author(s): Patrick Matthäi
  • Date: 2013-09-17 10:35:51 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20130917103551-az7p3nz9jgxwqjfn
Tags: 1.3.9.15-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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-2013  The ManaPlus Developers
 
6
 *
 
7
 *  This file is part of The ManaPlus Client.
 
8
 *
 
9
 *  This program is free software; you can redistribute it and/or modify
 
10
 *  it under the terms of the GNU General Public License as published by
 
11
 *  the Free Software Foundation; either version 2 of the License, or
 
12
 *  any later version.
 
13
 *
 
14
 *  This program is distributed in the hope that it will be useful,
 
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 *  GNU General Public License for more details.
 
18
 *
 
19
 *  You should have received a copy of the GNU General Public License
 
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
 */
 
22
 
 
23
#ifdef USE_SDL2
 
24
 
 
25
#include "render/sdl2softwaregraphics.h"
 
26
 
 
27
#include "main.h"
 
28
 
 
29
#include "configuration.h"
 
30
#include "graphicsmanager.h"
 
31
#include "graphicsvertexes.h"
 
32
#include "logger.h"
 
33
 
 
34
#include "resources/imagehelper.h"
 
35
#include "resources/sdl2softwareimagehelper.h"
 
36
 
 
37
#include <guichan/sdl/sdlpixel.hpp>
 
38
 
 
39
#include "utils/sdlcheckutils.h"
 
40
 
 
41
#include <SDL.h>
 
42
 
 
43
#include "debug.h"
 
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
 
50
 
 
51
SDL2SoftwareGraphics::SDL2SoftwareGraphics() :
 
52
    Graphics(),
 
53
    mRendererFlags(SDL_RENDERER_SOFTWARE),
 
54
    mSurface(nullptr),
 
55
    mOldPixel(0),
 
56
    mOldAlpha(0)
 
57
{
 
58
    mOpenGL = RENDER_SOFTWARE;
 
59
    mName = "Software";
 
60
}
 
61
 
 
62
SDL2SoftwareGraphics::~SDL2SoftwareGraphics()
 
63
{
 
64
}
 
65
 
 
66
bool SDL2SoftwareGraphics::drawRescaledImage(const Image *const image,
 
67
                                             int srcX, int srcY,
 
68
                                             int dstX, int dstY,
 
69
                                             const int width, const int height,
 
70
                                             const int desiredWidth,
 
71
                                             const int desiredHeight,
 
72
                                             const bool useColor A_UNUSED)
 
73
{
 
74
    FUNC_BLOCK("Graphics::drawRescaledImage", 1)
 
75
    // Check that preconditions for blitting are met.
 
76
    if (!mSurface || !image)
 
77
        return false;
 
78
    if (!image->mSDLSurface)
 
79
        return false;
 
80
 
 
81
    Image *const tmpImage = image->SDLgetScaledImage(
 
82
        desiredWidth, desiredHeight);
 
83
 
 
84
    if (!tmpImage)
 
85
        return false;
 
86
    if (!tmpImage->mSDLSurface)
 
87
        return false;
 
88
 
 
89
    const gcn::ClipRectangle &top = mClipStack.top();
 
90
    const SDL_Rect &bounds = image->mBounds;
 
91
 
 
92
    SDL_Rect srcRect =
 
93
    {
 
94
        static_cast<int16_t>(srcX + bounds.x),
 
95
        static_cast<int16_t>(srcY + bounds.y),
 
96
        static_cast<uint16_t>(width),
 
97
        static_cast<uint16_t>(height)
 
98
    };
 
99
 
 
100
    SDL_Rect dstRect =
 
101
    {
 
102
        static_cast<int16_t>(dstX + top.xOffset),
 
103
        static_cast<int16_t>(dstY + top.yOffset),
 
104
        0,
 
105
        0
 
106
    };
 
107
 
 
108
    const bool returnValue = !(SDL_BlitSurface(tmpImage->mSDLSurface,
 
109
        &srcRect, mSurface, &dstRect) < 0);
 
110
 
 
111
    delete tmpImage;
 
112
 
 
113
    return returnValue;
 
114
}
 
115
 
 
116
bool SDL2SoftwareGraphics::drawImage2(const Image *const image,
 
117
                                      int srcX, int srcY,
 
118
                                      int dstX, int dstY, const int width,
 
119
                                      const int height,
 
120
                                      const bool useColor A_UNUSED)
 
121
{
 
122
    FUNC_BLOCK("Graphics::drawImage2", 1)
 
123
    // Check that preconditions for blitting are met.
 
124
    if (!mSurface || !image || !image->mSDLSurface)
 
125
        return false;
 
126
 
 
127
    const gcn::ClipRectangle &top = mClipStack.top();
 
128
    const SDL_Rect &bounds = image->mBounds;
 
129
 
 
130
 
 
131
    SDL_Surface *const src = image->mSDLSurface;
 
132
 
 
133
    srcX += bounds.x;
 
134
    srcY += bounds.y;
 
135
    dstX += top.xOffset;
 
136
    dstY += top.yOffset;
 
137
 
 
138
    int w = width;
 
139
    int h = height;
 
140
    if (srcX < 0)
 
141
    {
 
142
        w += srcX;
 
143
        dstX -= static_cast<int16_t>(srcX);
 
144
        srcX = 0;
 
145
    }
 
146
    const int maxw = src->w - srcX;
 
147
    if (maxw < w)
 
148
        w = maxw;
 
149
 
 
150
    if (srcY < 0)
 
151
    {
 
152
        h += srcY;
 
153
        dstY -= static_cast<int16_t>(srcY);
 
154
        srcY = 0;
 
155
    }
 
156
    const int maxh = src->h - srcY;
 
157
    if (maxh < h)
 
158
        h = maxh;
 
159
 
 
160
    const SDL_Rect *const clip = &mSurface->clip_rect;
 
161
    const int clipX = clip->x;
 
162
    const int clipY = clip->y;
 
163
    int dx = clipX - dstX;
 
164
    if (dx > 0)
 
165
    {
 
166
        w -= dx;
 
167
        dstX += static_cast<int16_t>(dx);
 
168
        srcX += dx;
 
169
    }
 
170
    dx = dstX + w - clipX - clip->w;
 
171
    if (dx > 0)
 
172
        w -= dx;
 
173
 
 
174
    int dy = clipY - dstY;
 
175
    if (dy > 0)
 
176
    {
 
177
        h -= dy;
 
178
        dstY += static_cast<int16_t>(dy);
 
179
        srcY += dy;
 
180
    }
 
181
    dy = dstY + h - clipY - clip->h;
 
182
    if (dy > 0)
 
183
        h -= dy;
 
184
 
 
185
    if (w > 0 && h > 0)
 
186
    {
 
187
        SDL_Rect srcRect =
 
188
        {
 
189
            static_cast<int16_t>(srcX),
 
190
            static_cast<int16_t>(srcY),
 
191
            static_cast<uint16_t>(w),
 
192
            static_cast<uint16_t>(h)
 
193
        };
 
194
 
 
195
        SDL_Rect dstRect =
 
196
        {
 
197
            static_cast<int16_t>(dstX),
 
198
            static_cast<int16_t>(dstY),
 
199
            static_cast<uint16_t>(w),
 
200
            static_cast<uint16_t>(h)
 
201
        };
 
202
 
 
203
        return SDL_LowerBlit(src, &srcRect, mSurface, &dstRect);
 
204
    }
 
205
    return 0;
 
206
}
 
207
 
 
208
void SDL2SoftwareGraphics::drawImagePattern(const Image *const image,
 
209
                                            const int x, const int y,
 
210
                                            const int w, const int h)
 
211
{
 
212
    FUNC_BLOCK("Graphics::drawImagePattern", 1)
 
213
    // Check that preconditions for blitting are met.
 
214
    if (!mSurface || !image)
 
215
        return;
 
216
    if (!image->mSDLSurface)
 
217
        return;
 
218
 
 
219
    const SDL_Rect &bounds = image->mBounds;
 
220
    const int iw = bounds.w;
 
221
    const int ih = bounds.h;
 
222
    if (iw == 0 || ih == 0)
 
223
        return;
 
224
 
 
225
    const gcn::ClipRectangle &top = mClipStack.top();
 
226
    const int xOffset = top.xOffset + x;
 
227
    const int yOffset = top.yOffset + y;
 
228
    const int srcX = bounds.x;
 
229
    const int srcY = bounds.y;
 
230
    SDL_Surface *const src = image->mSDLSurface;
 
231
    const SDL_Rect *const clip = &mSurface->clip_rect;
 
232
    const int clipX = clip->x;
 
233
    const int clipY = clip->y;
 
234
 
 
235
    for (int py = 0; py < h; py += ih)
 
236
    {
 
237
        const int dh = (py + ih >= h) ? h - py : ih;
 
238
        int dstY = py + yOffset;
 
239
        int y2 = srcY;
 
240
        int h2 = dh;
 
241
        if (y2 < 0)
 
242
        {
 
243
            h2 += y2;
 
244
            dstY -= static_cast<int16_t>(y2);
 
245
            y2 = 0;
 
246
        }
 
247
        const int maxh = src->h - y2;
 
248
        if (maxh < h2)
 
249
            h2 = maxh;
 
250
 
 
251
        int dy = clipY - dstY;
 
252
        if (dy > 0)
 
253
        {
 
254
            h2 -= dy;
 
255
            dstY += static_cast<int16_t>(dy);
 
256
            y2 += dy;
 
257
        }
 
258
        dy = dstY + h2 - clipY - clip->h;
 
259
        if (dy > 0)
 
260
            h2 -= dy;
 
261
 
 
262
        if (h2 > 0)
 
263
        {
 
264
            for (int px = 0; px < w; px += iw)
 
265
            {
 
266
                const int dw = (px + iw >= w) ? w - px : iw;
 
267
                int dstX = px + xOffset;
 
268
                int x2 = srcX;
 
269
                int w2 = dw;
 
270
                if (x2 < 0)
 
271
                {
 
272
                    w2 += x2;
 
273
                    dstX -= static_cast<int16_t>(x2);
 
274
                    x2 = 0;
 
275
                }
 
276
                const int maxw = src->w - x2;
 
277
                if (maxw < w2)
 
278
                    w2 = maxw;
 
279
 
 
280
                int dx = clipX - dstX;
 
281
                if (dx > 0)
 
282
                {
 
283
                    w2 -= dx;
 
284
                    dstX += static_cast<int16_t>(dx);
 
285
                    x2 += dx;
 
286
                }
 
287
                dx = dstX + w2 - clipX - clip->w;
 
288
                if (dx > 0)
 
289
                    w2 -= dx;
 
290
 
 
291
                if (w2 > 0)
 
292
                {
 
293
                    SDL_Rect srcRect =
 
294
                    {
 
295
                        static_cast<int16_t>(x2),
 
296
                        static_cast<int16_t>(y2),
 
297
                        static_cast<uint16_t>(w2),
 
298
                        static_cast<uint16_t>(h2)
 
299
                    };
 
300
 
 
301
                    SDL_Rect dstRect =
 
302
                    {
 
303
                        static_cast<int16_t>(dstX),
 
304
                        static_cast<int16_t>(dstY),
 
305
                        static_cast<uint16_t>(w2),
 
306
                        static_cast<uint16_t>(h2)
 
307
                    };
 
308
 
 
309
                    SDL_LowerBlit(src, &srcRect, mSurface, &dstRect);
 
310
                }
 
311
 
 
312
//            SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
 
313
            }
 
314
        }
 
315
    }
 
316
}
 
317
 
 
318
void SDL2SoftwareGraphics::drawRescaledImagePattern(const Image *const image,
 
319
                                                    const int x, const int y,
 
320
                                                    const int w, const int h,
 
321
                                                    const int scaledWidth,
 
322
                                                    const int scaledHeight)
 
323
{
 
324
    // Check that preconditions for blitting are met.
 
325
    if (!mSurface || !image)
 
326
        return;
 
327
    if (!image->mSDLSurface)
 
328
        return;
 
329
 
 
330
    if (scaledHeight == 0 || scaledWidth == 0)
 
331
        return;
 
332
 
 
333
    Image *const tmpImage = image->SDLgetScaledImage(
 
334
        scaledWidth, scaledHeight);
 
335
    if (!tmpImage)
 
336
        return;
 
337
 
 
338
    const SDL_Rect &bounds = tmpImage->mBounds;
 
339
    const int iw = bounds.w;
 
340
    const int ih = bounds.h;
 
341
    if (iw == 0 || ih == 0)
 
342
        return;
 
343
 
 
344
    const gcn::ClipRectangle &top = mClipStack.top();
 
345
    const int xOffset = top.xOffset + x;
 
346
    const int yOffset = top.yOffset + y;
 
347
    const int srcX = bounds.x;
 
348
    const int srcY = bounds.y;
 
349
 
 
350
    for (int py = 0; py < h; py += ih)  // Y position on pattern plane
 
351
    {
 
352
        const int dh = (py + ih >= h) ? h - py : ih;
 
353
        const int dstY = py + yOffset;
 
354
 
 
355
        for (int px = 0; px < w; px += iw)  // X position on pattern plane
 
356
        {
 
357
            const int dw = (px + iw >= w) ? w - px : iw;
 
358
            const int dstX = px + xOffset;
 
359
 
 
360
            SDL_Rect srcRect =
 
361
            {
 
362
                static_cast<int16_t>(srcX),
 
363
                static_cast<int16_t>(srcY),
 
364
                static_cast<uint16_t>(dw),
 
365
                static_cast<uint16_t>(dh)
 
366
            };
 
367
 
 
368
            SDL_Rect dstRect =
 
369
            {
 
370
                static_cast<int16_t>(dstX),
 
371
                static_cast<int16_t>(dstY),
 
372
                0,
 
373
                0
 
374
            };
 
375
 
 
376
            SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect,
 
377
                            mSurface, &dstRect);
 
378
        }
 
379
    }
 
380
 
 
381
    delete tmpImage;
 
382
}
 
383
 
 
384
void SDL2SoftwareGraphics::calcImagePattern(ImageVertexes* const vert,
 
385
                                            const Image *const image,
 
386
                                            const int x, const int y,
 
387
                                            const int w, const int h) const
 
388
{
 
389
    // Check that preconditions for blitting are met.
 
390
    if (!vert || !mSurface || !image || !image->mSDLSurface)
 
391
        return;
 
392
 
 
393
    const SDL_Rect &bounds = image->mBounds;
 
394
    const int iw = bounds.w;
 
395
    const int ih = bounds.h;
 
396
    if (iw == 0 || ih == 0)
 
397
        return;
 
398
 
 
399
    const gcn::ClipRectangle &top = mClipStack.top();
 
400
    const int xOffset = top.xOffset + x;
 
401
    const int yOffset = top.yOffset + y;
 
402
    const int srcX = bounds.x;
 
403
    const int srcY = bounds.y;
 
404
 
 
405
    for (int py = 0; py < h; py += ih)  // Y position on pattern plane
 
406
    {
 
407
        const int dh = (py + ih >= h) ? h - py : ih;
 
408
        const int dstY = py + yOffset;
 
409
 
 
410
        for (int px = 0; px < w; px += iw)  // X position on pattern plane
 
411
        {
 
412
            const int dw = (px + iw >= w) ? w - px : iw;
 
413
            const int dstX = px + xOffset;
 
414
 
 
415
            DoubleRect *const r = new DoubleRect();
 
416
            SDL_Rect &srcRect = r->src;
 
417
            srcRect.x = static_cast<int16_t>(srcX);
 
418
            srcRect.y = static_cast<int16_t>(srcY);
 
419
            srcRect.w = static_cast<uint16_t>(dw);
 
420
            srcRect.h = static_cast<uint16_t>(dh);
 
421
            SDL_Rect &dstRect = r->dst;
 
422
            dstRect.x = static_cast<int16_t>(dstX);
 
423
            dstRect.y = static_cast<int16_t>(dstY);
 
424
 
 
425
            if (SDL_FakeUpperBlit(image->mSDLSurface, &srcRect,
 
426
                mSurface, &dstRect) == 1)
 
427
            {
 
428
                vert->sdl.push_back(r);
 
429
            }
 
430
            else
 
431
            {
 
432
                delete r;
 
433
            }
 
434
        }
 
435
    }
 
436
}
 
437
 
 
438
void SDL2SoftwareGraphics::calcImagePattern(ImageCollection* const vertCol,
 
439
                                            const Image *const image,
 
440
                                            const int x, const int y,
 
441
                                            const int w, const int h) const
 
442
{
 
443
    ImageVertexes *vert = nullptr;
 
444
    if (vertCol->currentImage != image)
 
445
    {
 
446
        vert = new ImageVertexes();
 
447
        vertCol->currentImage = image;
 
448
        vertCol->currentVert = vert;
 
449
        vert->image = image;
 
450
        vertCol->draws.push_back(vert);
 
451
    }
 
452
    else
 
453
    {
 
454
        vert = vertCol->currentVert;
 
455
    }
 
456
 
 
457
    calcImagePattern(vert, image, x, y, w, h);
 
458
}
 
459
 
 
460
void SDL2SoftwareGraphics::calcTile(ImageVertexes *const vert,
 
461
                                    const Image *const image,
 
462
                                    int x, int y) const
 
463
{
 
464
    vert->image = image;
 
465
    calcTileSDL(vert, x, y);
 
466
}
 
467
 
 
468
void SDL2SoftwareGraphics::calcTileSDL(ImageVertexes *const vert,
 
469
                                       int x, int y) const
 
470
{
 
471
    // Check that preconditions for blitting are met.
 
472
    if (!vert || !vert->image || !vert->image->mSDLSurface)
 
473
        return;
 
474
 
 
475
    const Image *const image = vert->image;
 
476
    const gcn::ClipRectangle &top = mClipStack.top();
 
477
    const SDL_Rect &bounds = image->mBounds;
 
478
 
 
479
    DoubleRect *rect = new DoubleRect();
 
480
    rect->src.x = static_cast<int16_t>(bounds.x);
 
481
    rect->src.y = static_cast<int16_t>(bounds.y);
 
482
    rect->src.w = static_cast<uint16_t>(bounds.w);
 
483
    rect->src.h = static_cast<uint16_t>(bounds.h);
 
484
    rect->dst.x = static_cast<int16_t>(x + top.xOffset);
 
485
    rect->dst.y = static_cast<int16_t>(y + top.yOffset);
 
486
    if (SDL_FakeUpperBlit(image->mSDLSurface, &rect->src,
 
487
        mSurface, &rect->dst) == 1)
 
488
    {
 
489
        vert->sdl.push_back(rect);
 
490
    }
 
491
    else
 
492
    {
 
493
        delete rect;
 
494
    }
 
495
}
 
496
 
 
497
void SDL2SoftwareGraphics::calcTile(ImageCollection *const vertCol,
 
498
                                    const Image *const image,
 
499
                                    int x, int y)
 
500
{
 
501
    if (vertCol->currentImage != image)
 
502
    {
 
503
        ImageVertexes *const vert = new ImageVertexes();
 
504
        vertCol->currentImage = image;
 
505
        vertCol->currentVert = vert;
 
506
        vert->image = image;
 
507
        vertCol->draws.push_back(vert);
 
508
        calcTileSDL(vert, x, y);
 
509
    }
 
510
    else
 
511
    {
 
512
        calcTileSDL(vertCol->currentVert, x, y);
 
513
    }
 
514
}
 
515
 
 
516
void SDL2SoftwareGraphics::drawTile(const ImageCollection *const vertCol)
 
517
{
 
518
    const ImageVertexesVector &draws = vertCol->draws;
 
519
    const ImageCollectionCIter it_end = draws.end();
 
520
    for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
 
521
    {
 
522
        const ImageVertexes *const vert = *it;
 
523
        const Image *const img = vert->image;
 
524
        const DoubleRects *const rects = &vert->sdl;
 
525
        DoubleRects::const_iterator it2 = rects->begin();
 
526
        const DoubleRects::const_iterator it2_end = rects->end();
 
527
        while (it2 != it2_end)
 
528
        {
 
529
            SDL_LowerBlit(img->mSDLSurface, &(*it2)->src,
 
530
                mSurface, &(*it2)->dst);
 
531
            ++ it2;
 
532
        }
 
533
    }
 
534
}
 
535
 
 
536
void SDL2SoftwareGraphics::drawTile(const ImageVertexes *const vert)
 
537
{
 
538
    // vert and img must be != 0
 
539
    const Image *const img = vert->image;
 
540
    const DoubleRects *const rects = &vert->sdl;
 
541
    DoubleRects::const_iterator it = rects->begin();
 
542
    const DoubleRects::const_iterator it_end = rects->end();
 
543
    while (it != it_end)
 
544
    {
 
545
        SDL_LowerBlit(img->mSDLSurface, &(*it)->src, mSurface, &(*it)->dst);
 
546
        ++ it;
 
547
    }
 
548
}
 
549
 
 
550
void SDL2SoftwareGraphics::updateScreen()
 
551
{
 
552
    BLOCK_START("Graphics::updateScreen")
 
553
    SDL_UpdateWindowSurfaceRects(mWindow, &mRect, 1);
 
554
    BLOCK_END("Graphics::updateScreen")
 
555
}
 
556
 
 
557
SDL_Surface *SDL2SoftwareGraphics::getScreenshot()
 
558
{
 
559
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
 
560
    const int rmask = 0xff000000;
 
561
    const int gmask = 0x00ff0000;
 
562
    const int bmask = 0x0000ff00;
 
563
#else
 
564
    const int rmask = 0x000000ff;
 
565
    const int gmask = 0x0000ff00;
 
566
    const int bmask = 0x00ff0000;
 
567
#endif
 
568
    const int amask = 0x00000000;
 
569
 
 
570
    SDL_Surface *const screenshot = MSDL_CreateRGBSurface(SDL_SWSURFACE,
 
571
        mRect.w, mRect.h, 24, rmask, gmask, bmask, amask);
 
572
 
 
573
    if (screenshot)
 
574
        SDL_BlitSurface(mSurface, nullptr, screenshot, nullptr);
 
575
 
 
576
    return screenshot;
 
577
}
 
578
 
 
579
bool SDL2SoftwareGraphics::drawNet(const int x1, const int y1,
 
580
                                   const int x2, const int y2,
 
581
                                   const int width, const int height)
 
582
{
 
583
    // +++ need use SDL_RenderDrawLines
 
584
    for (int y = y1; y < y2; y += height)
 
585
        drawLine(x1, y, x2, y);
 
586
 
 
587
    for (int x = x1; x < x2; x += width)
 
588
        drawLine(x, y1, x, y2);
 
589
 
 
590
    return true;
 
591
}
 
592
 
 
593
bool SDL2SoftwareGraphics::calcWindow(ImageCollection *const vertCol,
 
594
                                      const int x, const int y,
 
595
                                      const int w, const int h,
 
596
                                      const ImageRect &imgRect)
 
597
{
 
598
    ImageVertexes *vert = nullptr;
 
599
    Image *const image = imgRect.grid[4];
 
600
    if (vertCol->currentImage != image)
 
601
    {
 
602
        vert = new ImageVertexes();
 
603
        vertCol->currentImage = image;
 
604
        vertCol->currentVert = vert;
 
605
        vert->image = image;
 
606
        vertCol->draws.push_back(vert);
 
607
    }
 
608
    else
 
609
    {
 
610
        vert = vertCol->currentVert;
 
611
    }
 
612
 
 
613
    const Image *const *const grid = &imgRect.grid[0];
 
614
    return calcImageRect(vert, x, y, w, h,
 
615
        grid[0], grid[2], grid[6], grid[8],
 
616
        grid[1], grid[5], grid[7], grid[3],
 
617
        grid[4]);
 
618
}
 
619
 
 
620
int SDL2SoftwareGraphics::SDL_FakeUpperBlit(const SDL_Surface *const src,
 
621
                                            SDL_Rect *const srcrect,
 
622
                                            const SDL_Surface *const dst,
 
623
                                            SDL_Rect *dstrect) const
 
624
{
 
625
    int srcx, srcy, w, h;
 
626
 
 
627
    // Make sure the surfaces aren't locked
 
628
    if (!src || !dst)
 
629
        return -1;
 
630
 
 
631
    if (!srcrect || !dstrect)
 
632
        return -1;
 
633
 
 
634
    srcx = srcrect->x;
 
635
    w = srcrect->w;
 
636
    if (srcx < 0)
 
637
    {
 
638
        w += srcx;
 
639
        dstrect->x -= static_cast<int16_t>(srcx);
 
640
        srcx = 0;
 
641
    }
 
642
    int maxw = src->w - srcx;
 
643
    if (maxw < w)
 
644
        w = maxw;
 
645
 
 
646
    srcy = srcrect->y;
 
647
    h = srcrect->h;
 
648
    if (srcy < 0)
 
649
    {
 
650
        h += srcy;
 
651
        dstrect->y -= static_cast<int16_t>(srcy);
 
652
        srcy = 0;
 
653
    }
 
654
    int maxh = src->h - srcy;
 
655
    if (maxh < h)
 
656
        h = maxh;
 
657
 
 
658
    const SDL_Rect *const clip = &dst->clip_rect;
 
659
    const int clipX = clip->x;
 
660
    const int clipY = clip->y;
 
661
    int dx = clipX - dstrect->x;
 
662
    if (dx > 0)
 
663
    {
 
664
        w -= dx;
 
665
        dstrect->x += static_cast<int16_t>(dx);
 
666
        srcx += dx;
 
667
    }
 
668
    dx = dstrect->x + w - clipX - clip->w;
 
669
    if (dx > 0)
 
670
        w -= dx;
 
671
 
 
672
    int dy = clipY - dstrect->y;
 
673
    if (dy > 0)
 
674
    {
 
675
        h -= dy;
 
676
        dstrect->y += static_cast<int16_t>(dy);
 
677
        srcy += dy;
 
678
    }
 
679
    dy = dstrect->y + h - clipY - clip->h;
 
680
    if (dy > 0)
 
681
        h -= dy;
 
682
 
 
683
    if (w > 0 && h > 0)
 
684
    {
 
685
        if (srcrect)
 
686
        {
 
687
            srcrect->x = static_cast<int16_t>(srcx);
 
688
            srcrect->y = static_cast<int16_t>(srcy);
 
689
            srcrect->w = static_cast<int16_t>(w);
 
690
            srcrect->h = static_cast<int16_t>(h);
 
691
        }
 
692
        dstrect->w = static_cast<int16_t>(w);
 
693
        dstrect->h = static_cast<int16_t>(h);
 
694
 
 
695
        return 1;
 
696
//        return SDL_LowerBlit(src, &sr, dst, dstrect);
 
697
    }
 
698
    dstrect->w = dstrect->h = 0;
 
699
    return 0;
 
700
}
 
701
 
 
702
void SDL2SoftwareGraphics::fillRectangle(const gcn::Rectangle &rectangle)
 
703
{
 
704
    FUNC_BLOCK("Graphics::fillRectangle", 1)
 
705
    if (mClipStack.empty())
 
706
        return;
 
707
 
 
708
    const gcn::ClipRectangle& top = mClipStack.top();
 
709
 
 
710
    gcn::Rectangle area = rectangle;
 
711
    area.x += top.xOffset;
 
712
    area.y += top.yOffset;
 
713
 
 
714
    if (!area.isIntersecting(top))
 
715
        return;
 
716
 
 
717
    if (mAlpha)
 
718
    {
 
719
        const int x1 = area.x > top.x ? area.x : top.x;
 
720
        const int y1 = area.y > top.y ? area.y : top.y;
 
721
        const int x2 = area.x + area.width < top.x + top.width ?
 
722
            area.x + area.width : top.x + top.width;
 
723
        const int y2 = area.y + area.height < top.y + top.height ?
 
724
            area.y + area.height : top.y + top.height;
 
725
        int x, y;
 
726
 
 
727
        SDL_LockSurface(mSurface);
 
728
 
 
729
        const int bpp = mSurface->format->BytesPerPixel;
 
730
        const uint32_t pixel = SDL_MapRGB(mSurface->format,
 
731
            static_cast<uint8_t>(mColor.r), static_cast<uint8_t>(mColor.g),
 
732
            static_cast<uint8_t>(mColor.b));
 
733
 
 
734
        switch (bpp)
 
735
        {
 
736
            case 1:
 
737
                for (y = y1; y < y2; y++)
 
738
                {
 
739
                    uint8_t *const p = static_cast<uint8_t *>(mSurface->pixels)
 
740
                        + y * mSurface->pitch;
 
741
                    for (x = x1; x < x2; x++)
 
742
                        *(p + x) = static_cast<uint8_t>(pixel);
 
743
                }
 
744
                break;
 
745
            case 2:
 
746
                for (y = y1; y < y2; y++)
 
747
                {
 
748
                    uint8_t *const p0 = static_cast<uint8_t *>(
 
749
                        mSurface->pixels) + y * mSurface->pitch;
 
750
                    for (x = x1; x < x2; x++)
 
751
                    {
 
752
                        uint8_t *const p = p0 + x * 2;
 
753
                        *reinterpret_cast<uint16_t *>(p) = gcn::SDLAlpha16(
 
754
                            static_cast<uint16_t>(pixel),
 
755
                            *reinterpret_cast<uint16_t *>(p),
 
756
                            static_cast<uint8_t>(mColor.a), mSurface->format);
 
757
                    }
 
758
                }
 
759
                break;
 
760
            case 3:
 
761
            {
 
762
                const int ca = 255 - mColor.a;
 
763
                const int cr = mColor.r * mColor.a;
 
764
                const int cg = mColor.g * mColor.a;
 
765
                const int cb = mColor.b * mColor.a;
 
766
 
 
767
                for (y = y1; y < y2; y++)
 
768
                {
 
769
                    uint8_t *const p0 = static_cast<uint8_t *>(
 
770
                        mSurface->pixels) + y * mSurface->pitch;
 
771
                    for (x = x1; x < x2; x++)
 
772
                    {
 
773
                        uint8_t *const p = p0 + x * 3;
 
774
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
 
775
                        p[2] = static_cast<uint8_t>((p[2] * ca + cb) >> 8);
 
776
                        p[1] = static_cast<uint8_t>((p[1] * ca + cg) >> 8);
 
777
                        p[0] = static_cast<uint8_t>((p[0] * ca + cr) >> 8);
 
778
#else
 
779
                        p[0] = static_cast<uint8_t>((p[0] * ca + cb) >> 8);
 
780
                        p[1] = static_cast<uint8_t>((p[1] * ca + cg) >> 8);
 
781
                        p[2] = static_cast<uint8_t>((p[2] * ca + cr) >> 8);
 
782
#endif
 
783
                    }
 
784
                }
 
785
                break;
 
786
            }
 
787
            case 4:
 
788
            {
 
789
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
 
790
                const unsigned pb = (pixel & 0xff) * mColor.a;
 
791
                const unsigned pg = (pixel & 0xff00) * mColor.a;
 
792
                const unsigned pr = (pixel & 0xff0000) * mColor.a;
 
793
                const unsigned a1 = (255 - mColor.a);
 
794
 
 
795
                for (y = y1; y < y2; y++)
 
796
                {
 
797
                    uint8_t *const p0 = static_cast<uint8_t *>(
 
798
                        mSurface->pixels) + y * mSurface->pitch;
 
799
                    for (x = x1; x < x2; x++)
 
800
                    {
 
801
                        uint8_t *p = p0 + x * 4;
 
802
                        uint32_t dst = *reinterpret_cast<uint32_t *>(p);
 
803
                        const unsigned int b = (pb + (dst & 0xff) * a1) >> 8;
 
804
                        const unsigned int g = (pg + (dst & 0xff00) * a1) >> 8;
 
805
                        const unsigned int r = (pr
 
806
                            + (dst & 0xff0000) * a1) >> 8;
 
807
 
 
808
                        *reinterpret_cast<uint32_t *>(p) = ((b & 0xff)
 
809
                            | (g & 0xff00) | (r & 0xff0000));
 
810
                    }
 
811
                }
 
812
#else
 
813
                if (!cR)
 
814
                {
 
815
                    cR = new unsigned int[0x100];
 
816
                    cG = new unsigned int[0x100];
 
817
                    cB = new unsigned int[0x100];
 
818
                    mOldPixel = 0;
 
819
                    mOldAlpha = mColor.a;
 
820
                }
 
821
 
 
822
                const SDL_PixelFormat * const format = mSurface->format;
 
823
                const unsigned rMask = format->Rmask;
 
824
                const unsigned gMask = format->Gmask;
 
825
                const unsigned bMask = format->Bmask;
 
826
//                const unsigned aMask = format->Amask;
 
827
                unsigned rShift = rMask / 0xff;
 
828
                unsigned gShift = gMask / 0xff;
 
829
                unsigned bShift = bMask / 0xff;
 
830
                if (!rShift)
 
831
                    rShift = 1;
 
832
                if (!gShift)
 
833
                    gShift = 1;
 
834
                if (!bShift)
 
835
                    bShift = 1;
 
836
                if (pixel != mOldPixel || mColor.a != mOldAlpha)
 
837
                {
 
838
                    const unsigned pb = (pixel & bMask) * mColor.a;
 
839
                    const unsigned pg = (pixel & gMask) * mColor.a;
 
840
                    const unsigned pr = (pixel & rMask) * mColor.a;
 
841
                    const unsigned a0 = (255 - mColor.a);
 
842
 
 
843
                    const unsigned int a1 = a0 * bShift;
 
844
                    const unsigned int a2 = a0 * gShift;
 
845
                    const unsigned int a3 = a0 * rShift;
 
846
 
 
847
                    for (int f = 0; f <= 0xff; f ++)
 
848
                    {
 
849
                        cB[f] = ((pb + f * a1) >> 8) & bMask;
 
850
                        cG[f] = ((pg + f * a2) >> 8) & gMask;
 
851
                        cR[f] = ((pr + f * a3) >> 8) & rMask;
 
852
                    }
 
853
 
 
854
                    mOldPixel = pixel;
 
855
                    mOldAlpha = mColor.a;
 
856
                }
 
857
 
 
858
                for (y = y1; y < y2; y++)
 
859
                {
 
860
                    uint32_t *const p0 = reinterpret_cast<uint32_t*>(
 
861
                        static_cast<uint8_t*>(mSurface->pixels)
 
862
                        + y * mSurface->pitch);
 
863
                    for (x = x1; x < x2; x++)
 
864
                    {
 
865
                        uint32_t *const p = p0 + x;
 
866
                        const uint32_t dst = *p;
 
867
                        *p = cB[dst & bMask / bShift]
 
868
                            | cG[(dst & gMask) / gShift]
 
869
                            | cR[(dst & rMask) / rShift];
 
870
                    }
 
871
                }
 
872
#endif
 
873
                break;
 
874
            }
 
875
            default:
 
876
                break;
 
877
        }
 
878
 
 
879
        SDL_UnlockSurface(mSurface);
 
880
    }
 
881
    else
 
882
    {
 
883
        SDL_Rect rect =
 
884
        {
 
885
            static_cast<int16_t>(area.x),
 
886
            static_cast<int16_t>(area.y),
 
887
            static_cast<uint16_t>(area.width),
 
888
            static_cast<uint16_t>(area.height)
 
889
        };
 
890
 
 
891
        const uint32_t color = SDL_MapRGBA(mSurface->format,
 
892
            static_cast<int8_t>(mColor.r),
 
893
            static_cast<int8_t>(mColor.g),
 
894
            static_cast<int8_t>(mColor.b),
 
895
            static_cast<int8_t>(mColor.a));
 
896
        SDL_FillRect(mSurface, &rect, color);
 
897
    }
 
898
}
 
899
 
 
900
void SDL2SoftwareGraphics::_beginDraw()
 
901
{
 
902
    pushClipArea(gcn::Rectangle(0, 0, mRect.w, mRect.h));
 
903
}
 
904
 
 
905
void SDL2SoftwareGraphics::_endDraw()
 
906
{
 
907
    popClipArea();
 
908
}
 
909
 
 
910
bool SDL2SoftwareGraphics::pushClipArea(gcn::Rectangle area)
 
911
{
 
912
    const bool result = gcn::Graphics::pushClipArea(area);
 
913
 
 
914
    const gcn::ClipRectangle &carea = mClipStack.top();
 
915
    const SDL_Rect rect =
 
916
    {
 
917
        static_cast<int32_t>(carea.x),
 
918
        static_cast<int32_t>(carea.y),
 
919
        static_cast<int32_t>(carea.width),
 
920
        static_cast<int32_t>(carea.height)
 
921
    };
 
922
    SDL_SetClipRect(mSurface, &rect);
 
923
    return result;
 
924
}
 
925
 
 
926
void SDL2SoftwareGraphics::popClipArea()
 
927
{
 
928
    gcn::Graphics::popClipArea();
 
929
 
 
930
    if (mClipStack.empty())
 
931
        return;
 
932
 
 
933
    const gcn::ClipRectangle &carea = mClipStack.top();
 
934
    const SDL_Rect rect =
 
935
    {
 
936
        static_cast<int32_t>(carea.x),
 
937
        static_cast<int32_t>(carea.y),
 
938
        static_cast<int32_t>(carea.width),
 
939
        static_cast<int32_t>(carea.height)
 
940
    };
 
941
 
 
942
    SDL_SetClipRect(mSurface, &rect);
 
943
}
 
944
 
 
945
void SDL2SoftwareGraphics::drawPoint(int x, int y)
 
946
{
 
947
    if (mClipStack.empty())
 
948
        return;
 
949
 
 
950
    const gcn::ClipRectangle& top = mClipStack.top();
 
951
 
 
952
    x += top.xOffset;
 
953
    y += top.yOffset;
 
954
 
 
955
    if (!top.isPointInRect(x, y))
 
956
        return;
 
957
 
 
958
    if (mAlpha)
 
959
        SDLputPixelAlpha(mSurface, x, y, mColor);
 
960
    else
 
961
        SDLputPixel(mSurface, x, y, mColor);
 
962
}
 
963
 
 
964
void SDL2SoftwareGraphics::drawHLine(int x1, int y, int x2)
 
965
{
 
966
    if (mClipStack.empty())
 
967
        return;
 
968
 
 
969
    const gcn::ClipRectangle& top = mClipStack.top();
 
970
 
 
971
    const int xOffset = top.xOffset;
 
972
    x1 += xOffset;
 
973
    y += top.yOffset;
 
974
    x2 += xOffset;
 
975
 
 
976
    const int topY = top.y;
 
977
    if (y < topY || y >= topY + top.height)
 
978
        return;
 
979
 
 
980
    if (x1 > x2)
 
981
    {
 
982
        x1 ^= x2;
 
983
        x2 ^= x1;
 
984
        x1 ^= x2;
 
985
    }
 
986
 
 
987
    const int topX = top.x;
 
988
    if (topX > x1)
 
989
    {
 
990
        if (topX > x2)
 
991
            return;
 
992
 
 
993
        x1 = topX;
 
994
    }
 
995
 
 
996
    const int sumX = topX + top.width;
 
997
    if (sumX <= x2)
 
998
    {
 
999
        if (sumX <= x1)
 
1000
            return;
 
1001
 
 
1002
        x2 = sumX -1;
 
1003
    }
 
1004
 
 
1005
    const int bpp = mSurface->format->BytesPerPixel;
 
1006
 
 
1007
    SDL_LockSurface(mSurface);
 
1008
 
 
1009
    uint8_t *p = static_cast<uint8_t*>(mSurface->pixels)
 
1010
        + y * mSurface->pitch + x1 * bpp;
 
1011
 
 
1012
    const uint32_t pixel = SDL_MapRGB(mSurface->format,
 
1013
        static_cast<uint8_t>(mColor.r),
 
1014
        static_cast<uint8_t>(mColor.g),
 
1015
        static_cast<uint8_t>(mColor.b));
 
1016
    switch (bpp)
 
1017
    {
 
1018
        case 1:
 
1019
            for (; x1 <= x2; ++x1)
 
1020
                *(p++) = static_cast<uint8_t>(pixel);
 
1021
            break;
 
1022
 
 
1023
        case 2:
 
1024
        {
 
1025
            uint16_t* q = reinterpret_cast<uint16_t*>(p);
 
1026
            for (; x1 <= x2; ++x1)
 
1027
                *(q++) = pixel;
 
1028
            break;
 
1029
        }
 
1030
 
 
1031
        case 3:
 
1032
        {
 
1033
            const uint8_t b0 = static_cast<uint8_t>((pixel >> 16) & 0xff);
 
1034
            const uint8_t b1 = static_cast<uint8_t>((pixel >> 8) & 0xff);
 
1035
            const uint8_t b2 = static_cast<uint8_t>(pixel & 0xff);
 
1036
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
 
1037
            for (; x1 <= x2; ++x1)
 
1038
            {
 
1039
                p[0] = b0;
 
1040
                p[1] = b1;
 
1041
                p[2] = b2;
 
1042
                p += 3;
 
1043
            }
 
1044
#else
 
1045
            for (; x1 <= x2; ++x1)
 
1046
            {
 
1047
                p[0] = b2;
 
1048
                p[1] = b1;
 
1049
                p[2] = b0;
 
1050
                p += 3;
 
1051
            }
 
1052
#endif
 
1053
            break;
 
1054
        }
 
1055
 
 
1056
        case 4:
 
1057
        {
 
1058
            uint32_t *q = reinterpret_cast<uint32_t*>(p);
 
1059
            if (mAlpha)
 
1060
            {
 
1061
                unsigned char a = static_cast<unsigned char>(mColor.a);
 
1062
                unsigned char a1 = 255 - a;
 
1063
                const int b0 = (pixel & 0xff) * a;
 
1064
                const int g0 = (pixel & 0xff00) * a;
 
1065
                const int r0 = (pixel & 0xff0000) * a;
 
1066
                for (; x1 <= x2; ++x1)
 
1067
                {
 
1068
                    const unsigned int b = (b0 + (*q & 0xff) * a1) >> 8;
 
1069
                    const unsigned int g = (g0 + (*q & 0xff00) * a1) >> 8;
 
1070
                    const unsigned int r = (r0 + (*q & 0xff0000) * a1) >> 8;
 
1071
                    *q = (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
 
1072
 
 
1073
                    q++;
 
1074
                }
 
1075
            }
 
1076
            else
 
1077
            {
 
1078
                for (; x1 <= x2; ++x1)
 
1079
                    *(q++) = pixel;
 
1080
            }
 
1081
            break;
 
1082
        }
 
1083
        default:
 
1084
            break;
 
1085
    }  // end switch
 
1086
 
 
1087
    SDL_UnlockSurface(mSurface);
 
1088
}
 
1089
 
 
1090
void SDL2SoftwareGraphics::drawVLine(int x, int y1, int y2)
 
1091
{
 
1092
    if (mClipStack.empty())
 
1093
        return;
 
1094
 
 
1095
    const gcn::ClipRectangle& top = mClipStack.top();
 
1096
 
 
1097
    const int yOffset = top.yOffset;
 
1098
    x += top.xOffset;
 
1099
    y1 += yOffset;
 
1100
    y2 += yOffset;
 
1101
 
 
1102
    if (x < top.x || x >= top.x + top.width)
 
1103
        return;
 
1104
 
 
1105
    if (y1 > y2)
 
1106
    {
 
1107
        y1 ^= y2;
 
1108
        y2 ^= y1;
 
1109
        y1 ^= y2;
 
1110
    }
 
1111
 
 
1112
    if (top.y > y1)
 
1113
    {
 
1114
        if (top.y > y2)
 
1115
            return;
 
1116
 
 
1117
        y1 = top.y;
 
1118
    }
 
1119
 
 
1120
    const int sumY = top.y + top.height;
 
1121
    if (sumY <= y2)
 
1122
    {
 
1123
        if (sumY <= y1)
 
1124
            return;
 
1125
 
 
1126
        y2 = sumY - 1;
 
1127
    }
 
1128
 
 
1129
    const int bpp = mSurface->format->BytesPerPixel;
 
1130
 
 
1131
    SDL_LockSurface(mSurface);
 
1132
 
 
1133
    uint8_t *p = static_cast<uint8_t*>(mSurface->pixels)
 
1134
        + y1 * mSurface->pitch + x * bpp;
 
1135
 
 
1136
    const uint32_t pixel = SDL_MapRGB(mSurface->format,
 
1137
        static_cast<uint8_t>(mColor.r),
 
1138
        static_cast<uint8_t>(mColor.g),
 
1139
        static_cast<uint8_t>(mColor.b));
 
1140
 
 
1141
    const int pitch = mSurface->pitch;
 
1142
    switch (bpp)
 
1143
    {
 
1144
        case 1:
 
1145
            for (; y1 <= y2; ++y1)
 
1146
            {
 
1147
                *p = static_cast<uint8_t>(pixel);
 
1148
                p += pitch;
 
1149
            }
 
1150
            break;
 
1151
 
 
1152
        case 2:
 
1153
            for (; y1 <= y2; ++ y1)
 
1154
            {
 
1155
                *reinterpret_cast<uint16_t*>(p)
 
1156
                    = static_cast<uint16_t>(pixel);
 
1157
                p += pitch;
 
1158
            }
 
1159
            break;
 
1160
 
 
1161
        case 3:
 
1162
        {
 
1163
            const uint8_t b0 = static_cast<uint8_t>((pixel >> 16) & 0xff);
 
1164
            const uint8_t b1 = static_cast<uint8_t>((pixel >> 8) & 0xff);
 
1165
            const uint8_t b2 = static_cast<uint8_t>(pixel & 0xff);
 
1166
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
 
1167
            for (; y1 <= y2; ++y1)
 
1168
            {
 
1169
                p[0] = b0;
 
1170
                p[1] = b1;
 
1171
                p[2] = b2;
 
1172
                p += pitch;
 
1173
            }
 
1174
#else
 
1175
            for (; y1 <= y2; ++y1)
 
1176
            {
 
1177
                p[0] = b2;
 
1178
                p[1] = b1;
 
1179
                p[2] = b0;
 
1180
                p += pitch;
 
1181
            }
 
1182
#endif
 
1183
            break;
 
1184
        }
 
1185
 
 
1186
        case 4:
 
1187
        {
 
1188
            if (mAlpha)
 
1189
            {
 
1190
                unsigned char a = static_cast<unsigned char>(mColor.a);
 
1191
                unsigned char a1 = 255 - a;
 
1192
                const int b0 = (pixel & 0xff) * a;
 
1193
                const int g0 = (pixel & 0xff00) * a;
 
1194
                const int r0 = (pixel & 0xff0000) * a;
 
1195
                for (; y1 <= y2; ++y1)
 
1196
                {
 
1197
                    const unsigned int dst = *reinterpret_cast<uint32_t*>(p);
 
1198
                    const unsigned int b = (b0 + (dst & 0xff) * a1) >> 8;
 
1199
                    const unsigned int g = (g0 + (dst & 0xff00) * a1) >> 8;
 
1200
                    const unsigned int r = (r0 + (dst & 0xff0000) * a1) >> 8;
 
1201
                    *reinterpret_cast<uint32_t*>(p) =
 
1202
                        (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
 
1203
 
 
1204
                    p += pitch;
 
1205
                }
 
1206
            }
 
1207
            else
 
1208
            {
 
1209
                for (; y1 <= y2; ++y1)
 
1210
                {
 
1211
                    *reinterpret_cast<uint32_t*>(p) = pixel;
 
1212
                    p += pitch;
 
1213
                }
 
1214
            }
 
1215
            break;
 
1216
        }
 
1217
 
 
1218
        default:
 
1219
            break;
 
1220
    }  // end switch
 
1221
 
 
1222
    SDL_UnlockSurface(mSurface);
 
1223
}
 
1224
 
 
1225
void SDL2SoftwareGraphics::drawRectangle(const gcn::Rectangle &rectangle)
 
1226
{
 
1227
    const int x1 = rectangle.x;
 
1228
    const int x2 = x1 + rectangle.width - 1;
 
1229
    const int y1 = rectangle.y;
 
1230
    const int y2 = y1 + rectangle.height - 1;
 
1231
 
 
1232
    drawHLine(x1, y1, x2);
 
1233
    drawHLine(x1, y2, x2);
 
1234
 
 
1235
    drawVLine(x1, y1, y2);
 
1236
    drawVLine(x2, y1, y2);
 
1237
}
 
1238
 
 
1239
void SDL2SoftwareGraphics::drawLine(int x1, int y1, int x2, int y2)
 
1240
{
 
1241
    if (x1 == x2)
 
1242
    {
 
1243
        drawVLine(x1, y1, y2);
 
1244
        return;
 
1245
    }
 
1246
    if (y1 == y2)
 
1247
    {
 
1248
        drawHLine(x1, y1, x2);
 
1249
        return;
 
1250
    }
 
1251
}
 
1252
 
 
1253
bool SDL2SoftwareGraphics::setVideoMode(const int w, const int h,
 
1254
                                        const int bpp, const bool fs,
 
1255
                                        const bool hwaccel, const bool resize,
 
1256
                                        const bool noFrame)
 
1257
{
 
1258
    setMainFlags(w, h, bpp, fs, hwaccel, resize, noFrame);
 
1259
 
 
1260
    if (!(mWindow = graphicsManager.createWindow(w, h, bpp,
 
1261
        getSoftwareFlags())))
 
1262
    {
 
1263
        mRect.w = 0;
 
1264
        mRect.h = 0;
 
1265
        mSurface = nullptr;
 
1266
        return false;
 
1267
    }
 
1268
 
 
1269
    mSurface = SDL_GetWindowSurface(mWindow);
 
1270
    imageHelper->dumpSurfaceFormat(mSurface);
 
1271
    SDL2SoftwareImageHelper::setFormat(mSurface->format);
 
1272
 
 
1273
    int w1 = 0;
 
1274
    int h1 = 0;
 
1275
    SDL_GetWindowSize(mWindow, &w1, &h1);
 
1276
    mRect.w = w1;
 
1277
    mRect.h = h1;
 
1278
 
 
1279
    mRenderer = graphicsManager.createRenderer(mWindow, mRendererFlags);
 
1280
    return videoInfo();
 
1281
}
 
1282
 
 
1283
bool SDL2SoftwareGraphics::resizeScreen(const int width, const int height)
 
1284
{
 
1285
    const bool ret = Graphics::resizeScreen(width, height);
 
1286
 
 
1287
    mSurface = SDL_GetWindowSurface(mWindow);
 
1288
    SDL2SoftwareImageHelper::setFormat(mSurface->format);
 
1289
    return ret;
 
1290
}
 
1291
 
 
1292
#endif  // USE_SDL2