slouken@2256
|
1 |
/*
|
slouken@5535
|
2 |
Simple DirectMedia Layer
|
slouken@6138
|
3 |
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
|
slouken@2256
|
4 |
|
slouken@5535
|
5 |
This software is provided 'as-is', without any express or implied
|
slouken@5535
|
6 |
warranty. In no event will the authors be held liable for any damages
|
slouken@5535
|
7 |
arising from the use of this software.
|
slouken@2256
|
8 |
|
slouken@5535
|
9 |
Permission is granted to anyone to use this software for any purpose,
|
slouken@5535
|
10 |
including commercial applications, and to alter it and redistribute it
|
slouken@5535
|
11 |
freely, subject to the following restrictions:
|
slouken@2256
|
12 |
|
slouken@5535
|
13 |
1. The origin of this software must not be misrepresented; you must not
|
slouken@5535
|
14 |
claim that you wrote the original software. If you use this software
|
slouken@5535
|
15 |
in a product, an acknowledgment in the product documentation would be
|
slouken@5535
|
16 |
appreciated but is not required.
|
slouken@5535
|
17 |
2. Altered source versions must be plainly marked as such, and must not be
|
slouken@5535
|
18 |
misrepresented as being the original software.
|
slouken@5535
|
19 |
3. This notice may not be removed or altered from any source distribution.
|
slouken@2256
|
20 |
*/
|
slouken@2256
|
21 |
#include "SDL_config.h"
|
slouken@2256
|
22 |
|
slouken@2256
|
23 |
#include "SDL_video.h"
|
slouken@2256
|
24 |
#include "SDL_blit.h"
|
slouken@4472
|
25 |
#include "SDL_blit_slow.h"
|
slouken@2256
|
26 |
|
slouken@2256
|
27 |
/* The ONE TRUE BLITTER
|
slouken@2256
|
28 |
* This puppy has to handle all the unoptimized cases - yes, it's slow.
|
slouken@2256
|
29 |
*/
|
slouken@2824
|
30 |
void
|
slouken@2824
|
31 |
SDL_Blit_Slow(SDL_BlitInfo * info)
|
slouken@2824
|
32 |
{
|
slouken@2824
|
33 |
const int flags = info->flags;
|
slouken@2824
|
34 |
const Uint32 modulateR = info->r;
|
slouken@2824
|
35 |
const Uint32 modulateG = info->g;
|
slouken@2824
|
36 |
const Uint32 modulateB = info->b;
|
slouken@2824
|
37 |
const Uint32 modulateA = info->a;
|
slouken@2824
|
38 |
Uint32 srcpixel;
|
slouken@2824
|
39 |
Uint32 srcR, srcG, srcB, srcA;
|
slouken@2824
|
40 |
Uint32 dstpixel;
|
slouken@2824
|
41 |
Uint32 dstR, dstG, dstB, dstA;
|
slouken@2824
|
42 |
int srcy, srcx;
|
slouken@2824
|
43 |
int posy, posx;
|
slouken@2824
|
44 |
int incy, incx;
|
slouken@2824
|
45 |
SDL_PixelFormat *src_fmt = info->src_fmt;
|
slouken@2824
|
46 |
SDL_PixelFormat *dst_fmt = info->dst_fmt;
|
slouken@2824
|
47 |
int srcbpp = src_fmt->BytesPerPixel;
|
slouken@2824
|
48 |
int dstbpp = dst_fmt->BytesPerPixel;
|
slouken@2824
|
49 |
|
slouken@2824
|
50 |
srcy = 0;
|
slouken@2824
|
51 |
posy = 0;
|
slouken@2824
|
52 |
incy = (info->src_h << 16) / info->dst_h;
|
slouken@2824
|
53 |
incx = (info->src_w << 16) / info->dst_w;
|
slouken@2824
|
54 |
|
slouken@2824
|
55 |
while (info->dst_h--) {
|
slouken@5426
|
56 |
Uint8 *src = 0;
|
slouken@2824
|
57 |
Uint8 *dst = (Uint8 *) info->dst;
|
slouken@2824
|
58 |
int n = info->dst_w;
|
slouken@2824
|
59 |
srcx = -1;
|
slouken@2824
|
60 |
posx = 0x10000L;
|
slouken@2824
|
61 |
while (posy >= 0x10000L) {
|
slouken@2824
|
62 |
++srcy;
|
slouken@2824
|
63 |
posy -= 0x10000L;
|
slouken@2824
|
64 |
}
|
slouken@2824
|
65 |
while (n--) {
|
slouken@2824
|
66 |
if (posx >= 0x10000L) {
|
slouken@2824
|
67 |
while (posx >= 0x10000L) {
|
slouken@2824
|
68 |
++srcx;
|
slouken@2824
|
69 |
posx -= 0x10000L;
|
slouken@2824
|
70 |
}
|
slouken@2824
|
71 |
src =
|
slouken@2824
|
72 |
(info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
slouken@2824
|
73 |
}
|
slouken@2824
|
74 |
if (src_fmt->Amask) {
|
slouken@2824
|
75 |
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
slouken@2824
|
76 |
srcB, srcA);
|
slouken@2824
|
77 |
} else {
|
slouken@2824
|
78 |
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
slouken@2824
|
79 |
srcB);
|
slouken@2824
|
80 |
srcA = 0xFF;
|
slouken@2824
|
81 |
}
|
slouken@2824
|
82 |
if (flags & SDL_COPY_COLORKEY) {
|
slouken@2824
|
83 |
/* srcpixel isn't set for 24 bpp */
|
slouken@3588
|
84 |
if (srcbpp == 3) {
|
slouken@2824
|
85 |
srcpixel = (srcR << src_fmt->Rshift) |
|
slouken@2824
|
86 |
(srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
|
slouken@2824
|
87 |
}
|
slouken@2824
|
88 |
if (srcpixel == info->colorkey) {
|
slouken@2824
|
89 |
posx += incx;
|
slouken@2824
|
90 |
dst += dstbpp;
|
slouken@2824
|
91 |
continue;
|
slouken@2824
|
92 |
}
|
slouken@2824
|
93 |
}
|
slouken@2824
|
94 |
if (dst_fmt->Amask) {
|
slouken@2824
|
95 |
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
slouken@2824
|
96 |
dstB, dstA);
|
slouken@2824
|
97 |
} else {
|
slouken@2824
|
98 |
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
slouken@2824
|
99 |
dstB);
|
slouken@2824
|
100 |
dstA = 0xFF;
|
slouken@2824
|
101 |
}
|
slouken@2824
|
102 |
|
slouken@2824
|
103 |
if (flags & SDL_COPY_MODULATE_COLOR) {
|
slouken@2824
|
104 |
srcR = (srcR * modulateR) / 255;
|
slouken@2824
|
105 |
srcG = (srcG * modulateG) / 255;
|
slouken@2824
|
106 |
srcB = (srcB * modulateB) / 255;
|
slouken@2824
|
107 |
}
|
slouken@2824
|
108 |
if (flags & SDL_COPY_MODULATE_ALPHA) {
|
slouken@2824
|
109 |
srcA = (srcA * modulateA) / 255;
|
slouken@2824
|
110 |
}
|
slouken@2824
|
111 |
if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
|
slouken@2824
|
112 |
/* This goes away if we ever use premultiplied alpha */
|
slouken@2824
|
113 |
if (srcA < 255) {
|
slouken@2824
|
114 |
srcR = (srcR * srcA) / 255;
|
slouken@2824
|
115 |
srcG = (srcG * srcA) / 255;
|
slouken@2824
|
116 |
srcB = (srcB * srcA) / 255;
|
slouken@2824
|
117 |
}
|
slouken@2824
|
118 |
}
|
slouken@5184
|
119 |
switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
|
slouken@2824
|
120 |
case 0:
|
slouken@2824
|
121 |
dstR = srcR;
|
slouken@2824
|
122 |
dstG = srcG;
|
slouken@2824
|
123 |
dstB = srcB;
|
slouken@2824
|
124 |
dstA = srcA;
|
slouken@2824
|
125 |
break;
|
slouken@2824
|
126 |
case SDL_COPY_BLEND:
|
slouken@2824
|
127 |
dstR = srcR + ((255 - srcA) * dstR) / 255;
|
slouken@2824
|
128 |
dstG = srcG + ((255 - srcA) * dstG) / 255;
|
slouken@2824
|
129 |
dstB = srcB + ((255 - srcA) * dstB) / 255;
|
slouken@2824
|
130 |
break;
|
slouken@2824
|
131 |
case SDL_COPY_ADD:
|
slouken@2824
|
132 |
dstR = srcR + dstR;
|
slouken@2824
|
133 |
if (dstR > 255)
|
slouken@2824
|
134 |
dstR = 255;
|
slouken@2824
|
135 |
dstG = srcG + dstG;
|
slouken@2824
|
136 |
if (dstG > 255)
|
slouken@2824
|
137 |
dstG = 255;
|
slouken@2824
|
138 |
dstB = srcB + dstB;
|
slouken@2824
|
139 |
if (dstB > 255)
|
slouken@2824
|
140 |
dstB = 255;
|
slouken@2824
|
141 |
break;
|
slouken@5184
|
142 |
case SDL_COPY_MOD:
|
slouken@5184
|
143 |
dstR = (srcR * dstR) / 255;
|
slouken@5184
|
144 |
dstG = (srcG * dstG) / 255;
|
slouken@5184
|
145 |
dstB = (srcB * dstB) / 255;
|
slouken@5184
|
146 |
break;
|
slouken@2824
|
147 |
}
|
slouken@2824
|
148 |
if (dst_fmt->Amask) {
|
slouken@2824
|
149 |
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
|
slouken@2824
|
150 |
} else {
|
slouken@2824
|
151 |
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
|
slouken@2824
|
152 |
}
|
slouken@2824
|
153 |
posx += incx;
|
slouken@2824
|
154 |
dst += dstbpp;
|
slouken@2824
|
155 |
}
|
slouken@2824
|
156 |
posy += incy;
|
slouken@2824
|
157 |
info->dst += info->dst_pitch;
|
slouken@2824
|
158 |
}
|
slouken@2824
|
159 |
}
|
slouken@2256
|
160 |
|
slouken@2256
|
161 |
/* vi: set ts=4 sw=4 expandtab: */
|