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/sdlgraphics.h"
29
#include "configuration.h"
30
#include "graphicsmanager.h"
31
#include "graphicsvertexes.h"
34
#include "resources/imagehelper.h"
36
#include "utils/sdlcheckutils.h"
38
#include <guichan/sdl/sdlpixel.hpp>
42
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
43
static unsigned int *cR = nullptr;
44
static unsigned int *cG = nullptr;
45
static unsigned int *cB = nullptr;
48
SDLGraphics::SDLGraphics() :
53
mOpenGL = RENDER_SOFTWARE;
57
SDLGraphics::~SDLGraphics()
61
bool SDLGraphics::drawRescaledImage(const Image *const image,
64
const int width, const int height,
65
const int desiredWidth,
66
const int desiredHeight,
67
const bool useColor A_UNUSED)
69
FUNC_BLOCK("Graphics::drawRescaledImage", 1)
70
// Check that preconditions for blitting are met.
71
if (!mWindow || !image)
73
if (!image->mSDLSurface)
76
Image *const tmpImage = image->SDLgetScaledImage(
77
desiredWidth, desiredHeight);
81
if (!tmpImage->mSDLSurface)
84
const gcn::ClipRectangle &top = mClipStack.top();
85
const SDL_Rect &bounds = image->mBounds;
89
static_cast<int16_t>(srcX + bounds.x),
90
static_cast<int16_t>(srcY + bounds.y),
91
static_cast<uint16_t>(width),
92
static_cast<uint16_t>(height)
97
static_cast<int16_t>(dstX + top.xOffset),
98
static_cast<int16_t>(dstY + top.yOffset),
103
const bool returnValue = !(SDL_BlitSurface(tmpImage->mSDLSurface,
104
&srcRect, mWindow, &dstRect) < 0);
111
bool SDLGraphics::drawImage2(const Image *const image, int srcX, int srcY,
112
int dstX, int dstY, const int width,
113
const int height, const bool useColor A_UNUSED)
115
FUNC_BLOCK("Graphics::drawImage2", 1)
116
// Check that preconditions for blitting are met.
117
if (!mWindow || !image || !image->mSDLSurface)
120
const gcn::ClipRectangle &top = mClipStack.top();
121
const SDL_Rect &bounds = image->mBounds;
124
SDL_Surface *const src = image->mSDLSurface;
136
dstX -= static_cast<int16_t>(srcX);
139
const int maxw = src->w - srcX;
146
dstY -= static_cast<int16_t>(srcY);
149
const int maxh = src->h - srcY;
153
const SDL_Rect *const clip = &mWindow->clip_rect;
154
const int clipX = clip->x;
155
const int clipY = clip->y;
156
int dx = clipX - dstX;
160
dstX += static_cast<int16_t>(dx);
163
dx = dstX + w - clipX - clip->w;
167
int dy = clipY - dstY;
171
dstY += static_cast<int16_t>(dy);
174
dy = dstY + h - clipY - clip->h;
182
static_cast<int16_t>(srcX),
183
static_cast<int16_t>(srcY),
184
static_cast<uint16_t>(w),
185
static_cast<uint16_t>(h)
190
static_cast<int16_t>(dstX),
191
static_cast<int16_t>(dstY),
192
static_cast<uint16_t>(w),
193
static_cast<uint16_t>(h)
196
return SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
201
void SDLGraphics::drawImagePattern(const Image *const image,
202
const int x, const int y,
203
const int w, const int h)
205
FUNC_BLOCK("Graphics::drawImagePattern", 1)
206
// Check that preconditions for blitting are met.
207
if (!mWindow || !image)
209
if (!image->mSDLSurface)
212
const SDL_Rect &bounds = image->mBounds;
213
const int iw = bounds.w;
214
const int ih = bounds.h;
215
if (iw == 0 || ih == 0)
218
const gcn::ClipRectangle &top = mClipStack.top();
219
const int xOffset = top.xOffset + x;
220
const int yOffset = top.yOffset + y;
221
const int srcX = bounds.x;
222
const int srcY = bounds.y;
223
SDL_Surface *const src = image->mSDLSurface;
224
const SDL_Rect *const clip = &mWindow->clip_rect;
225
const int clipX = clip->x;
226
const int clipY = clip->y;
228
for (int py = 0; py < h; py += ih)
230
const int dh = (py + ih >= h) ? h - py : ih;
231
int dstY = py + yOffset;
237
dstY -= static_cast<int16_t>(y2);
240
const int maxh = src->h - y2;
244
int dy = clipY - dstY;
248
dstY += static_cast<int16_t>(dy);
251
dy = dstY + h2 - clipY - clip->h;
257
for (int px = 0; px < w; px += iw)
259
const int dw = (px + iw >= w) ? w - px : iw;
260
int dstX = px + xOffset;
266
dstX -= static_cast<int16_t>(x2);
269
const int maxw = src->w - x2;
273
int dx = clipX - dstX;
277
dstX += static_cast<int16_t>(dx);
280
dx = dstX + w2 - clipX - clip->w;
288
static_cast<int16_t>(x2),
289
static_cast<int16_t>(y2),
290
static_cast<uint16_t>(w2),
291
static_cast<uint16_t>(h2)
296
static_cast<int16_t>(dstX),
297
static_cast<int16_t>(dstY),
298
static_cast<uint16_t>(w2),
299
static_cast<uint16_t>(h2)
302
SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
305
// SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
311
void SDLGraphics::drawRescaledImagePattern(const Image *const image,
312
const int x, const int y,
313
const int w, const int h,
314
const int scaledWidth,
315
const int scaledHeight)
317
// Check that preconditions for blitting are met.
318
if (!mWindow || !image)
320
if (!image->mSDLSurface)
323
if (scaledHeight == 0 || scaledWidth == 0)
326
Image *const tmpImage = image->SDLgetScaledImage(
327
scaledWidth, scaledHeight);
331
const SDL_Rect &bounds = tmpImage->mBounds;
332
const int iw = bounds.w;
333
const int ih = bounds.h;
334
if (iw == 0 || ih == 0)
337
const gcn::ClipRectangle &top = mClipStack.top();
338
const int xOffset = top.xOffset + x;
339
const int yOffset = top.yOffset + y;
340
const int srcX = bounds.x;
341
const int srcY = bounds.y;
343
for (int py = 0; py < h; py += ih) // Y position on pattern plane
345
const int dh = (py + ih >= h) ? h - py : ih;
346
const int dstY = py + yOffset;
348
for (int px = 0; px < w; px += iw) // X position on pattern plane
350
const int dw = (px + iw >= w) ? w - px : iw;
351
const int dstX = px + xOffset;
355
static_cast<int16_t>(srcX),
356
static_cast<int16_t>(srcY),
357
static_cast<uint16_t>(dw),
358
static_cast<uint16_t>(dh)
363
static_cast<int16_t>(dstX),
364
static_cast<int16_t>(dstY),
369
SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect,
377
void SDLGraphics::calcImagePattern(ImageVertexes* const vert,
378
const Image *const image,
379
const int x, const int y,
380
const int w, const int h) const
382
// Check that preconditions for blitting are met.
383
if (!vert || !mWindow || !image || !image->mSDLSurface)
386
const SDL_Rect &bounds = image->mBounds;
387
const int iw = bounds.w;
388
const int ih = bounds.h;
389
if (iw == 0 || ih == 0)
392
const gcn::ClipRectangle &top = mClipStack.top();
393
const int xOffset = top.xOffset + x;
394
const int yOffset = top.yOffset + y;
395
const int srcX = bounds.x;
396
const int srcY = bounds.y;
398
for (int py = 0; py < h; py += ih) // Y position on pattern plane
400
const int dh = (py + ih >= h) ? h - py : ih;
401
const int dstY = py + yOffset;
403
for (int px = 0; px < w; px += iw) // X position on pattern plane
405
const int dw = (px + iw >= w) ? w - px : iw;
406
const int dstX = px + xOffset;
408
DoubleRect *const r = new DoubleRect();
409
SDL_Rect &srcRect = r->src;
410
srcRect.x = static_cast<int16_t>(srcX);
411
srcRect.y = static_cast<int16_t>(srcY);
412
srcRect.w = static_cast<uint16_t>(dw);
413
srcRect.h = static_cast<uint16_t>(dh);
414
SDL_Rect &dstRect = r->dst;
415
dstRect.x = static_cast<int16_t>(dstX);
416
dstRect.y = static_cast<int16_t>(dstY);
418
if (SDL_FakeUpperBlit(image->mSDLSurface, &srcRect,
419
mWindow, &dstRect) == 1)
421
vert->sdl.push_back(r);
431
void SDLGraphics::calcImagePattern(ImageCollection* const vertCol,
432
const Image *const image,
433
const int x, const int y,
434
const int w, const int h) const
436
ImageVertexes *vert = nullptr;
437
if (vertCol->currentImage != image)
439
vert = new ImageVertexes();
440
vertCol->currentImage = image;
441
vertCol->currentVert = vert;
443
vertCol->draws.push_back(vert);
447
vert = vertCol->currentVert;
450
calcImagePattern(vert, image, x, y, w, h);
453
void SDLGraphics::calcTile(ImageVertexes *const vert,
454
const Image *const image,
458
calcTileSDL(vert, x, y);
461
void SDLGraphics::calcTileSDL(ImageVertexes *const vert, int x, int y) const
463
// Check that preconditions for blitting are met.
464
if (!vert || !vert->image || !vert->image->mSDLSurface)
467
const Image *const image = vert->image;
468
const gcn::ClipRectangle &top = mClipStack.top();
469
const SDL_Rect &bounds = image->mBounds;
471
DoubleRect *rect = new DoubleRect();
472
rect->src.x = static_cast<int16_t>(bounds.x);
473
rect->src.y = static_cast<int16_t>(bounds.y);
474
rect->src.w = static_cast<uint16_t>(bounds.w);
475
rect->src.h = static_cast<uint16_t>(bounds.h);
476
rect->dst.x = static_cast<int16_t>(x + top.xOffset);
477
rect->dst.y = static_cast<int16_t>(y + top.yOffset);
478
if (SDL_FakeUpperBlit(image->mSDLSurface, &rect->src,
479
mWindow, &rect->dst) == 1)
481
vert->sdl.push_back(rect);
489
void SDLGraphics::calcTile(ImageCollection *const vertCol,
490
const Image *const image,
493
if (vertCol->currentImage != image)
495
ImageVertexes *const vert = new ImageVertexes();
496
vertCol->currentImage = image;
497
vertCol->currentVert = vert;
499
vertCol->draws.push_back(vert);
500
calcTileSDL(vert, x, y);
504
calcTileSDL(vertCol->currentVert, x, y);
508
void SDLGraphics::drawTile(const ImageCollection *const vertCol)
510
const ImageVertexesVector &draws = vertCol->draws;
511
const ImageCollectionCIter it_end = draws.end();
512
for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
514
const ImageVertexes *const vert = *it;
515
const Image *const img = vert->image;
516
const DoubleRects *const rects = &vert->sdl;
517
DoubleRects::const_iterator it2 = rects->begin();
518
const DoubleRects::const_iterator it2_end = rects->end();
519
while (it2 != it2_end)
521
SDL_LowerBlit(img->mSDLSurface, &(*it2)->src,
522
mWindow, &(*it2)->dst);
528
void SDLGraphics::drawTile(const ImageVertexes *const vert)
530
// vert and img must be != 0
531
const Image *const img = vert->image;
532
const DoubleRects *const rects = &vert->sdl;
533
DoubleRects::const_iterator it = rects->begin();
534
const DoubleRects::const_iterator it_end = rects->end();
537
SDL_LowerBlit(img->mSDLSurface, &(*it)->src, mWindow, &(*it)->dst);
542
void SDLGraphics::updateScreen()
544
BLOCK_START("Graphics::updateScreen")
551
SDL_UpdateRects(mWindow, 1, &mRect);
552
// SDL_UpdateRect(mWindow, 0, 0, 0, 0);
554
BLOCK_END("Graphics::updateScreen")
557
SDL_Surface *SDLGraphics::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(mWindow, nullptr, screenshot, nullptr);
579
bool SDLGraphics::drawNet(const int x1, const int y1,
580
const int x2, const int y2,
581
const int width, const int height)
583
for (int y = y1; y < y2; y += height)
584
drawLine(x1, y, x2, y);
586
for (int x = x1; x < x2; x += width)
587
drawLine(x, y1, x, y2);
592
bool SDLGraphics::calcWindow(ImageCollection *const vertCol,
593
const int x, const int y,
594
const int w, const int h,
595
const ImageRect &imgRect)
597
ImageVertexes *vert = nullptr;
598
Image *const image = imgRect.grid[4];
599
if (vertCol->currentImage != image)
601
vert = new ImageVertexes();
602
vertCol->currentImage = image;
603
vertCol->currentVert = vert;
605
vertCol->draws.push_back(vert);
609
vert = vertCol->currentVert;
612
const Image *const *const grid = &imgRect.grid[0];
613
return calcImageRect(vert, x, y, w, h,
614
grid[0], grid[2], grid[6], grid[8],
615
grid[1], grid[5], grid[7], grid[3],
619
int SDLGraphics::SDL_FakeUpperBlit(const SDL_Surface *const src,
620
SDL_Rect *const srcrect,
621
const SDL_Surface *const dst,
622
SDL_Rect *dstrect) const
624
int srcx, srcy, w, h;
626
// Make sure the surfaces aren't locked
630
if (!srcrect || !dstrect)
638
dstrect->x -= static_cast<int16_t>(srcx);
641
int maxw = src->w - srcx;
650
dstrect->y -= static_cast<int16_t>(srcy);
653
int maxh = src->h - srcy;
657
const SDL_Rect *const clip = &dst->clip_rect;
658
const int clipX = clip->x;
659
const int clipY = clip->y;
660
int dx = clipX - dstrect->x;
664
dstrect->x += static_cast<int16_t>(dx);
667
dx = dstrect->x + w - clipX - clip->w;
671
int dy = clipY - dstrect->y;
675
dstrect->y += static_cast<int16_t>(dy);
678
dy = dstrect->y + h - clipY - clip->h;
686
srcrect->x = static_cast<int16_t>(srcx);
687
srcrect->y = static_cast<int16_t>(srcy);
688
srcrect->w = static_cast<int16_t>(w);
689
srcrect->h = static_cast<int16_t>(h);
691
dstrect->w = static_cast<int16_t>(w);
692
dstrect->h = static_cast<int16_t>(h);
695
// return SDL_LowerBlit(src, &sr, dst, dstrect);
697
dstrect->w = dstrect->h = 0;
701
void SDLGraphics::fillRectangle(const gcn::Rectangle& rectangle)
703
FUNC_BLOCK("Graphics::fillRectangle", 1)
704
if (mClipStack.empty())
707
const gcn::ClipRectangle& top = mClipStack.top();
709
gcn::Rectangle area = rectangle;
710
area.x += top.xOffset;
711
area.y += top.yOffset;
713
if (!area.isIntersecting(top))
718
const int x1 = area.x > top.x ? area.x : top.x;
719
const int y1 = area.y > top.y ? area.y : top.y;
720
const int x2 = area.x + area.width < top.x + top.width ?
721
area.x + area.width : top.x + top.width;
722
const int y2 = area.y + area.height < top.y + top.height ?
723
area.y + area.height : top.y + top.height;
726
SDL_LockSurface(mWindow);
728
const int bpp = mWindow->format->BytesPerPixel;
729
const uint32_t pixel = SDL_MapRGB(mWindow->format,
730
static_cast<uint8_t>(mColor.r), static_cast<uint8_t>(mColor.g),
731
static_cast<uint8_t>(mColor.b));
736
for (y = y1; y < y2; y++)
738
uint8_t *const p = static_cast<uint8_t *>(mWindow->pixels)
739
+ y * mWindow->pitch;
740
for (x = x1; x < x2; x++)
741
*(p + x) = static_cast<uint8_t>(pixel);
745
for (y = y1; y < y2; y++)
747
uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
748
+ y * mWindow->pitch;
749
for (x = x1; x < x2; x++)
751
uint8_t *const p = p0 + x * 2;
752
*reinterpret_cast<uint16_t *>(p) = gcn::SDLAlpha16(
753
static_cast<uint16_t>(pixel),
754
*reinterpret_cast<uint16_t *>(p),
755
static_cast<uint8_t>(mColor.a), mWindow->format);
761
const int ca = 255 - mColor.a;
762
const int cr = mColor.r * mColor.a;
763
const int cg = mColor.g * mColor.a;
764
const int cb = mColor.b * mColor.a;
766
for (y = y1; y < y2; y++)
768
uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
769
+ y * mWindow->pitch;
770
for (x = x1; x < x2; x++)
772
uint8_t *const p = p0 + x * 3;
773
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
774
p[2] = static_cast<uint8_t>((p[2] * ca + cb) >> 8);
775
p[1] = static_cast<uint8_t>((p[1] * ca + cg) >> 8);
776
p[0] = static_cast<uint8_t>((p[0] * ca + cr) >> 8);
778
p[0] = static_cast<uint8_t>((p[0] * ca + cb) >> 8);
779
p[1] = static_cast<uint8_t>((p[1] * ca + cg) >> 8);
780
p[2] = static_cast<uint8_t>((p[2] * ca + cr) >> 8);
788
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
789
const unsigned pb = (pixel & 0xff) * mColor.a;
790
const unsigned pg = (pixel & 0xff00) * mColor.a;
791
const unsigned pr = (pixel & 0xff0000) * mColor.a;
792
const unsigned a1 = (255 - mColor.a);
794
for (y = y1; y < y2; y++)
796
uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
797
+ y * mWindow->pitch;
798
for (x = x1; x < x2; x++)
800
uint8_t *p = p0 + x * 4;
801
uint32_t dst = *reinterpret_cast<uint32_t *>(p);
802
const unsigned int b = (pb + (dst & 0xff) * a1) >> 8;
803
const unsigned int g = (pg + (dst & 0xff00) * a1) >> 8;
804
const unsigned int r = (pr
805
+ (dst & 0xff0000) * a1) >> 8;
807
*reinterpret_cast<uint32_t *>(p) = ((b & 0xff)
808
| (g & 0xff00) | (r & 0xff0000));
814
cR = new unsigned int[0x100];
815
cG = new unsigned int[0x100];
816
cB = new unsigned int[0x100];
818
mOldAlpha = mColor.a;
821
const SDL_PixelFormat * const format = mWindow->format;
822
const unsigned rMask = format->Rmask;
823
const unsigned gMask = format->Gmask;
824
const unsigned bMask = format->Bmask;
825
// const unsigned aMask = format->Amask;
826
unsigned rShift = rMask / 0xff;
827
unsigned gShift = gMask / 0xff;
828
unsigned bShift = bMask / 0xff;
835
if (pixel != mOldPixel || mColor.a != mOldAlpha)
837
const unsigned pb = (pixel & bMask) * mColor.a;
838
const unsigned pg = (pixel & gMask) * mColor.a;
839
const unsigned pr = (pixel & rMask) * mColor.a;
840
const unsigned a0 = (255 - mColor.a);
842
const unsigned int a1 = a0 * bShift;
843
const unsigned int a2 = a0 * gShift;
844
const unsigned int a3 = a0 * rShift;
846
for (int f = 0; f <= 0xff; f ++)
848
cB[f] = ((pb + f * a1) >> 8) & bMask;
849
cG[f] = ((pg + f * a2) >> 8) & gMask;
850
cR[f] = ((pr + f * a3) >> 8) & rMask;
854
mOldAlpha = mColor.a;
857
for (y = y1; y < y2; y++)
859
uint32_t *const p0 = reinterpret_cast<uint32_t*>(
860
static_cast<uint8_t*>(mWindow->pixels)
861
+ y * mWindow->pitch);
862
for (x = x1; x < x2; x++)
864
uint32_t *const p = p0 + x;
865
const uint32_t dst = *p;
866
*p = cB[dst & bMask / bShift]
867
| cG[(dst & gMask) / gShift]
868
| cR[(dst & rMask) / rShift];
878
SDL_UnlockSurface(mWindow);
884
static_cast<int16_t>(area.x),
885
static_cast<int16_t>(area.y),
886
static_cast<uint16_t>(area.width),
887
static_cast<uint16_t>(area.height)
890
const uint32_t color = SDL_MapRGBA(mWindow->format,
891
static_cast<int8_t>(mColor.r),
892
static_cast<int8_t>(mColor.g),
893
static_cast<int8_t>(mColor.b),
894
static_cast<int8_t>(mColor.a));
895
SDL_FillRect(mWindow, &rect, color);
899
void SDLGraphics::_beginDraw()
901
pushClipArea(gcn::Rectangle(0, 0, mRect.w, mRect.h));
904
void SDLGraphics::_endDraw()
909
bool SDLGraphics::pushClipArea(gcn::Rectangle area)
911
const bool result = gcn::Graphics::pushClipArea(area);
912
const gcn::ClipRectangle &carea = mClipStack.top();
913
const SDL_Rect rect =
915
static_cast<int16_t>(carea.x),
916
static_cast<int16_t>(carea.y),
917
static_cast<uint16_t>(carea.width),
918
static_cast<uint16_t>(carea.height)
920
SDL_SetClipRect(mWindow, &rect);
925
void SDLGraphics::popClipArea()
927
gcn::Graphics::popClipArea();
929
if (mClipStack.empty())
932
const gcn::ClipRectangle &carea = mClipStack.top();
933
const SDL_Rect rect =
935
static_cast<int16_t>(carea.x),
936
static_cast<int16_t>(carea.y),
937
static_cast<uint16_t>(carea.width),
938
static_cast<uint16_t>(carea.height)
941
SDL_SetClipRect(mWindow, &rect);
944
void SDLGraphics::drawPoint(int x, int y)
946
if (mClipStack.empty())
949
const gcn::ClipRectangle& top = mClipStack.top();
954
if (!top.isPointInRect(x, y))
958
SDLputPixelAlpha(mWindow, x, y, mColor);
960
SDLputPixel(mWindow, x, y, mColor);
963
void SDLGraphics::drawHLine(int x1, int y, int x2)
965
if (mClipStack.empty())
968
const gcn::ClipRectangle& top = mClipStack.top();
970
const int xOffset = top.xOffset;
975
const int topY = top.y;
976
if (y < topY || y >= topY + top.height)
986
const int topX = top.x;
995
const int sumX = topX + top.width;
1004
const int bpp = mWindow->format->BytesPerPixel;
1006
SDL_LockSurface(mWindow);
1008
uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1009
+ y * mWindow->pitch + x1 * bpp;
1011
const uint32_t pixel = SDL_MapRGB(mWindow->format,
1012
static_cast<uint8_t>(mColor.r),
1013
static_cast<uint8_t>(mColor.g),
1014
static_cast<uint8_t>(mColor.b));
1018
for (; x1 <= x2; ++x1)
1019
*(p++) = static_cast<uint8_t>(pixel);
1024
uint16_t* q = reinterpret_cast<uint16_t*>(p);
1025
for (; x1 <= x2; ++x1)
1032
const uint8_t b0 = static_cast<uint8_t>((pixel >> 16) & 0xff);
1033
const uint8_t b1 = static_cast<uint8_t>((pixel >> 8) & 0xff);
1034
const uint8_t b2 = static_cast<uint8_t>(pixel & 0xff);
1035
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
1036
for (; x1 <= x2; ++x1)
1044
for (; x1 <= x2; ++x1)
1057
uint32_t *q = reinterpret_cast<uint32_t*>(p);
1060
unsigned char a = static_cast<unsigned char>(mColor.a);
1061
unsigned char a1 = 255 - a;
1062
const int b0 = (pixel & 0xff) * a;
1063
const int g0 = (pixel & 0xff00) * a;
1064
const int r0 = (pixel & 0xff0000) * a;
1065
for (; x1 <= x2; ++x1)
1067
const unsigned int b = (b0 + (*q & 0xff) * a1) >> 8;
1068
const unsigned int g = (g0 + (*q & 0xff00) * a1) >> 8;
1069
const unsigned int r = (r0 + (*q & 0xff0000) * a1) >> 8;
1070
*q = (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1077
for (; x1 <= x2; ++x1)
1086
SDL_UnlockSurface(mWindow);
1089
void SDLGraphics::drawVLine(int x, int y1, int y2)
1091
if (mClipStack.empty())
1094
const gcn::ClipRectangle& top = mClipStack.top();
1096
const int yOffset = top.yOffset;
1101
if (x < top.x || x >= top.x + top.width)
1119
const int sumY = top.y + top.height;
1128
const int bpp = mWindow->format->BytesPerPixel;
1130
SDL_LockSurface(mWindow);
1132
uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1133
+ y1 * mWindow->pitch + x * bpp;
1135
const uint32_t pixel = SDL_MapRGB(mWindow->format,
1136
static_cast<uint8_t>(mColor.r),
1137
static_cast<uint8_t>(mColor.g),
1138
static_cast<uint8_t>(mColor.b));
1140
const int pitch = mWindow->pitch;
1144
for (; y1 <= y2; ++y1)
1146
*p = static_cast<uint8_t>(pixel);
1152
for (; y1 <= y2; ++ y1)
1154
*reinterpret_cast<uint16_t*>(p)
1155
= static_cast<uint16_t>(pixel);
1162
const uint8_t b0 = static_cast<uint8_t>((pixel >> 16) & 0xff);
1163
const uint8_t b1 = static_cast<uint8_t>((pixel >> 8) & 0xff);
1164
const uint8_t b2 = static_cast<uint8_t>(pixel & 0xff);
1165
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
1166
for (; y1 <= y2; ++y1)
1174
for (; y1 <= y2; ++y1)
1189
unsigned char a = static_cast<unsigned char>(mColor.a);
1190
unsigned char a1 = 255 - a;
1191
const int b0 = (pixel & 0xff) * a;
1192
const int g0 = (pixel & 0xff00) * a;
1193
const int r0 = (pixel & 0xff0000) * a;
1194
for (; y1 <= y2; ++y1)
1196
const unsigned int dst = *reinterpret_cast<uint32_t*>(p);
1197
const unsigned int b = (b0 + (dst & 0xff) * a1) >> 8;
1198
const unsigned int g = (g0 + (dst & 0xff00) * a1) >> 8;
1199
const unsigned int r = (r0 + (dst & 0xff0000) * a1) >> 8;
1200
*reinterpret_cast<uint32_t*>(p) =
1201
(b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1208
for (; y1 <= y2; ++y1)
1210
*reinterpret_cast<uint32_t*>(p) = pixel;
1221
SDL_UnlockSurface(mWindow);
1224
void SDLGraphics::drawRectangle(const gcn::Rectangle &rectangle)
1226
const int x1 = rectangle.x;
1227
const int x2 = x1 + rectangle.width - 1;
1228
const int y1 = rectangle.y;
1229
const int y2 = y1 + rectangle.height - 1;
1231
drawHLine(x1, y1, x2);
1232
drawHLine(x1, y2, x2);
1234
drawVLine(x1, y1, y2);
1235
drawVLine(x2, y1, y2);
1238
void SDLGraphics::drawLine(int x1, int y1, int x2, int y2)
1242
drawVLine(x1, y1, y2);
1247
drawHLine(x1, y1, x2);
1251
// other cases not implimented
1254
bool SDLGraphics::setVideoMode(const int w, const int h, const int bpp,
1255
const bool fs, const bool hwaccel,
1256
const bool resize, const bool noFrame)
1258
setMainFlags(w, h, bpp, fs, hwaccel, resize, noFrame);
1260
if (!(mWindow = graphicsManager.createWindow(w, h, bpp,
1261
getSoftwareFlags())))
1268
mRect.w = static_cast<uint16_t>(mWindow->w);
1269
mRect.h = static_cast<uint16_t>(mWindow->h);