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 "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() :
55
SDLGraphics::~SDLGraphics()
59
bool SDLGraphics::drawRescaledImage(const Image *const image,
62
const int width, const int height,
63
const int desiredWidth,
64
const int desiredHeight,
65
const bool useColor A_UNUSED)
67
FUNC_BLOCK("Graphics::drawRescaledImage", 1)
68
// Check that preconditions for blitting are met.
69
if (!mWindow || !image)
71
if (!image->mSDLSurface)
74
Image *const tmpImage = image->SDLgetScaledImage(
75
desiredWidth, desiredHeight);
79
if (!tmpImage->mSDLSurface)
82
const gcn::ClipRectangle &top = mClipStack.top();
83
const SDL_Rect &bounds = image->mBounds;
87
static_cast<int16_t>(srcX + bounds.x),
88
static_cast<int16_t>(srcY + bounds.y),
89
static_cast<uint16_t>(width),
90
static_cast<uint16_t>(height)
95
static_cast<int16_t>(dstX + top.xOffset),
96
static_cast<int16_t>(dstY + top.yOffset),
101
const bool returnValue = !(SDL_BlitSurface(tmpImage->mSDLSurface,
102
&srcRect, mWindow, &dstRect) < 0);
109
bool SDLGraphics::drawImage2(const Image *const image, int srcX, int srcY,
110
int dstX, int dstY, const int width,
111
const int height, const bool useColor A_UNUSED)
113
FUNC_BLOCK("Graphics::drawImage2", 1)
114
// Check that preconditions for blitting are met.
115
if (!mWindow || !image || !image->mSDLSurface)
118
const gcn::ClipRectangle &top = mClipStack.top();
119
const SDL_Rect &bounds = image->mBounds;
122
SDL_Surface *const src = image->mSDLSurface;
134
dstX -= static_cast<int16_t>(srcX);
137
const int maxw = src->w - srcX;
144
dstY -= static_cast<int16_t>(srcY);
147
const int maxh = src->h - srcY;
151
const SDL_Rect *const clip = &mWindow->clip_rect;
152
const int clipX = clip->x;
153
const int clipY = clip->y;
154
int dx = clipX - dstX;
158
dstX += static_cast<int16_t>(dx);
161
dx = dstX + w - clipX - clip->w;
165
int dy = clipY - dstY;
169
dstY += static_cast<int16_t>(dy);
172
dy = dstY + h - clipY - clip->h;
180
static_cast<int16_t>(srcX),
181
static_cast<int16_t>(srcY),
182
static_cast<uint16_t>(w),
183
static_cast<uint16_t>(h)
188
static_cast<int16_t>(dstX),
189
static_cast<int16_t>(dstY),
190
static_cast<uint16_t>(w),
191
static_cast<uint16_t>(h)
194
return SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
199
void SDLGraphics::drawImagePattern(const Image *const image,
200
const int x, const int y,
201
const int w, const int h)
203
FUNC_BLOCK("Graphics::drawImagePattern", 1)
204
// Check that preconditions for blitting are met.
205
if (!mWindow || !image)
207
if (!image->mSDLSurface)
210
const SDL_Rect &bounds = image->mBounds;
211
const int iw = bounds.w;
212
const int ih = bounds.h;
213
if (iw == 0 || ih == 0)
216
const gcn::ClipRectangle &top = mClipStack.top();
217
const int xOffset = top.xOffset + x;
218
const int yOffset = top.yOffset + y;
219
const int srcX = bounds.x;
220
const int srcY = bounds.y;
221
SDL_Surface *const src = image->mSDLSurface;
222
const SDL_Rect *const clip = &mWindow->clip_rect;
223
const int clipX = clip->x;
224
const int clipY = clip->y;
226
for (int py = 0; py < h; py += ih)
228
const int dh = (py + ih >= h) ? h - py : ih;
229
int dstY = py + yOffset;
235
dstY -= static_cast<int16_t>(y2);
238
const int maxh = src->h - y2;
242
int dy = clipY - dstY;
246
dstY += static_cast<int16_t>(dy);
249
dy = dstY + h2 - clipY - clip->h;
255
for (int px = 0; px < w; px += iw)
257
const int dw = (px + iw >= w) ? w - px : iw;
258
int dstX = px + xOffset;
264
dstX -= static_cast<int16_t>(x2);
267
const int maxw = src->w - x2;
271
int dx = clipX - dstX;
275
dstX += static_cast<int16_t>(dx);
278
dx = dstX + w2 - clipX - clip->w;
286
static_cast<int16_t>(x2),
287
static_cast<int16_t>(y2),
288
static_cast<uint16_t>(w2),
289
static_cast<uint16_t>(h2)
294
static_cast<int16_t>(dstX),
295
static_cast<int16_t>(dstY),
296
static_cast<uint16_t>(w2),
297
static_cast<uint16_t>(h2)
300
SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
303
// SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
309
void SDLGraphics::drawRescaledImagePattern(const Image *const image,
310
const int x, const int y,
311
const int w, const int h,
312
const int scaledWidth,
313
const int scaledHeight)
315
// Check that preconditions for blitting are met.
316
if (!mWindow || !image)
318
if (!image->mSDLSurface)
321
if (scaledHeight == 0 || scaledWidth == 0)
324
Image *const tmpImage = image->SDLgetScaledImage(
325
scaledWidth, scaledHeight);
329
const SDL_Rect &bounds = tmpImage->mBounds;
330
const int iw = bounds.w;
331
const int ih = bounds.h;
332
if (iw == 0 || ih == 0)
335
const gcn::ClipRectangle &top = mClipStack.top();
336
const int xOffset = top.xOffset + x;
337
const int yOffset = top.yOffset + y;
338
const int srcX = bounds.x;
339
const int srcY = bounds.y;
341
for (int py = 0; py < h; py += ih) // Y position on pattern plane
343
const int dh = (py + ih >= h) ? h - py : ih;
344
const int dstY = py + yOffset;
346
for (int px = 0; px < w; px += iw) // X position on pattern plane
348
const int dw = (px + iw >= w) ? w - px : iw;
349
const int dstX = px + xOffset;
353
static_cast<int16_t>(srcX),
354
static_cast<int16_t>(srcY),
355
static_cast<uint16_t>(dw),
356
static_cast<uint16_t>(dh)
361
static_cast<int16_t>(dstX),
362
static_cast<int16_t>(dstY),
367
SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect,
375
void SDLGraphics::calcImagePattern(ImageVertexes* const vert,
376
const Image *const image,
377
const int x, const int y,
378
const int w, const int h) const
380
// Check that preconditions for blitting are met.
381
if (!vert || !mWindow || !image || !image->mSDLSurface)
384
const SDL_Rect &bounds = image->mBounds;
385
const int iw = bounds.w;
386
const int ih = bounds.h;
387
if (iw == 0 || ih == 0)
390
const gcn::ClipRectangle &top = mClipStack.top();
391
const int xOffset = top.xOffset + x;
392
const int yOffset = top.yOffset + y;
393
const int srcX = bounds.x;
394
const int srcY = bounds.y;
396
for (int py = 0; py < h; py += ih) // Y position on pattern plane
398
const int dh = (py + ih >= h) ? h - py : ih;
399
const int dstY = py + yOffset;
401
for (int px = 0; px < w; px += iw) // X position on pattern plane
403
const int dw = (px + iw >= w) ? w - px : iw;
404
const int dstX = px + xOffset;
406
DoubleRect *const r = new DoubleRect();
407
SDL_Rect &srcRect = r->src;
408
srcRect.x = static_cast<int16_t>(srcX);
409
srcRect.y = static_cast<int16_t>(srcY);
410
srcRect.w = static_cast<uint16_t>(dw);
411
srcRect.h = static_cast<uint16_t>(dh);
412
SDL_Rect &dstRect = r->dst;
413
dstRect.x = static_cast<int16_t>(dstX);
414
dstRect.y = static_cast<int16_t>(dstY);
416
if (SDL_FakeUpperBlit(image->mSDLSurface, &srcRect,
417
mWindow, &dstRect) == 1)
419
vert->sdl.push_back(r);
429
void SDLGraphics::calcImagePattern(ImageCollection* const vertCol,
430
const Image *const image,
431
const int x, const int y,
432
const int w, const int h) const
434
ImageVertexes *vert = nullptr;
435
if (vertCol->currentImage != image)
437
vert = new ImageVertexes();
438
vertCol->currentImage = image;
439
vertCol->currentVert = vert;
441
vertCol->draws.push_back(vert);
445
vert = vertCol->currentVert;
448
calcImagePattern(vert, image, x, y, w, h);
451
void SDLGraphics::calcTile(ImageVertexes *const vert,
452
const Image *const image,
456
calcTileSDL(vert, x, y);
459
void SDLGraphics::calcTileSDL(ImageVertexes *const vert, int x, int y) const
461
// Check that preconditions for blitting are met.
462
if (!vert || !vert->image || !vert->image->mSDLSurface)
465
const Image *const image = vert->image;
466
const gcn::ClipRectangle &top = mClipStack.top();
467
const SDL_Rect &bounds = image->mBounds;
469
DoubleRect *rect = new DoubleRect();
470
rect->src.x = static_cast<int16_t>(bounds.x);
471
rect->src.y = static_cast<int16_t>(bounds.y);
472
rect->src.w = static_cast<uint16_t>(bounds.w);
473
rect->src.h = static_cast<uint16_t>(bounds.h);
474
rect->dst.x = static_cast<int16_t>(x + top.xOffset);
475
rect->dst.y = static_cast<int16_t>(y + top.yOffset);
476
if (SDL_FakeUpperBlit(image->mSDLSurface, &rect->src,
477
mWindow, &rect->dst) == 1)
479
vert->sdl.push_back(rect);
487
void SDLGraphics::calcTile(ImageCollection *const vertCol,
488
const Image *const image,
491
if (vertCol->currentImage != image)
493
ImageVertexes *const vert = new ImageVertexes();
494
vertCol->currentImage = image;
495
vertCol->currentVert = vert;
497
vertCol->draws.push_back(vert);
498
calcTileSDL(vert, x, y);
502
calcTileSDL(vertCol->currentVert, x, y);
506
void SDLGraphics::drawTile(const ImageCollection *const vertCol)
508
const ImageVertexesVector &draws = vertCol->draws;
509
const ImageCollectionCIter it_end = draws.end();
510
for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
512
const ImageVertexes *const vert = *it;
513
const Image *const img = vert->image;
514
const DoubleRects *const rects = &vert->sdl;
515
DoubleRects::const_iterator it2 = rects->begin();
516
const DoubleRects::const_iterator it2_end = rects->end();
517
while (it2 != it2_end)
519
SDL_LowerBlit(img->mSDLSurface, &(*it2)->src,
520
mWindow, &(*it2)->dst);
526
void SDLGraphics::drawTile(const ImageVertexes *const vert)
528
// vert and img must be != 0
529
const Image *const img = vert->image;
530
const DoubleRects *const rects = &vert->sdl;
531
DoubleRects::const_iterator it = rects->begin();
532
const DoubleRects::const_iterator it_end = rects->end();
535
SDL_LowerBlit(img->mSDLSurface, &(*it)->src, mWindow, &(*it)->dst);
540
void SDLGraphics::updateScreen()
542
BLOCK_START("Graphics::updateScreen")
549
SDL_UpdateRects(mWindow, 1, &mRect);
550
// SDL_UpdateRect(mWindow, 0, 0, 0, 0);
552
BLOCK_END("Graphics::updateScreen")
555
SDL_Surface *SDLGraphics::getScreenshot()
557
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
558
const int rmask = 0xff000000;
559
const int gmask = 0x00ff0000;
560
const int bmask = 0x0000ff00;
562
const int rmask = 0x000000ff;
563
const int gmask = 0x0000ff00;
564
const int bmask = 0x00ff0000;
566
const int amask = 0x00000000;
568
SDL_Surface *const screenshot = MSDL_CreateRGBSurface(SDL_SWSURFACE,
569
mRect.w, mRect.h, 24, rmask, gmask, bmask, amask);
572
SDL_BlitSurface(mWindow, nullptr, screenshot, nullptr);
577
bool SDLGraphics::drawNet(const int x1, const int y1,
578
const int x2, const int y2,
579
const int width, const int height)
581
for (int y = y1; y < y2; y += height)
582
drawLine(x1, y, x2, y);
584
for (int x = x1; x < x2; x += width)
585
drawLine(x, y1, x, y2);
590
bool SDLGraphics::calcWindow(ImageCollection *const vertCol,
591
const int x, const int y,
592
const int w, const int h,
593
const ImageRect &imgRect)
595
ImageVertexes *vert = nullptr;
596
Image *const image = imgRect.grid[4];
597
if (vertCol->currentImage != image)
599
vert = new ImageVertexes();
600
vertCol->currentImage = image;
601
vertCol->currentVert = vert;
603
vertCol->draws.push_back(vert);
607
vert = vertCol->currentVert;
610
const Image *const *const grid = &imgRect.grid[0];
611
return calcImageRect(vert, x, y, w, h,
612
grid[0], grid[2], grid[6], grid[8],
613
grid[1], grid[5], grid[7], grid[3],
617
int SDLGraphics::SDL_FakeUpperBlit(const SDL_Surface *const src,
618
SDL_Rect *const srcrect,
619
const SDL_Surface *const dst,
620
SDL_Rect *dstrect) const
622
int srcx, srcy, w, h;
624
// Make sure the surfaces aren't locked
628
if (!srcrect || !dstrect)
636
dstrect->x -= static_cast<int16_t>(srcx);
639
int maxw = src->w - srcx;
648
dstrect->y -= static_cast<int16_t>(srcy);
651
int maxh = src->h - srcy;
655
const SDL_Rect *const clip = &dst->clip_rect;
656
const int clipX = clip->x;
657
const int clipY = clip->y;
658
int dx = clipX - dstrect->x;
662
dstrect->x += static_cast<int16_t>(dx);
665
dx = dstrect->x + w - clipX - clip->w;
669
int dy = clipY - dstrect->y;
673
dstrect->y += static_cast<int16_t>(dy);
676
dy = dstrect->y + h - clipY - clip->h;
684
srcrect->x = static_cast<int16_t>(srcx);
685
srcrect->y = static_cast<int16_t>(srcy);
686
srcrect->w = static_cast<int16_t>(w);
687
srcrect->h = static_cast<int16_t>(h);
689
dstrect->w = static_cast<int16_t>(w);
690
dstrect->h = static_cast<int16_t>(h);
693
// return SDL_LowerBlit(src, &sr, dst, dstrect);
695
dstrect->w = dstrect->h = 0;
699
void SDLGraphics::fillRectangle(const gcn::Rectangle& rectangle)
701
FUNC_BLOCK("Graphics::fillRectangle", 1)
702
if (mClipStack.empty())
705
const gcn::ClipRectangle& top = mClipStack.top();
707
gcn::Rectangle area = rectangle;
708
area.x += top.xOffset;
709
area.y += top.yOffset;
711
if (!area.isIntersecting(top))
716
const int x1 = area.x > top.x ? area.x : top.x;
717
const int y1 = area.y > top.y ? area.y : top.y;
718
const int x2 = area.x + area.width < top.x + top.width ?
719
area.x + area.width : top.x + top.width;
720
const int y2 = area.y + area.height < top.y + top.height ?
721
area.y + area.height : top.y + top.height;
724
SDL_LockSurface(mWindow);
726
const int bpp = mWindow->format->BytesPerPixel;
727
const uint32_t pixel = SDL_MapRGB(mWindow->format,
728
static_cast<uint8_t>(mColor.r), static_cast<uint8_t>(mColor.g),
729
static_cast<uint8_t>(mColor.b));
734
for (y = y1; y < y2; y++)
736
uint8_t *const p = static_cast<uint8_t *>(mWindow->pixels)
737
+ y * mWindow->pitch;
738
for (x = x1; x < x2; x++)
739
*(p + x) = static_cast<uint8_t>(pixel);
743
for (y = y1; y < y2; y++)
745
uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
746
+ y * mWindow->pitch;
747
for (x = x1; x < x2; x++)
749
uint8_t *const p = p0 + x * 2;
750
*reinterpret_cast<uint16_t *>(p) = gcn::SDLAlpha16(
751
static_cast<uint16_t>(pixel),
752
*reinterpret_cast<uint16_t *>(p),
753
static_cast<uint8_t>(mColor.a), mWindow->format);
759
const int ca = 255 - mColor.a;
760
const int cr = mColor.r * mColor.a;
761
const int cg = mColor.g * mColor.a;
762
const int cb = mColor.b * mColor.a;
764
for (y = y1; y < y2; y++)
766
uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
767
+ y * mWindow->pitch;
768
for (x = x1; x < x2; x++)
770
uint8_t *const p = p0 + x * 3;
771
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
772
p[2] = static_cast<uint8_t>((p[2] * ca + cb) >> 8);
773
p[1] = static_cast<uint8_t>((p[1] * ca + cg) >> 8);
774
p[0] = static_cast<uint8_t>((p[0] * ca + cr) >> 8);
776
p[0] = static_cast<uint8_t>((p[0] * ca + cb) >> 8);
777
p[1] = static_cast<uint8_t>((p[1] * ca + cg) >> 8);
778
p[2] = static_cast<uint8_t>((p[2] * ca + cr) >> 8);
786
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
787
const unsigned pb = (pixel & 0xff) * mColor.a;
788
const unsigned pg = (pixel & 0xff00) * mColor.a;
789
const unsigned pr = (pixel & 0xff0000) * mColor.a;
790
const unsigned a1 = (255 - mColor.a);
792
for (y = y1; y < y2; y++)
794
uint8_t *const p0 = static_cast<uint8_t *>(mWindow->pixels)
795
+ y * mWindow->pitch;
796
for (x = x1; x < x2; x++)
798
uint8_t *p = p0 + x * 4;
799
uint32_t dst = *reinterpret_cast<uint32_t *>(p);
800
const unsigned int b = (pb + (dst & 0xff) * a1) >> 8;
801
const unsigned int g = (pg + (dst & 0xff00) * a1) >> 8;
802
const unsigned int r = (pr
803
+ (dst & 0xff0000) * a1) >> 8;
805
*reinterpret_cast<uint32_t *>(p) = ((b & 0xff)
806
| (g & 0xff00) | (r & 0xff0000));
812
cR = new unsigned int[0x100];
813
cG = new unsigned int[0x100];
814
cB = new unsigned int[0x100];
816
mOldAlpha = mColor.a;
819
const SDL_PixelFormat * const format = mWindow->format;
820
const unsigned rMask = format->Rmask;
821
const unsigned gMask = format->Gmask;
822
const unsigned bMask = format->Bmask;
823
// const unsigned aMask = format->Amask;
824
unsigned rShift = rMask / 0xff;
825
unsigned gShift = gMask / 0xff;
826
unsigned bShift = bMask / 0xff;
833
if (pixel != mOldPixel || mColor.a != mOldAlpha)
835
const unsigned pb = (pixel & bMask) * mColor.a;
836
const unsigned pg = (pixel & gMask) * mColor.a;
837
const unsigned pr = (pixel & rMask) * mColor.a;
838
const unsigned a0 = (255 - mColor.a);
840
const unsigned int a1 = a0 * bShift;
841
const unsigned int a2 = a0 * gShift;
842
const unsigned int a3 = a0 * rShift;
844
for (int f = 0; f <= 0xff; f ++)
846
cB[f] = ((pb + f * a1) >> 8) & bMask;
847
cG[f] = ((pg + f * a2) >> 8) & gMask;
848
cR[f] = ((pr + f * a3) >> 8) & rMask;
852
mOldAlpha = mColor.a;
855
for (y = y1; y < y2; y++)
857
uint32_t *const p0 = reinterpret_cast<uint32_t*>(
858
static_cast<uint8_t*>(mWindow->pixels)
859
+ y * mWindow->pitch);
860
for (x = x1; x < x2; x++)
862
uint32_t *const p = p0 + x;
863
const uint32_t dst = *p;
864
*p = cB[dst & bMask / bShift]
865
| cG[(dst & gMask) / gShift]
866
| cR[(dst & rMask) / rShift];
876
SDL_UnlockSurface(mWindow);
882
static_cast<int16_t>(area.x),
883
static_cast<int16_t>(area.y),
884
static_cast<uint16_t>(area.width),
885
static_cast<uint16_t>(area.height)
888
const uint32_t color = SDL_MapRGBA(mWindow->format,
889
static_cast<int8_t>(mColor.r),
890
static_cast<int8_t>(mColor.g),
891
static_cast<int8_t>(mColor.b),
892
static_cast<int8_t>(mColor.a));
893
SDL_FillRect(mWindow, &rect, color);
897
void SDLGraphics::_beginDraw()
899
pushClipArea(gcn::Rectangle(0, 0, mRect.w, mRect.h));
902
void SDLGraphics::_endDraw()
907
bool SDLGraphics::pushClipArea(gcn::Rectangle area)
909
const bool result = gcn::Graphics::pushClipArea(area);
910
const gcn::ClipRectangle &carea = mClipStack.top();
911
const SDL_Rect rect =
913
static_cast<int16_t>(carea.x),
914
static_cast<int16_t>(carea.y),
915
static_cast<uint16_t>(carea.width),
916
static_cast<uint16_t>(carea.height)
918
SDL_SetClipRect(mWindow, &rect);
923
void SDLGraphics::popClipArea()
925
gcn::Graphics::popClipArea();
927
if (mClipStack.empty())
930
const gcn::ClipRectangle &carea = mClipStack.top();
931
const SDL_Rect rect =
933
static_cast<int16_t>(carea.x),
934
static_cast<int16_t>(carea.y),
935
static_cast<uint16_t>(carea.width),
936
static_cast<uint16_t>(carea.height)
939
SDL_SetClipRect(mWindow, &rect);
942
void SDLGraphics::drawPoint(int x, int y)
944
if (mClipStack.empty())
947
const gcn::ClipRectangle& top = mClipStack.top();
952
if (!top.isPointInRect(x, y))
956
SDLputPixelAlpha(mWindow, x, y, mColor);
958
SDLputPixel(mWindow, x, y, mColor);
961
void SDLGraphics::drawHLine(int x1, int y, int x2)
963
if (mClipStack.empty())
966
const gcn::ClipRectangle& top = mClipStack.top();
968
const int xOffset = top.xOffset;
973
const int topY = top.y;
974
if (y < topY || y >= topY + top.height)
984
const int topX = top.x;
993
const int sumX = topX + top.width;
1002
const int bpp = mWindow->format->BytesPerPixel;
1004
SDL_LockSurface(mWindow);
1006
uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1007
+ y * mWindow->pitch + x1 * bpp;
1009
const uint32_t pixel = SDL_MapRGB(mWindow->format,
1010
static_cast<uint8_t>(mColor.r),
1011
static_cast<uint8_t>(mColor.g),
1012
static_cast<uint8_t>(mColor.b));
1016
for (; x1 <= x2; ++x1)
1017
*(p++) = static_cast<uint8_t>(pixel);
1022
uint16_t* q = reinterpret_cast<uint16_t*>(p);
1023
for (; x1 <= x2; ++x1)
1030
const uint8_t b0 = static_cast<uint8_t>((pixel >> 16) & 0xff);
1031
const uint8_t b1 = static_cast<uint8_t>((pixel >> 8) & 0xff);
1032
const uint8_t b2 = static_cast<uint8_t>(pixel & 0xff);
1033
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
1034
for (; x1 <= x2; ++x1)
1042
for (; x1 <= x2; ++x1)
1055
uint32_t *q = reinterpret_cast<uint32_t*>(p);
1058
unsigned char a = static_cast<unsigned char>(mColor.a);
1059
unsigned char a1 = 255 - a;
1060
const int b0 = (pixel & 0xff) * a;
1061
const int g0 = (pixel & 0xff00) * a;
1062
const int r0 = (pixel & 0xff0000) * a;
1063
for (; x1 <= x2; ++x1)
1065
const unsigned int b = (b0 + (*q & 0xff) * a1) >> 8;
1066
const unsigned int g = (g0 + (*q & 0xff00) * a1) >> 8;
1067
const unsigned int r = (r0 + (*q & 0xff0000) * a1) >> 8;
1068
*q = (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1075
for (; x1 <= x2; ++x1)
1084
SDL_UnlockSurface(mWindow);
1087
void SDLGraphics::drawVLine(int x, int y1, int y2)
1089
if (mClipStack.empty())
1092
const gcn::ClipRectangle& top = mClipStack.top();
1094
const int yOffset = top.yOffset;
1099
if (x < top.x || x >= top.x + top.width)
1117
const int sumY = top.y + top.height;
1126
const int bpp = mWindow->format->BytesPerPixel;
1128
SDL_LockSurface(mWindow);
1130
uint8_t *p = static_cast<uint8_t*>(mWindow->pixels)
1131
+ y1 * mWindow->pitch + x * bpp;
1133
const uint32_t pixel = SDL_MapRGB(mWindow->format,
1134
static_cast<uint8_t>(mColor.r),
1135
static_cast<uint8_t>(mColor.g),
1136
static_cast<uint8_t>(mColor.b));
1138
const int pitch = mWindow->pitch;
1142
for (; y1 <= y2; ++y1)
1144
*p = static_cast<uint8_t>(pixel);
1150
for (; y1 <= y2; ++ y1)
1152
*reinterpret_cast<uint16_t*>(p)
1153
= static_cast<uint16_t>(pixel);
1160
const uint8_t b0 = static_cast<uint8_t>((pixel >> 16) & 0xff);
1161
const uint8_t b1 = static_cast<uint8_t>((pixel >> 8) & 0xff);
1162
const uint8_t b2 = static_cast<uint8_t>(pixel & 0xff);
1163
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
1164
for (; y1 <= y2; ++y1)
1172
for (; y1 <= y2; ++y1)
1187
unsigned char a = static_cast<unsigned char>(mColor.a);
1188
unsigned char a1 = 255 - a;
1189
const int b0 = (pixel & 0xff) * a;
1190
const int g0 = (pixel & 0xff00) * a;
1191
const int r0 = (pixel & 0xff0000) * a;
1192
for (; y1 <= y2; ++y1)
1194
const unsigned int dst = *reinterpret_cast<uint32_t*>(p);
1195
const unsigned int b = (b0 + (dst & 0xff) * a1) >> 8;
1196
const unsigned int g = (g0 + (dst & 0xff00) * a1) >> 8;
1197
const unsigned int r = (r0 + (dst & 0xff0000) * a1) >> 8;
1198
*reinterpret_cast<uint32_t*>(p) =
1199
(b & 0xff) | (g & 0xff00) | (r & 0xff0000);
1206
for (; y1 <= y2; ++y1)
1208
*reinterpret_cast<uint32_t*>(p) = pixel;
1219
SDL_UnlockSurface(mWindow);
1222
void SDLGraphics::drawRectangle(const gcn::Rectangle &rectangle)
1224
const int x1 = rectangle.x;
1225
const int x2 = x1 + rectangle.width - 1;
1226
const int y1 = rectangle.y;
1227
const int y2 = y1 + rectangle.height - 1;
1229
drawHLine(x1, y1, x2);
1230
drawHLine(x1, y2, x2);
1232
drawVLine(x1, y1, y2);
1233
drawVLine(x2, y1, y2);
1236
void SDLGraphics::drawLine(int x1, int y1, int x2, int y2)
1240
drawVLine(x1, y1, y2);
1245
drawHLine(x1, y1, x2);
1249
// other cases not implimented
1252
bool SDLGraphics::setVideoMode(const int w, const int h, const int bpp,
1253
const bool fs, const bool hwaccel,
1254
const bool resize, const bool noFrame)
1256
setMainFlags(w, h, bpp, fs, hwaccel, resize, noFrame);
1258
if (!(mWindow = graphicsManager.createWindow(w, h, bpp,
1259
getSoftwareFlags())))
1266
mRect.w = static_cast<uint16_t>(mWindow->w);
1267
mRect.h = static_cast<uint16_t>(mWindow->h);