📄 rleaccel.c
字号:
*(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) \ + ((d & (mask | mask << 16)) >> 1) \ + (s & d & (~(mask | mask << 16))); \ src += 2; \ dst += 2; \ } \ if(n) \ BLEND16_50(dst, src, mask); /* last odd pixel */ \ } \ } while(0)#define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \ ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xf7de)#define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \ ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xfbde)#define CHOOSE_BLIT(blitter, alpha, fmt) \ do { \ if(alpha == 255) { \ switch(fmt->BytesPerPixel) { \ case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \ case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \ case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \ case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \ } \ } else { \ switch(fmt->BytesPerPixel) { \ case 1: \ /* No 8bpp alpha blitting */ \ break; \ \ case 2: \ switch(fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ case 0xffff: \ if(fmt->Gmask == 0x07e0 \ || fmt->Rmask == 0x07e0 \ || fmt->Bmask == 0x07e0) { \ if(alpha == 128) \ blitter(2, Uint8, ALPHA_BLIT16_565_50); \ else { \ alpha >>= 3; /* use 5 bit alpha */ \ blitter(2, Uint8, ALPHA_BLIT16_565); \ } \ } else \ goto general16; \ break; \ \ case 0x7fff: \ if(fmt->Gmask == 0x03e0 \ || fmt->Rmask == 0x03e0 \ || fmt->Bmask == 0x03e0) { \ if(alpha == 128) \ blitter(2, Uint8, ALPHA_BLIT16_555_50); \ else { \ alpha >>= 3; /* use 5 bit alpha */ \ blitter(2, Uint8, ALPHA_BLIT16_555); \ } \ break; \ } \ /* fallthrough */ \ \ default: \ general16: \ blitter(2, Uint8, ALPHA_BLIT_ANY); \ } \ break; \ \ case 3: \ blitter(3, Uint8, ALPHA_BLIT_ANY); \ break; \ \ case 4: \ if((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \ && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \ || fmt->Bmask == 0xff00)) { \ if(alpha == 128) \ blitter(4, Uint16, ALPHA_BLIT32_888_50); \ else \ blitter(4, Uint16, ALPHA_BLIT32_888); \ } else \ blitter(4, Uint16, ALPHA_BLIT_ANY); \ break; \ } \ } \ } while(0)/* * This takes care of the case when the surface is clipped on the left and/or * right. Top clipping has already been taken care of. */static void RLEClipBlit(int w, Uint8 *srcbuf, GAL_Surface *dst, Uint8 *dstbuf, GAL_Rect *srcrect, unsigned alpha){ GAL_PixelFormat *fmt = dst->format;#define RLECLIPBLIT(bpp, Type, do_blit) \ do { \ int linecount = srcrect->h; \ int ofs = 0; \ int left = srcrect->x; \ int right = left + srcrect->w; \ dstbuf -= left * bpp; \ for(;;) { \ int run; \ ofs += *(Type *)srcbuf; \ run = ((Type *)srcbuf)[1]; \ srcbuf += 2 * sizeof(Type); \ if(run) { \ /* clip to left and right borders */ \ if(ofs < right) { \ int start = 0; \ int len = run; \ int startcol; \ if(left - ofs > 0) { \ start = left - ofs; \ len -= start; \ if(len <= 0) \ goto nocopy ## bpp ## do_blit; \ } \ startcol = ofs + start; \ if(len > right - startcol) \ len = right - startcol; \ do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \ len, bpp, alpha); \ } \ nocopy ## bpp ## do_blit: \ srcbuf += run * bpp; \ ofs += run; \ } else if(!ofs) \ break; \ if(ofs == w) { \ ofs = 0; \ dstbuf += dst->pitch; \ if(!--linecount) \ break; \ } \ } \ } while(0) CHOOSE_BLIT(RLECLIPBLIT, alpha, fmt);#undef RLECLIPBLIT}/* blit a colorkeyed RLE surface */int GAL_RLEBlit(GAL_Surface *src, GAL_Rect *srcrect, GAL_Surface *dst, GAL_Rect *dstrect){ Uint8 *dstbuf; Uint8 *srcbuf; int x, y; int w = src->w; unsigned alpha;#if 0 /* Lock the destination if necessary */ if ( dst->flags & (GAL_HWSURFACE|GAL_ASYNCBLIT) ) { GAL_VideoDevice *video = current_video; GAL_VideoDevice *this = current_video; if ( video->LockHWSurface(this, dst) < 0 ) { return(-1); } }#endif /* Set up the source and destination pointers */ x = dstrect->x; y = dstrect->y; dstbuf = (Uint8 *)dst->pixels + dst->offset + y * dst->pitch + x * src->format->BytesPerPixel; srcbuf = (Uint8 *)src->map->sw_data->aux_data; { /* skip lines at the top if neccessary */ int vskip = srcrect->y; int ofs = 0; if(vskip) {#define RLESKIP(bpp, Type) \ for(;;) { \ int run; \ ofs += *(Type *)srcbuf; \ run = ((Type *)srcbuf)[1]; \ srcbuf += sizeof(Type) * 2; \ if(run) { \ srcbuf += run * bpp; \ ofs += run; \ } else if(!ofs) \ goto done; \ if(ofs == w) { \ ofs = 0; \ if(!--vskip) \ break; \ } \ } switch(src->format->BytesPerPixel) { case 1: RLESKIP(1, Uint8); break; case 2: RLESKIP(2, Uint8); break; case 3: RLESKIP(3, Uint8); break; case 4: RLESKIP(4, Uint16); break; }#undef RLESKIP } } alpha = (src->flags & GAL_SRCALPHA) == GAL_SRCALPHA ? src->format->alpha : 255; /* if left or right edge clipping needed, call clip blit */ if ( srcrect->x || srcrect->w != src->w ) { RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha); } else { GAL_PixelFormat *fmt = src->format;#define RLEBLIT(bpp, Type, do_blit) \ do { \ int linecount = srcrect->h; \ int ofs = 0; \ for(;;) { \ unsigned run; \ ofs += *(Type *)srcbuf; \ run = ((Type *)srcbuf)[1]; \ srcbuf += 2 * sizeof(Type); \ if(run) { \ do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \ srcbuf += run * bpp; \ ofs += run; \ } else if(!ofs) \ break; \ if(ofs == w) { \ ofs = 0; \ dstbuf += dst->pitch; \ if(!--linecount) \ break; \ } \ } \ } while(0) CHOOSE_BLIT(RLEBLIT, alpha, fmt);#undef RLEBLIT }done:#if 0 /* Unlock the destination if necessary */ if ( dst->flags & (GAL_HWSURFACE|GAL_ASYNCBLIT) ) { GAL_VideoDevice *video = current_video; GAL_VideoDevice *this = current_video; video->UnlockHWSurface(this, dst); }#endif return(0);}#undef OPAQUE_BLIT/* * Per-pixel blitting macros for translucent pixels: * These use the same techniques as the per-surface blitting macros *//* * For 32bpp pixels, we have made sure the alpha is stored in the top * 8 bits, so proceed as usual */#define BLIT_TRANSL_888(src, dst) \ do { \ Uint32 s = src; \ Uint32 d = dst; \ unsigned alpha = s >> 24; \ Uint32 s1 = s & 0xff00ff; \ Uint32 d1 = d & 0xff00ff; \ d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ s &= 0xff00; \ d &= 0xff00; \ d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ dst = d1 | d; \ } while(0)/* * For 16bpp pixels, we have stored the 5 most significant alpha bits in * bits 5-10. As before, we can process all 3 RGB components at the same time. */#define BLIT_TRANSL_565(src, dst) \ do { \ Uint32 s = src; \ Uint32 d = dst; \ unsigned alpha = (s & 0x3e0) >> 5; \ s &= 0x07e0f81f; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -