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
7
* This file is part of The ManaPlus Client.
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
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.
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/>.
25
#include "render/sdl2softwaregraphics.h"
29
#include "configuration.h"
30
#include "graphicsmanager.h"
31
#include "graphicsvertexes.h"
34
#include "resources/imagehelper.h"
35
#include "resources/sdl2softwareimagehelper.h"
37
#include <guichan/sdl/sdlpixel.hpp>
39
#include "utils/sdlcheckutils.h"
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;
51
SDL2SoftwareGraphics::SDL2SoftwareGraphics() :
53
mRendererFlags(SDL_RENDERER_SOFTWARE),
58
mOpenGL = RENDER_SOFTWARE;
62
SDL2SoftwareGraphics::~SDL2SoftwareGraphics()
66
bool SDL2SoftwareGraphics::drawRescaledImage(const Image *const image,
69
const int width, const int height,
70
const int desiredWidth,
71
const int desiredHeight,
72
const bool useColor A_UNUSED)
74
FUNC_BLOCK("Graphics::drawRescaledImage", 1)
75
// Check that preconditions for blitting are met.
76
if (!mSurface || !image)
78
if (!image->mSDLSurface)
81
Image *const tmpImage = image->SDLgetScaledImage(
82
desiredWidth, desiredHeight);
86
if (!tmpImage->mSDLSurface)
89
const gcn::ClipRectangle &top = mClipStack.top();
90
const SDL_Rect &bounds = image->mBounds;
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)
102
static_cast<int16_t>(dstX + top.xOffset),
103
static_cast<int16_t>(dstY + top.yOffset),
108
const bool returnValue = !(SDL_BlitSurface(tmpImage->mSDLSurface,
109
&srcRect, mSurface, &dstRect) < 0);
116
bool SDL2SoftwareGraphics::drawImage2(const Image *const image,
118
int dstX, int dstY, const int width,
120
const bool useColor A_UNUSED)
122
FUNC_BLOCK("Graphics::drawImage2", 1)
123
// Check that preconditions for blitting are met.
124
if (!mSurface || !image || !image->mSDLSurface)
127
const gcn::ClipRectangle &top = mClipStack.top();
128
const SDL_Rect &bounds = image->mBounds;
131
SDL_Surface *const src = image->mSDLSurface;
143
dstX -= static_cast<int16_t>(srcX);
146
const int maxw = src->w - srcX;
153
dstY -= static_cast<int16_t>(srcY);
156
const int maxh = src->h - srcY;
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;
167
dstX += static_cast<int16_t>(dx);
170
dx = dstX + w - clipX - clip->w;
174
int dy = clipY - dstY;
178
dstY += static_cast<int16_t>(dy);
181
dy = dstY + h - clipY - clip->h;
189
static_cast<int16_t>(srcX),
190
static_cast<int16_t>(srcY),
191
static_cast<uint16_t>(w),
192
static_cast<uint16_t>(h)
197
static_cast<int16_t>(dstX),
198
static_cast<int16_t>(dstY),
199
static_cast<uint16_t>(w),
200
static_cast<uint16_t>(h)
203
return SDL_LowerBlit(src, &srcRect, mSurface, &dstRect);
208
void SDL2SoftwareGraphics::drawImagePattern(const Image *const image,
209
const int x, const int y,
210
const int w, const int h)
212
FUNC_BLOCK("Graphics::drawImagePattern", 1)
213
// Check that preconditions for blitting are met.
214
if (!mSurface || !image)
216
if (!image->mSDLSurface)
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)
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;
235
for (int py = 0; py < h; py += ih)
237
const int dh = (py + ih >= h) ? h - py : ih;
238
int dstY = py + yOffset;
244
dstY -= static_cast<int16_t>(y2);
247
const int maxh = src->h - y2;
251
int dy = clipY - dstY;
255
dstY += static_cast<int16_t>(dy);
258
dy = dstY + h2 - clipY - clip->h;
264
for (int px = 0; px < w; px += iw)
266
const int dw = (px + iw >= w) ? w - px : iw;
267
int dstX = px + xOffset;
273
dstX -= static_cast<int16_t>(x2);
276
const int maxw = src->w - x2;
280
int dx = clipX - dstX;
284
dstX += static_cast<int16_t>(dx);
287
dx = dstX + w2 - clipX - clip->w;
295
static_cast<int16_t>(x2),
296
static_cast<int16_t>(y2),
297
static_cast<uint16_t>(w2),
298
static_cast<uint16_t>(h2)
303
static_cast<int16_t>(dstX),
304
static_cast<int16_t>(dstY),
305
static_cast<uint16_t>(w2),
306
static_cast<uint16_t>(h2)
309
SDL_LowerBlit(src, &srcRect, mSurface, &dstRect);
312
// SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
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)
324
// Check that preconditions for blitting are met.
325
if (!mSurface || !image)
327
if (!image->mSDLSurface)
330
if (scaledHeight == 0 || scaledWidth == 0)
333
Image *const tmpImage = image->SDLgetScaledImage(
334
scaledWidth, scaledHeight);
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)
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;
350
for (int py = 0; py < h; py += ih) // Y position on pattern plane
352
const int dh = (py + ih >= h) ? h - py : ih;
353
const int dstY = py + yOffset;
355
for (int px = 0; px < w; px += iw) // X position on pattern plane
357
const int dw = (px + iw >= w) ? w - px : iw;
358
const int dstX = px + xOffset;
362
static_cast<int16_t>(srcX),
363
static_cast<int16_t>(srcY),
364
static_cast<uint16_t>(dw),
365
static_cast<uint16_t>(dh)
370
static_cast<int16_t>(dstX),
371
static_cast<int16_t>(dstY),
376
SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect,
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
389
// Check that preconditions for blitting are met.
390
if (!vert || !mSurface || !image || !image->mSDLSurface)
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)
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;
405
for (int py = 0; py < h; py += ih) // Y position on pattern plane
407
const int dh = (py + ih >= h) ? h - py : ih;
408
const int dstY = py + yOffset;
410
for (int px = 0; px < w; px += iw) // X position on pattern plane
412
const int dw = (px + iw >= w) ? w - px : iw;
413
const int dstX = px + xOffset;
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);
425
if (SDL_FakeUpperBlit(image->mSDLSurface, &srcRect,
426
mSurface, &dstRect) == 1)
428
vert->sdl.push_back(r);
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
443
ImageVertexes *vert = nullptr;
444
if (vertCol->currentImage != image)
446
vert = new ImageVertexes();
447
vertCol->currentImage = image;
448
vertCol->currentVert = vert;
450
vertCol->draws.push_back(vert);
454
vert = vertCol->currentVert;
457
calcImagePattern(vert, image, x, y, w, h);
460
void SDL2SoftwareGraphics::calcTile(ImageVertexes *const vert,
461
const Image *const image,
465
calcTileSDL(vert, x, y);
468
void SDL2SoftwareGraphics::calcTileSDL(ImageVertexes *const vert,
471
// Check that preconditions for blitting are met.
472
if (!vert || !vert->image || !vert->image->mSDLSurface)
475
const Image *const image = vert->image;
476
const gcn::ClipRectangle &top = mClipStack.top();
477
const SDL_Rect &bounds = image->mBounds;
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)
489
vert->sdl.push_back(rect);
497
void SDL2SoftwareGraphics::calcTile(ImageCollection *const vertCol,
498
const Image *const image,
501
if (vertCol->currentImage != image)
503
ImageVertexes *const vert = new ImageVertexes();
504
vertCol->currentImage = image;
505
vertCol->currentVert = vert;
507
vertCol->draws.push_back(vert);
508
calcTileSDL(vert, x, y);
512
calcTileSDL(vertCol->currentVert, x, y);
516
void SDL2SoftwareGraphics::drawTile(const ImageCollection *const vertCol)
518
const ImageVertexesVector &draws = vertCol->draws;
519
const ImageCollectionCIter it_end = draws.end();
520
for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
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)
529
SDL_LowerBlit(img->mSDLSurface, &(*it2)->src,
530
mSurface, &(*it2)->dst);
536
void SDL2SoftwareGraphics::drawTile(const ImageVertexes *const vert)
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();
545
SDL_LowerBlit(img->mSDLSurface, &(*it)->src, mSurface, &(*it)->dst);
550
void SDL2SoftwareGraphics::updateScreen()
552
BLOCK_START("Graphics::updateScreen")
553
SDL_UpdateWindowSurfaceRects(mWindow, &mRect, 1);
554
BLOCK_END("Graphics::updateScreen")
557
SDL_Surface *SDL2SoftwareGraphics::getScreenshot()
559
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
560
const int rmask = 0xff000000;
561
const int gmask = 0x00ff0000;
562
const int bmask = 0x0000ff00;
564
const int rmask = 0x000000ff;
565
const int gmask = 0x0000ff00;
566
const int bmask = 0x00ff0000;
568
const int amask = 0x00000000;
570
SDL_Surface *const screenshot = MSDL_CreateRGBSurface(SDL_SWSURFACE,
571
mRect.w, mRect.h, 24, rmask, gmask, bmask, amask);
574
SDL_BlitSurface(mSurface, nullptr, screenshot, nullptr);
579
bool SDL2SoftwareGraphics::drawNet(const int x1, const int y1,
580
const int x2, const int y2,
581
const int width, const int height)
583
// +++ need use SDL_RenderDrawLines
584
for (int y = y1; y < y2; y += height)
585
drawLine(x1, y, x2, y);
587
for (int x = x1; x < x2; x += width)
588
drawLine(x, y1, x, y2);
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)
598
ImageVertexes *vert = nullptr;
599
Image *const image = imgRect.grid[4];
600
if (vertCol->currentImage != image)
602
vert = new ImageVertexes();
603
vertCol->currentImage = image;
604
vertCol->currentVert = vert;
606
vertCol->draws.push_back(vert);
610
vert = vertCol->currentVert;
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],
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
625
int srcx, srcy, w, h;
627
// Make sure the surfaces aren't locked
631
if (!srcrect || !dstrect)
639
dstrect->x -= static_cast<int16_t>(srcx);
642
int maxw = src->w - srcx;
651
dstrect->y -= static_cast<int16_t>(srcy);
654
int maxh = src->h - srcy;
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;
665
dstrect->x += static_cast<int16_t>(dx);
668
dx = dstrect->x + w - clipX - clip->w;
672
int dy = clipY - dstrect->y;
676
dstrect->y += static_cast<int16_t>(dy);
679
dy = dstrect->y + h - clipY - clip->h;
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);
692
dstrect->w = static_cast<int16_t>(w);
693
dstrect->h = static_cast<int16_t>(h);
696
// return SDL_LowerBlit(src, &sr, dst, dstrect);
698
dstrect->w = dstrect->h = 0;
702
void SDL2SoftwareGraphics::fillRectangle(const gcn::Rectangle &rectangle)
704
FUNC_BLOCK("Graphics::fillRectangle", 1)
705
if (mClipStack.empty())
708
const gcn::ClipRectangle& top = mClipStack.top();
710
gcn::Rectangle area = rectangle;
711
area.x += top.xOffset;
712
area.y += top.yOffset;
714
if (!area.isIntersecting(top))
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;
727
SDL_LockSurface(mSurface);
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));
737
for (y = y1; y < y2; y++)
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);
746
for (y = y1; y < y2; y++)
748
uint8_t *const p0 = static_cast<uint8_t *>(
749
mSurface->pixels) + y * mSurface->pitch;
750
for (x = x1; x < x2; x++)
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);
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;
767
for (y = y1; y < y2; y++)
769
uint8_t *const p0 = static_cast<uint8_t *>(
770
mSurface->pixels) + y * mSurface->pitch;
771
for (x = x1; x < x2; x++)
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);
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);
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);
795
for (y = y1; y < y2; y++)
797
uint8_t *const p0 = static_cast<uint8_t *>(
798
mSurface->pixels) + y * mSurface->pitch;
799
for (x = x1; x < x2; x++)
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;
808
*reinterpret_cast<uint32_t *>(p) = ((b & 0xff)
809
| (g & 0xff00) | (r & 0xff0000));
815
cR = new unsigned int[0x100];
816
cG = new unsigned int[0x100];
817
cB = new unsigned int[0x100];
819
mOldAlpha = mColor.a;
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;
836
if (pixel != mOldPixel || mColor.a != mOldAlpha)
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);
843
const unsigned int a1 = a0 * bShift;
844
const unsigned int a2 = a0 * gShift;
845
const unsigned int a3 = a0 * rShift;
847
for (int f = 0; f <= 0xff; f ++)
849
cB[f] = ((pb + f * a1) >> 8) & bMask;
850
cG[f] = ((pg + f * a2) >> 8) & gMask;
851
cR[f] = ((pr + f * a3) >> 8) & rMask;
855
mOldAlpha = mColor.a;
858
for (y = y1; y < y2; y++)
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++)
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];
879
SDL_UnlockSurface(mSurface);
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)
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);
900
void SDL2SoftwareGraphics::_beginDraw()
902
pushClipArea(gcn::Rectangle(0, 0, mRect.w, mRect.h));
905
void SDL2SoftwareGraphics::_endDraw()
910
bool SDL2SoftwareGraphics::pushClipArea(gcn::Rectangle area)
912
const bool result = gcn::Graphics::pushClipArea(area);
914
const gcn::ClipRectangle &carea = mClipStack.top();
915
const SDL_Rect rect =
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)
922
SDL_SetClipRect(mSurface, &rect);
926
void SDL2SoftwareGraphics::popClipArea()
928
gcn::Graphics::popClipArea();
930
if (mClipStack.empty())
933
const gcn::ClipRectangle &carea = mClipStack.top();
934
const SDL_Rect rect =
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)
942
SDL_SetClipRect(mSurface, &rect);
945
void SDL2SoftwareGraphics::drawPoint(int x, int y)
947
if (mClipStack.empty())
950
const gcn::ClipRectangle& top = mClipStack.top();
955
if (!top.isPointInRect(x, y))
959
SDLputPixelAlpha(mSurface, x, y, mColor);
961
SDLputPixel(mSurface, x, y, mColor);
964
void SDL2SoftwareGraphics::drawHLine(int x1, int y, int x2)
966
if (mClipStack.empty())
969
const gcn::ClipRectangle& top = mClipStack.top();
971
const int xOffset = top.xOffset;
976
const int topY = top.y;
977
if (y < topY || y >= topY + top.height)
987
const int topX = top.x;
996
const int sumX = topX + top.width;
1005
const int bpp = mSurface->format->BytesPerPixel;
1007
SDL_LockSurface(mSurface);
1009
uint8_t *p = static_cast<uint8_t*>(mSurface->pixels)
1010
+ y * mSurface->pitch + x1 * bpp;
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));
1019
for (; x1 <= x2; ++x1)
1020
*(p++) = static_cast<uint8_t>(pixel);
1025
uint16_t* q = reinterpret_cast<uint16_t*>(p);
1026
for (; x1 <= x2; ++x1)
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)
1045
for (; x1 <= x2; ++x1)
1058
uint32_t *q = reinterpret_cast<uint32_t*>(p);
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)
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);
1078
for (; x1 <= x2; ++x1)
1087
SDL_UnlockSurface(mSurface);
1090
void SDL2SoftwareGraphics::drawVLine(int x, int y1, int y2)
1092
if (mClipStack.empty())
1095
const gcn::ClipRectangle& top = mClipStack.top();
1097
const int yOffset = top.yOffset;
1102
if (x < top.x || x >= top.x + top.width)
1120
const int sumY = top.y + top.height;
1129
const int bpp = mSurface->format->BytesPerPixel;
1131
SDL_LockSurface(mSurface);
1133
uint8_t *p = static_cast<uint8_t*>(mSurface->pixels)
1134
+ y1 * mSurface->pitch + x * bpp;
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));
1141
const int pitch = mSurface->pitch;
1145
for (; y1 <= y2; ++y1)
1147
*p = static_cast<uint8_t>(pixel);
1153
for (; y1 <= y2; ++ y1)
1155
*reinterpret_cast<uint16_t*>(p)
1156
= static_cast<uint16_t>(pixel);
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)
1175
for (; y1 <= y2; ++y1)
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)
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);
1209
for (; y1 <= y2; ++y1)
1211
*reinterpret_cast<uint32_t*>(p) = pixel;
1222
SDL_UnlockSurface(mSurface);
1225
void SDL2SoftwareGraphics::drawRectangle(const gcn::Rectangle &rectangle)
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;
1232
drawHLine(x1, y1, x2);
1233
drawHLine(x1, y2, x2);
1235
drawVLine(x1, y1, y2);
1236
drawVLine(x2, y1, y2);
1239
void SDL2SoftwareGraphics::drawLine(int x1, int y1, int x2, int y2)
1243
drawVLine(x1, y1, y2);
1248
drawHLine(x1, y1, x2);
1253
bool SDL2SoftwareGraphics::setVideoMode(const int w, const int h,
1254
const int bpp, const bool fs,
1255
const bool hwaccel, const bool resize,
1258
setMainFlags(w, h, bpp, fs, hwaccel, resize, noFrame);
1260
if (!(mWindow = graphicsManager.createWindow(w, h, bpp,
1261
getSoftwareFlags())))
1269
mSurface = SDL_GetWindowSurface(mWindow);
1270
imageHelper->dumpSurfaceFormat(mSurface);
1271
SDL2SoftwareImageHelper::setFormat(mSurface->format);
1275
SDL_GetWindowSize(mWindow, &w1, &h1);
1279
mRenderer = graphicsManager.createRenderer(mWindow, mRendererFlags);
1283
bool SDL2SoftwareGraphics::resizeScreen(const int width, const int height)
1285
const bool ret = Graphics::resizeScreen(width, height);
1287
mSurface = SDL_GetWindowSurface(mWindow);
1288
SDL2SoftwareImageHelper::setFormat(mSurface->format);