SDL_gfx
2.0.25
|
00001 /* 00002 00003 SDL_gfxBlitFunc.c: custom blitters 00004 00005 Copyright (C) 2001-2012 Andreas Schiffler 00006 00007 This software is provided 'as-is', without any express or implied 00008 warranty. In no event will the authors be held liable for any damages 00009 arising from the use of this software. 00010 00011 Permission is granted to anyone to use this software for any purpose, 00012 including commercial applications, and to alter it and redistribute it 00013 freely, subject to the following restrictions: 00014 00015 1. The origin of this software must not be misrepresented; you must not 00016 claim that you wrote the original software. If you use this software 00017 in a product, an acknowledgment in the product documentation would be 00018 appreciated but is not required. 00019 00020 2. Altered source versions must be plainly marked as such, and must not be 00021 misrepresented as being the original software. 00022 00023 3. This notice may not be removed or altered from any source 00024 distribution. 00025 00026 Andreas Schiffler -- aschiffler at ferzkopp dot net 00027 00028 */ 00029 00030 #include "SDL_gfxBlitFunc.h" 00031 00039 const unsigned int GFX_ALPHA_ADJUST_ARRAY[256] = { 00040 0, /* 0 */ 00041 15, /* 1 */ 00042 22, /* 2 */ 00043 27, /* 3 */ 00044 31, /* 4 */ 00045 35, /* 5 */ 00046 39, /* 6 */ 00047 42, /* 7 */ 00048 45, /* 8 */ 00049 47, /* 9 */ 00050 50, /* 10 */ 00051 52, /* 11 */ 00052 55, /* 12 */ 00053 57, /* 13 */ 00054 59, /* 14 */ 00055 61, /* 15 */ 00056 63, /* 16 */ 00057 65, /* 17 */ 00058 67, /* 18 */ 00059 69, /* 19 */ 00060 71, /* 20 */ 00061 73, /* 21 */ 00062 74, /* 22 */ 00063 76, /* 23 */ 00064 78, /* 24 */ 00065 79, /* 25 */ 00066 81, /* 26 */ 00067 82, /* 27 */ 00068 84, /* 28 */ 00069 85, /* 29 */ 00070 87, /* 30 */ 00071 88, /* 31 */ 00072 90, /* 32 */ 00073 91, /* 33 */ 00074 93, /* 34 */ 00075 94, /* 35 */ 00076 95, /* 36 */ 00077 97, /* 37 */ 00078 98, /* 38 */ 00079 99, /* 39 */ 00080 100, /* 40 */ 00081 102, /* 41 */ 00082 103, /* 42 */ 00083 104, /* 43 */ 00084 105, /* 44 */ 00085 107, /* 45 */ 00086 108, /* 46 */ 00087 109, /* 47 */ 00088 110, /* 48 */ 00089 111, /* 49 */ 00090 112, /* 50 */ 00091 114, /* 51 */ 00092 115, /* 52 */ 00093 116, /* 53 */ 00094 117, /* 54 */ 00095 118, /* 55 */ 00096 119, /* 56 */ 00097 120, /* 57 */ 00098 121, /* 58 */ 00099 122, /* 59 */ 00100 123, /* 60 */ 00101 124, /* 61 */ 00102 125, /* 62 */ 00103 126, /* 63 */ 00104 127, /* 64 */ 00105 128, /* 65 */ 00106 129, /* 66 */ 00107 130, /* 67 */ 00108 131, /* 68 */ 00109 132, /* 69 */ 00110 133, /* 70 */ 00111 134, /* 71 */ 00112 135, /* 72 */ 00113 136, /* 73 */ 00114 137, /* 74 */ 00115 138, /* 75 */ 00116 139, /* 76 */ 00117 140, /* 77 */ 00118 141, /* 78 */ 00119 141, /* 79 */ 00120 142, /* 80 */ 00121 143, /* 81 */ 00122 144, /* 82 */ 00123 145, /* 83 */ 00124 146, /* 84 */ 00125 147, /* 85 */ 00126 148, /* 86 */ 00127 148, /* 87 */ 00128 149, /* 88 */ 00129 150, /* 89 */ 00130 151, /* 90 */ 00131 152, /* 91 */ 00132 153, /* 92 */ 00133 153, /* 93 */ 00134 154, /* 94 */ 00135 155, /* 95 */ 00136 156, /* 96 */ 00137 157, /* 97 */ 00138 158, /* 98 */ 00139 158, /* 99 */ 00140 159, /* 100 */ 00141 160, /* 101 */ 00142 161, /* 102 */ 00143 162, /* 103 */ 00144 162, /* 104 */ 00145 163, /* 105 */ 00146 164, /* 106 */ 00147 165, /* 107 */ 00148 165, /* 108 */ 00149 166, /* 109 */ 00150 167, /* 110 */ 00151 168, /* 111 */ 00152 168, /* 112 */ 00153 169, /* 113 */ 00154 170, /* 114 */ 00155 171, /* 115 */ 00156 171, /* 116 */ 00157 172, /* 117 */ 00158 173, /* 118 */ 00159 174, /* 119 */ 00160 174, /* 120 */ 00161 175, /* 121 */ 00162 176, /* 122 */ 00163 177, /* 123 */ 00164 177, /* 124 */ 00165 178, /* 125 */ 00166 179, /* 126 */ 00167 179, /* 127 */ 00168 180, /* 128 */ 00169 181, /* 129 */ 00170 182, /* 130 */ 00171 182, /* 131 */ 00172 183, /* 132 */ 00173 184, /* 133 */ 00174 184, /* 134 */ 00175 185, /* 135 */ 00176 186, /* 136 */ 00177 186, /* 137 */ 00178 187, /* 138 */ 00179 188, /* 139 */ 00180 188, /* 140 */ 00181 189, /* 141 */ 00182 190, /* 142 */ 00183 190, /* 143 */ 00184 191, /* 144 */ 00185 192, /* 145 */ 00186 192, /* 146 */ 00187 193, /* 147 */ 00188 194, /* 148 */ 00189 194, /* 149 */ 00190 195, /* 150 */ 00191 196, /* 151 */ 00192 196, /* 152 */ 00193 197, /* 153 */ 00194 198, /* 154 */ 00195 198, /* 155 */ 00196 199, /* 156 */ 00197 200, /* 157 */ 00198 200, /* 158 */ 00199 201, /* 159 */ 00200 201, /* 160 */ 00201 202, /* 161 */ 00202 203, /* 162 */ 00203 203, /* 163 */ 00204 204, /* 164 */ 00205 205, /* 165 */ 00206 205, /* 166 */ 00207 206, /* 167 */ 00208 206, /* 168 */ 00209 207, /* 169 */ 00210 208, /* 170 */ 00211 208, /* 171 */ 00212 209, /* 172 */ 00213 210, /* 173 */ 00214 210, /* 174 */ 00215 211, /* 175 */ 00216 211, /* 176 */ 00217 212, /* 177 */ 00218 213, /* 178 */ 00219 213, /* 179 */ 00220 214, /* 180 */ 00221 214, /* 181 */ 00222 215, /* 182 */ 00223 216, /* 183 */ 00224 216, /* 184 */ 00225 217, /* 185 */ 00226 217, /* 186 */ 00227 218, /* 187 */ 00228 218, /* 188 */ 00229 219, /* 189 */ 00230 220, /* 190 */ 00231 220, /* 191 */ 00232 221, /* 192 */ 00233 221, /* 193 */ 00234 222, /* 194 */ 00235 222, /* 195 */ 00236 223, /* 196 */ 00237 224, /* 197 */ 00238 224, /* 198 */ 00239 225, /* 199 */ 00240 225, /* 200 */ 00241 226, /* 201 */ 00242 226, /* 202 */ 00243 227, /* 203 */ 00244 228, /* 204 */ 00245 228, /* 205 */ 00246 229, /* 206 */ 00247 229, /* 207 */ 00248 230, /* 208 */ 00249 230, /* 209 */ 00250 231, /* 210 */ 00251 231, /* 211 */ 00252 232, /* 212 */ 00253 233, /* 213 */ 00254 233, /* 214 */ 00255 234, /* 215 */ 00256 234, /* 216 */ 00257 235, /* 217 */ 00258 235, /* 218 */ 00259 236, /* 219 */ 00260 236, /* 220 */ 00261 237, /* 221 */ 00262 237, /* 222 */ 00263 238, /* 223 */ 00264 238, /* 224 */ 00265 239, /* 225 */ 00266 240, /* 226 */ 00267 240, /* 227 */ 00268 241, /* 228 */ 00269 241, /* 229 */ 00270 242, /* 230 */ 00271 242, /* 231 */ 00272 243, /* 232 */ 00273 243, /* 233 */ 00274 244, /* 234 */ 00275 244, /* 235 */ 00276 245, /* 236 */ 00277 245, /* 237 */ 00278 246, /* 238 */ 00279 246, /* 239 */ 00280 247, /* 240 */ 00281 247, /* 241 */ 00282 248, /* 242 */ 00283 248, /* 243 */ 00284 249, /* 244 */ 00285 249, /* 245 */ 00286 250, /* 246 */ 00287 250, /* 247 */ 00288 251, /* 248 */ 00289 251, /* 249 */ 00290 252, /* 250 */ 00291 252, /* 251 */ 00292 253, /* 252 */ 00293 253, /* 253 */ 00294 254, /* 254 */ 00295 255 /* 255 */ 00296 }; 00297 00306 void _SDL_gfxBlitBlitterRGBA(SDL_gfxBlitInfo * info) 00307 { 00308 int width = info->d_width; 00309 int height = info->d_height; 00310 Uint8 *src = info->s_pixels; 00311 int srcskip = info->s_skip; 00312 Uint8 *dst = info->d_pixels; 00313 int dstskip = info->d_skip; 00314 SDL_PixelFormat *srcfmt = info->src; 00315 SDL_PixelFormat *dstfmt = info->dst; 00316 Uint8 srcbpp = srcfmt->BytesPerPixel; 00317 Uint8 dstbpp = dstfmt->BytesPerPixel; 00318 00319 while (height--) { 00320 GFX_DUFFS_LOOP4( { 00321 Uint32 pixel; 00322 unsigned sR; 00323 unsigned sG; 00324 unsigned sB; 00325 unsigned sA; 00326 unsigned dR; 00327 unsigned dG; 00328 unsigned dB; 00329 unsigned dA; 00330 unsigned sAA; 00331 GFX_DISASSEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA); 00332 GFX_DISASSEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); 00333 sAA=GFX_ALPHA_ADJUST_ARRAY[sA & 255]; 00334 GFX_ALPHA_BLEND(sR, sG, sB, sAA, dR, dG, dB); 00335 dA |= sAA; 00336 GFX_ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); 00337 src += srcbpp; dst += dstbpp; 00338 }, width); 00339 src += srcskip; 00340 dst += dstskip; 00341 } 00342 } 00343 00356 int _SDL_gfxBlitRGBACall(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect) 00357 { 00358 /* 00359 * Set up source and destination buffer pointers, then blit 00360 */ 00361 if (srcrect->w && srcrect->h) { 00362 SDL_gfxBlitInfo info; 00363 00364 /* 00365 * Set up the blit information 00366 */ 00367 #if (SDL_MINOR_VERSION == 3) 00368 info.s_pixels = (Uint8 *) src->pixels + (Uint16) srcrect->y * src->pitch + (Uint16) srcrect->x * src->format->BytesPerPixel; 00369 #else 00370 info.s_pixels = (Uint8 *) src->pixels + src->offset + (Uint16) srcrect->y * src->pitch + (Uint16) srcrect->x * src->format->BytesPerPixel; 00371 #endif 00372 info.s_width = srcrect->w; 00373 info.s_height = srcrect->h; 00374 info.s_skip = (int)(src->pitch - info.s_width * src->format->BytesPerPixel); 00375 #if (SDL_MINOR_VERSION == 3) 00376 info.d_pixels = (Uint8 *) dst->pixels + (Uint16) dstrect->y * dst->pitch + (Uint16) dstrect->x * dst->format->BytesPerPixel; 00377 #else 00378 info.d_pixels = (Uint8 *) dst->pixels + dst->offset + (Uint16) dstrect->y * dst->pitch + (Uint16) dstrect->x * dst->format->BytesPerPixel; 00379 #endif 00380 info.d_width = dstrect->w; 00381 info.d_height = dstrect->h; 00382 info.d_skip = (int)(dst->pitch - info.d_width * dst->format->BytesPerPixel); 00383 info.aux_data = NULL; 00384 info.src = src->format; 00385 info.table = NULL; 00386 info.dst = dst->format; 00387 00388 /* 00389 * Run the actual software blitter 00390 */ 00391 _SDL_gfxBlitBlitterRGBA(&info); 00392 return 1; 00393 } 00394 00395 return (0); 00396 } 00397 00411 int SDL_gfxBlitRGBA(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect) 00412 { 00413 SDL_Rect sr, dr; 00414 int srcx, srcy, w, h; 00415 00416 /* 00417 * Make sure the surfaces aren't locked 00418 */ 00419 if (!src || !dst) { 00420 SDL_SetError("SDL_UpperBlit: passed a NULL surface"); 00421 return (-1); 00422 } 00423 if ((src->locked) || (dst->locked)) { 00424 SDL_SetError("Surfaces must not be locked during blit"); 00425 return (-1); 00426 } 00427 00428 /* 00429 * If the destination rectangle is NULL, use the entire dest surface 00430 */ 00431 if (dstrect == NULL) { 00432 dr.x = dr.y = 0; 00433 dr.w = dst->w; 00434 dr.h = dst->h; 00435 } else { 00436 dr = *dstrect; 00437 } 00438 00439 /* 00440 * Clip the source rectangle to the source surface 00441 */ 00442 if (srcrect) { 00443 int maxw, maxh; 00444 00445 srcx = srcrect->x; 00446 w = srcrect->w; 00447 if (srcx < 0) { 00448 w += srcx; 00449 dr.x -= srcx; 00450 srcx = 0; 00451 } 00452 maxw = src->w - srcx; 00453 if (maxw < w) 00454 w = maxw; 00455 00456 srcy = srcrect->y; 00457 h = srcrect->h; 00458 if (srcy < 0) { 00459 h += srcy; 00460 dr.y -= srcy; 00461 srcy = 0; 00462 } 00463 maxh = src->h - srcy; 00464 if (maxh < h) 00465 h = maxh; 00466 00467 } else { 00468 srcx = srcy = 0; 00469 w = src->w; 00470 h = src->h; 00471 } 00472 00473 /* 00474 * Clip the destination rectangle against the clip rectangle 00475 */ 00476 { 00477 SDL_Rect *clip = &dst->clip_rect; 00478 int dx, dy; 00479 00480 dx = clip->x - dr.x; 00481 if (dx > 0) { 00482 w -= dx; 00483 dr.x += dx; 00484 srcx += dx; 00485 } 00486 dx = dr.x + w - clip->x - clip->w; 00487 if (dx > 0) 00488 w -= dx; 00489 00490 dy = clip->y - dr.y; 00491 if (dy > 0) { 00492 h -= dy; 00493 dr.y += dy; 00494 srcy += dy; 00495 } 00496 dy = dr.y + h - clip->y - clip->h; 00497 if (dy > 0) 00498 h -= dy; 00499 } 00500 00501 if (w > 0 && h > 0) { 00502 sr.x = srcx; 00503 sr.y = srcy; 00504 sr.w = dr.w = w; 00505 sr.h = dr.h = h; 00506 return (_SDL_gfxBlitRGBACall(src, &sr, dst, &dr)); 00507 } 00508 00509 return 0; 00510 } 00511 00524 int SDL_gfxSetAlpha(SDL_Surface *src, Uint8 a) 00525 { 00526 #if SDL_BYTEORDER == SDL_BIG_ENDIAN 00527 const int alpha_offset = 0; 00528 #else 00529 const int alpha_offset = 3; 00530 #endif 00531 int i, j, row_skip; 00532 Uint8 *pixels; 00533 00534 /* Check if we have a 32bit surface */ 00535 if ( (src==NULL) || 00536 (src->format==NULL) || 00537 (src->format->BytesPerPixel!=4) ) { 00538 SDL_SetError("SDL_gfxSetAlpha: Invalid input surface."); 00539 return -1; 00540 } 00541 00542 /* 00543 * Lock the surface 00544 */ 00545 if (SDL_MUSTLOCK(src)) { 00546 if (SDL_LockSurface(src) < 0) { 00547 return (-1); 00548 } 00549 } 00550 00551 /* Process */ 00552 pixels = (Uint8 *)src->pixels; 00553 row_skip = (src->pitch - (4*src->w)); 00554 pixels += alpha_offset; 00555 for ( i=0; i<src->h; i++ ) { 00556 for ( j=0; j<src->w; j++ ) { 00557 *pixels = a; 00558 pixels += 4; 00559 } 00560 pixels += row_skip; 00561 } 00562 00563 /* 00564 * Unlock surface 00565 */ 00566 if (SDL_MUSTLOCK(src)) { 00567 SDL_UnlockSurface(src); 00568 } 00569 00570 return 1; 00571 } 00572 00587 int SDL_gfxMultiplyAlpha(SDL_Surface *src, Uint8 a) 00588 { 00589 #if SDL_BYTEORDER == SDL_BIG_ENDIAN 00590 const int alpha_offset = 0; 00591 #else 00592 const int alpha_offset = 3; 00593 #endif 00594 int i, j, row_skip; 00595 Uint8 *pixels; 00596 00597 /* Check if we have a 32bit surface */ 00598 if ( (src==NULL) || 00599 (src->format==NULL) || 00600 (src->format->BytesPerPixel!=4) ) { 00601 SDL_SetError("SDL_gfxMultiplyAlpha: Invalid input surface."); 00602 return -1; 00603 } 00604 00605 /* Check if multiplication is needed */ 00606 if (a==255) { 00607 return 0; 00608 } 00609 00610 /* 00611 * Lock the surface 00612 */ 00613 if (SDL_MUSTLOCK(src)) { 00614 if (SDL_LockSurface(src) < 0) { 00615 return (-1); 00616 } 00617 } 00618 00619 /* Process */ 00620 pixels = (Uint8 *)src->pixels; 00621 row_skip = (src->pitch - (4*src->w)); 00622 pixels += alpha_offset; 00623 for ( i=0; i<src->h; i++ ) { 00624 for ( j=0; j<src->w; j++ ) { 00625 *pixels = (Uint8)(((int)(*pixels)*a)>>8); 00626 pixels += 4; 00627 } 00628 pixels += row_skip; 00629 } 00630 00631 /* 00632 * Unlock surface 00633 */ 00634 if (SDL_MUSTLOCK(src)) { 00635 SDL_UnlockSurface(src); 00636 } 00637 00638 return 1; 00639 }