SoftRenderSurface.cpp

Go to the documentation of this file.
00001 /*
00002 SoftRenderSurface.cpp : SoftRenderSurface Implementation source file
00003 
00004 Copyright (C) 2002, 2003 The Pentagram Team
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this program; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 */
00020 
00021 #include "pent_include.h"
00022 #include <SDL.h>
00023 
00024 #include "SoftRenderSurface.h"
00025 #include "Texture.h"
00026 #include "Shape.h"
00027 #include "ShapeFrame.h"
00028 #include "Palette.h"
00029 #include "FixedWidthFont.h"
00030 #include "memset_n.h"
00031 
00032 #include "XFormBlend.h"
00033 #include "scalers/PointScaler.h"
00034 #include "scalers/BilinearScaler.h"
00035 
00037 //                   //
00038 // SoftRenderSurface //
00039 //                   //
00041 
00042 
00043 //
00044 // SoftRenderSurface::SoftRenderSurface(SDL_Surface *s)
00045 //
00046 // Desc: Create a SoftRenderSurface from a SDL_Surface
00047 //
00048 template<class uintX> SoftRenderSurface<uintX>::SoftRenderSurface(SDL_Surface *s)
00049         : BaseSoftRenderSurface(s)
00050 {
00051 }
00052 
00053 
00054 //
00055 // SoftRenderSurface::SoftRenderSurface(int w, int h, int bpp, int rsft, int gsft, int bsft)
00056 //
00057 // Desc: Create a Generic SoftRenderSurface
00058 //
00059 template<class uintX> SoftRenderSurface<uintX>::SoftRenderSurface(int w, int h, int bpp, int rsft, int gsft, int bsft, int asft)
00060         : BaseSoftRenderSurface(w,h,bpp,rsft,gsft,bsft,asft)
00061 {
00062 }
00063 
00064 
00065 //
00066 // SoftRenderSurface::SoftRenderSurface(int w, int h)
00067 //
00068 // Desc: Create a Generic surface that matches current screen parameters
00069 //
00070 template<class uintX> SoftRenderSurface<uintX>::SoftRenderSurface(int w, int h, uint8 *buf)
00071         : BaseSoftRenderSurface(w,h,buf)
00072 {
00073 }
00074 
00075 
00076 //
00077 // SoftRenderSurface::SoftRenderSurface(int w, int h)
00078 //
00079 // Desc: Create a Render to texture surface
00080 //
00081 template<class uintX> SoftRenderSurface<uintX>::SoftRenderSurface(int w, int h)
00082         : BaseSoftRenderSurface(w,h)
00083 {
00084 }
00085 
00086 
00087 //
00088 // SoftRenderSurface::Fill8(uint8 index, sint32 sx, sint32 sy, sint32 w, sint32 h)
00089 //
00090 // Desc: Fill buffer (using a palette index) - Remove????
00091 //
00092 template<class uintX> void SoftRenderSurface<uintX>::Fill8(uint8 /*index*/, sint32 /*sx*/, sint32 /*sy*/, sint32 /*w*/, sint32 /*h*/)
00093 {
00094 }
00095 
00096 
00097 //
00098 // SoftRenderSurface::Fill32(uint32 rgb, sint32 sx, sint32 sy, sint32 w, sint32 h)
00099 //
00100 // Desc: Fill buffer (using a RGB colour)
00101 //
00102 
00103 template<class uintX> void SoftRenderSurface<uintX>::Fill32(uint32 rgb, sint32 sx, sint32 sy, sint32 w, sint32 h)
00104 {
00105         clip_window.IntersectOther(sx,sy,w,h);
00106         if (!w || !h) return;
00107 
00108         // An optimization.
00109         if ((w*sizeof(uintX)) == pitch)
00110         {
00111                 w *= h;
00112                 h = 1;
00113         }
00114 
00115         uint8 *pixel = pixels + sy * pitch + sx * sizeof(uintX);
00116         uint8 *end = pixel + h * pitch;
00117 
00118         rgb = PACK_RGB8( (rgb>>16)&0xFF , (rgb>>8)&0xFF , rgb&0xFF );
00119 
00120         uint8 *line_end = pixel + w*sizeof(uintX);
00121         int diff = pitch - w*sizeof(uintX);
00122 
00123         while (pixel != end)
00124         {
00125                 while (pixel != line_end)
00126                 {
00127                         *(reinterpret_cast<uintX*>(pixel)) = rgb;
00128                         pixel+=sizeof(uintX);
00129                 }
00130 
00131                 line_end += pitch;
00132                 pixel += diff;
00133         }
00134 }
00135 
00136 // 16 bit version
00137 template<> void SoftRenderSurface<uint16>::Fill32(uint32 rgb, sint32 sx, sint32 sy, sint32 w, sint32 h)
00138 {
00139         clip_window.IntersectOther(sx,sy,w,h);
00140         if (!w || !h) return;
00141 
00142         // An optimization.
00143         if (2*w == pitch)
00144         {
00145                 w *= h;
00146                 h = 1;
00147         }
00148 
00149         uint8 *pixel = pixels + sy * pitch + sx * sizeof(uint16);
00150         uint8 *end = pixel + h * pitch;
00151 
00152         rgb = PACK_RGB8( (rgb>>16)&0xFF , (rgb>>8)&0xFF , rgb&0xFF );
00153 
00154         while (pixel != end)
00155         {
00156                 Pentagram::memset_16(pixel,rgb,w);
00157                 pixel += pitch;
00158         }
00159 }
00160 
00161 // 32 bit version
00162 template<> void SoftRenderSurface<uint32>::Fill32(uint32 rgb, sint32 sx, sint32 sy, sint32 w, sint32 h)
00163 {
00164         clip_window.IntersectOther(sx,sy,w,h);
00165         if (!w || !h) return;
00166 
00167         // An optimization.
00168         if (4*w == pitch)
00169         {
00170                 w *= h;
00171                 h = 1;
00172         }
00173 
00174         uint8 *pixel = pixels + sy * pitch + sx * sizeof(uint32);
00175         uint8 *end = pixel + h * pitch;
00176 
00177         rgb = PACK_RGB8( (rgb>>16)&0xFF , (rgb>>8)&0xFF , rgb&0xFF );
00178 
00179         while (pixel != end)
00180         {
00181                 Pentagram::memset_32(pixel,rgb,w);
00182                 pixel += pitch;
00183         }
00184 }
00185 
00186 
00187 //
00188 // SoftRenderSurface::FillAlpha(uint8 alpha, sint32 sx, sint32 sy, sint32 w, sint32 h)
00189 //
00190 // Desc: Fill alpha channel
00191 //
00192 
00193 //#define CHECK_ALPHA_FILLS
00194 
00195 template<class uintX> void SoftRenderSurface<uintX>::FillAlpha(uint8 alpha, sint32 sx, sint32 sy, sint32 w, sint32 h)
00196 {
00197         clip_window.IntersectOther(sx,sy,w,h);
00198         if (!w || !h || !RenderSurface::format.a_mask) return;
00199 
00200         // An optimization.
00201         if ((w*sizeof(uintX)) == pitch)
00202         {
00203                 w *= h;
00204                 h = 1;
00205         }
00206 
00207         uint8 *pixel = pixels + sy * pitch + sx * sizeof(uintX);
00208         uint8 *end = pixel + h * pitch;
00209 
00210         uint8 *line_end = pixel + w*sizeof(uintX);
00211         int diff = pitch - w*sizeof(uintX);
00212 
00213         uintX a = (((uintX)alpha)<<RenderSurface::format.a_shift)&RenderSurface::format.a_mask;
00214 
00215 #ifdef CHECK_ALPHA_FILLS
00216         uintX c;
00217         uintX m;
00218         if (a == 0)
00219         {
00220                 c = (RenderSurface::format.b_mask>>1)&RenderSurface::format.b_mask;
00221                 m = RenderSurface::format.b_mask;
00222         }
00223         else 
00224         {
00225                 c = (RenderSurface::format.r_mask>>1)&RenderSurface::format.r_mask;
00226                 m = RenderSurface::format.r_mask;
00227         }
00228 #endif
00229 
00230         while (pixel != end)
00231         {
00232                 while (pixel != line_end)
00233                 {
00234                         uintX *dest = reinterpret_cast<uintX*>(pixel);
00235                         *dest =( *dest & ~RenderSurface::format.a_mask) | a;
00236 #ifdef CHECK_ALPHA_FILLS
00237                         *dest = (*dest&~m) | (c + (((*dest&m)>>1)&m));
00238 #endif
00239                         pixel+=sizeof(uintX);
00240                 }
00241 
00242                 line_end += pitch;
00243                 pixel += diff;
00244         }
00245 }
00246 
00247 //
00248 // SoftRenderSurface::DrawLine32(uint32 rgb, sint32 sx, sint32 sy, sint32 ex, sint32 ey);
00249 //
00250 // Desc: Draw a (non-antialiased) line from (sx,sy) to (ex,ey) with color rgb
00251 //
00252 
00253 template<class uintX> void SoftRenderSurface<uintX>::DrawLine32(uint32 rgb, sint32 sx, sint32 sy, sint32 ex, sint32 ey)
00254 {
00255         if (sy == ey) {
00256                 int w;
00257                 if (sx < ex) {
00258                         w = ex - sx + 1;
00259                 } else {
00260                         w = sx - ex + 1;
00261                         sx = ex;
00262                 }
00263                 Fill32(rgb, sx, sy, w, 1);
00264         } else if (sx == ex) {
00265                 int h;
00266                 if (sy < ey) {
00267                         h = ey - sy + 1;
00268                 } else {
00269                         h = sy - ey + 1;
00270                         sy = ey;
00271                 }
00272                 Fill32(rgb, sx, sy, 1, h);
00273         } else {
00274                 sint32 t;
00275                 bool steep = abs(ey - sy) > abs(ex - sx);
00276                 if (steep) {
00277                         t = sx; sx = sy; sy = t;
00278                         t = ex; ex = ey; ey = t;
00279                 }
00280                 if (sx > ex) {
00281                         t = sx; sx = ex; ex = t;
00282                         t = sy; sy = ey; ey = t;
00283                 }
00284                 int deltax = ex - sx;
00285                 int deltay = abs(ey - sy);
00286                 int error = -deltax / 2;
00287                 int y = sy;
00288                 int ystep = (sy < ey) ? 1 : -1;
00289                 for (int x = sx; x <= ex; ++x) {
00290                         // TODO: don't use Fill32 here; it's too slow
00291                         if (steep) {
00292                                 Fill32(rgb, y, x, 1, 1);
00293                         } else {
00294                                 Fill32(rgb, x, y, 1, 1);
00295                         }
00296                         error += deltay;
00297                         if (error > 0) {
00298                                 y += ystep;
00299                                 error -= deltax;
00300                         }
00301                 }
00302         }
00303 }
00304 
00305 
00306 //
00307 // SoftRenderSurface::Blit(Texture *, sint32 sx, sint32 sy, sint32 w, sint32 h, sint32 dx, sint32 dy, bool alpha_blend)
00308 //
00309 // Desc: Blit a region from a Texture (Alpha == 0 -> skipped)
00310 //
00311 template<class uintX> void SoftRenderSurface<uintX>::Blit(Texture *tex, sint32 sx, sint32 sy, sint32 w, sint32 h, sint32 dx, sint32 dy, bool alpha_blend)
00312 {
00313         // Clamp or wrap or return?
00314         if (sx+w > static_cast<sint32>(tex->width)) 
00315                 return;
00316         
00317         // Clamp or wrap or return?
00318         if (sy+h > static_cast<sint32>(tex->height)) 
00319                 return;
00320 
00321         if (sx < 0 || sy < 0) 
00322                 return;
00323         
00324         // Clip to window
00325         int px = dx, py = dy;
00326         clip_window.IntersectOther(dx,dy,w,h);
00327         if (!w || !h) return;
00328 
00329         // Adjust source x and y
00330         if (px != dx) sx += dx - px;
00331         if (py != dy) sy += dy - py;
00332 
00333         uint8 *pixel = pixels + dy * pitch + dx * sizeof(uintX);
00334         uint8 *line_end = pixel + w*sizeof(uintX);
00335         uint8 *end = pixel + h * pitch;
00336         int diff = pitch - w*sizeof(uintX);
00337 
00338         if (tex->format == TEX_FMT_STANDARD)
00339         {
00340                 uint32 *texel = tex->buffer + (sy * tex->width + sx);
00341                 int tex_diff = tex->width - w;
00342 
00343                 while (pixel != end)
00344                 {
00345                         if (!alpha_blend) while (pixel != line_end)
00346                         {
00347                                 if (*texel & TEX32_A_MASK)
00348                                 {
00349                                         *(reinterpret_cast<uintX*>(pixel)) = static_cast<uintX>(PACK_RGB8( TEX32_R(*texel), TEX32_G(*texel), TEX32_B(*texel) ));
00350                                 }
00351                                 pixel+=sizeof(uintX);
00352                                 texel++;
00353                         }
00354                         else while (pixel != line_end)
00355                         {
00356                                 uint32 alpha = *texel & TEX32_A_MASK;
00357                                 if (alpha == 0xFF)
00358                                 {
00359                                         *(reinterpret_cast<uintX*>(pixel)) = static_cast<uintX>(PACK_RGB8( TEX32_R(*texel), TEX32_G(*texel), TEX32_B(*texel) ));
00360                                 }
00361                                 else if (alpha) {
00362                                         uintX* dest = reinterpret_cast<uintX*>(pixel);
00363                                         *dest = static_cast<uintX>(BlendPreModFast(*texel,*dest));
00364                                 }
00365                                 pixel+=sizeof(uintX);
00366                                 texel++;
00367                         }
00368 
00369                         line_end += pitch;
00370                         pixel += diff;
00371                         texel+= tex_diff;
00372                 }
00373         }
00374         else if (tex->format == TEX_FMT_NATIVE)
00375         {
00376                 uintX *texel = reinterpret_cast<uintX*>(tex->buffer) + (sy * tex->width + sx);
00377                 int tex_diff = tex->width - w;
00378 
00379                 while (pixel != end)
00380                 {
00381                         while (pixel != line_end)
00382                         {
00383                                 // Uh, not supported right now
00384                                 //if (*texel & RenderSurface::a_mask)
00385                                 {
00386                                         *(reinterpret_cast<uintX*>(pixel)) = *texel;
00387                                 }
00388                                 pixel+=sizeof(uintX);
00389                                 texel++;
00390                         }
00391 
00392                         line_end += pitch;
00393                         pixel += diff;
00394                         texel+= tex_diff;
00395                 }
00396         }
00397 
00398 /* Old complete code
00399         // Clamp or wrap or return?
00400 #ifndef BLIT_WRAP
00401         if (w > static_cast<sint32>(tex->width)) 
00402 #ifndef BLIT_CLIP
00403                 return;
00404 #else
00405                 w = tex->width;
00406 #endif
00407         
00408         // Clamp or wrap or return?
00409         if (h > static_cast<sint32>(tex->height)) 
00410 #ifndef BLIT_CLIP
00411                 return;
00412 #else
00413                 h = tex->height;
00414 #endif
00415 #endif
00416         
00417         // Clip to window
00418         int px = dx, py = dy;
00419         clip_window.IntersectOther(dx,dy,w,h);
00420         if (!w || !h) return;
00421 
00422         // Adjust source x and y
00423         if (px != dx) sx += dx - px;
00424         if (py != dy) sy += dy - py;
00425 
00426         uint8 *pixel = pixels + dy * pitch + dx * sizeof(uintX);
00427         uint8 *line_end = pixel + w*sizeof(uintX);
00428         uint8 *end = pixel + h * pitch;
00429         int diff = pitch - w*sizeof(uintX);
00430 
00431         uint32 *texel = tex->buffer + (sy * tex->width + sx);
00432 #ifdef BLIT_WRAP
00433         uint32 *texel_line_start = tex->buffer + sy * tex->width;
00434         uint32 *texel_line_end = tex->buffer + (sy+1) * tex->width;
00435         uint32 *texel_col_start = tex->buffer + sx;
00436         uint32 *texel_col_end = tex->buffer + (tex->height * tex->width + sx);
00437 #endif
00438         int tex_diff = tex->width - w;
00439 
00440         //b = PACK_RGB8( (rgb>>16)&0xFF , (rgb>>8)&0xFF , rgb&0xFF );
00441 
00442         while (pixel != end)
00443         {
00444                 while (pixel != line_end)
00445                 {
00446                         if (*texel & TEX32_A_MASK)
00447                         {
00448                                 *(reinterpret_cast<uintX*>(pixel)) = static_cast<uintX>(PACK_RGB8( TEX32_R(*texel), TEX32_G(*texel), TEX32_B(*texel) ));
00449                         }
00450                         pixel+=sizeof(uintX);
00451                         texel++;
00452 #ifdef BLIT_WRAP
00453                         if (texel == texel_line_end) texel = texel_line_start;
00454 #endif
00455                 }
00456 
00457                 line_end += pitch;
00458                 pixel += diff;
00459                 texel+= tex_diff;
00460 #ifdef BLIT_WRAP
00461                 if (texel == texel_col_end) texel = texel_col_start;
00462 #endif
00463         }
00464 
00465 */
00466 
00467 
00468 }
00469 
00470 
00471 //
00472 // void SoftRenderSurface::FadedBlit(Texture *, sint32 sx, sint32 sy, sint32 w, sint32 h, sint32 dx, sint32 dy, uint32 col32)
00473 //
00474 // Desc: Blit a region from a Texture (Alpha == 0 -> skipped)
00475 //
00476 template<class uintX> void SoftRenderSurface<uintX>::FadedBlit(Texture *tex, sint32 sx, sint32 sy, sint32 w, sint32 h, sint32 dx, sint32 dy, uint32 col32, bool alpha_blend)
00477 {
00478         // Clamp or wrap or return?
00479         if (w > static_cast<sint32>(tex->width)) 
00480                 return;
00481         
00482         // Clamp or wrap or return?
00483         if (h > static_cast<sint32>(tex->height)) 
00484                 return;
00485         
00486         // Clip to window
00487         int px = dx, py = dy;
00488         clip_window.IntersectOther(dx,dy,w,h);
00489         if (!w || !h) return;
00490 
00491         // Adjust source x and y
00492         if (px != dx) sx += dx - px;
00493         if (py != dy) sy += dy - py;
00494 
00495         uint8 *pixel = pixels + dy * pitch + dx * sizeof(uintX);
00496         uint8 *line_end = pixel + w*sizeof(uintX);
00497         uint8 *end = pixel + h * pitch;
00498         int diff = pitch - w*sizeof(uintX);
00499         
00500         uint32 a = TEX32_A(col32);
00501         uint32 ia = 256-a;
00502         uint32 r = (TEX32_R(col32)*a);
00503         uint32 g = (TEX32_G(col32)*a);
00504         uint32 b = (TEX32_B(col32)*a);
00505 
00506         if (tex->format == TEX_FMT_STANDARD)
00507         {
00508                 uint32 *texel = tex->buffer + (sy * tex->width + sx);
00509                 int tex_diff = tex->width - w;
00510 
00511                 while (pixel != end)
00512                 {
00513                         if (!alpha_blend) while (pixel != line_end)
00514                         {
00515                                 if (*texel & TEX32_A_MASK)
00516                                 {
00517                                         *(reinterpret_cast<uintX*>(pixel)) = static_cast<uintX>(
00518                                                 PACK_RGB8( 
00519                                                         (TEX32_R(*texel)*ia+r)>>8, 
00520                                                         (TEX32_G(*texel)*ia+g)>>8, 
00521                                                         (TEX32_B(*texel)*ia+b)>>8 
00522                                                         )
00523                                                 );
00524                                 }
00525                                 pixel+=sizeof(uintX);
00526                                 texel++;
00527                         }
00528                         else while (pixel != line_end)
00529                         {
00530                                 uint32 alpha = *texel & TEX32_A_MASK;
00531                                 if (alpha == 0xFF)
00532                                 {
00533                                         *(reinterpret_cast<uintX*>(pixel)) = static_cast<uintX>(
00534                                                 PACK_RGB8( 
00535                                                         (TEX32_R(*texel)*ia+r)>>8, 
00536                                                         (TEX32_G(*texel)*ia+g)>>8, 
00537                                                         (TEX32_B(*texel)*ia+b)>>8 
00538                                                         )
00539                                                 );
00540                                 }
00541                                 else if (alpha) {
00542                                         uintX* dest = reinterpret_cast<uintX*>(pixel);
00543 
00544                                         uint32 src= *texel;
00545                                         uint32 dr, dg, db;
00546                                         UNPACK_RGB8(*dest,dr,dg,db);
00547 
00548                                         dr*=256-TEX32_A(src);
00549                                         dg*=256-TEX32_A(src);
00550                                         db*=256-TEX32_A(src);
00551                                         dr+=TEX32_R(src)*ia+((r*TEX32_A(src))>>8);
00552                                         dg+=TEX32_G(src)*ia+((g*TEX32_A(src))>>8);
00553                                         db+=TEX32_B(src)*ia+((b*TEX32_A(src))>>8);
00554 
00555                                         *dest = PACK_RGB16(dr, dg, db);
00556                                 }
00557                                 pixel+=sizeof(uintX);
00558                                 texel++;
00559                         }
00560 
00561                         line_end += pitch;
00562                         pixel += diff;
00563                         texel+= tex_diff;
00564                 }
00565         }
00566         else if (tex->format == TEX_FMT_NATIVE)
00567         {
00568                 uintX *texel = reinterpret_cast<uintX*>(tex->buffer) + (sy * tex->width + sx);
00569                 int tex_diff = tex->width - w;
00570 
00571                 while (pixel != end)
00572                 {
00573                         while (pixel != line_end)
00574                         {
00575                                 // Uh, not supported right now
00576                                 //if (*texel & RenderSurface::a_mask)
00577                                 {
00578                                         *(reinterpret_cast<uintX*>(pixel)) = BlendHighlight(*texel, r, g, b, 1, ia);
00579                                 }
00580                                 pixel+=sizeof(uintX);
00581                                 texel++;
00582                         }
00583 
00584                         line_end += pitch;
00585                         pixel += diff;
00586                         texel+= tex_diff;
00587                 }
00588         }
00589 }
00590 
00591 
00592 //
00593 // void SoftRenderSurface::MaskedBlit(Texture *, sint32 sx, sint32 sy, sint32 w, sint32 h, sint32 dx, sint32 dy, uint32 col32, bool alpha_blend=false)
00594 //
00595 // Desc Blit a region from a Texture with a Colour blend masked based on DestAlpha (AlphaTex == 0 || AlphaDest == 0 -> skipped. AlphaCol32 -> Blend Factors)
00596 //
00597 //
00598 template<class uintX> void SoftRenderSurface<uintX>::MaskedBlit(Texture *tex, sint32 sx, sint32 sy, sint32 w, sint32 h, sint32 dx, sint32 dy, uint32 col32, bool alpha_blend)
00599 {
00600         // Clamp or wrap or return?
00601         if (w > static_cast<sint32>(tex->width)) 
00602                 return;
00603         
00604         // Clamp or wrap or return?
00605         if (h > static_cast<sint32>(tex->height)) 
00606                 return;
00607         
00608         // Clip to window
00609         int px = dx, py = dy;
00610         clip_window.IntersectOther(dx,dy,w,h);
00611         if (!w || !h) return;
00612 
00613         // Adjust source x and y
00614         if (px != dx) sx += dx - px;
00615         if (py != dy) sy += dy - py;
00616 
00617         uint8 *pixel = pixels + dy * pitch + dx * sizeof(uintX);
00618         uint8 *line_end = pixel + w*sizeof(uintX);
00619         uint8 *end = pixel + h * pitch;
00620         int diff = pitch - w*sizeof(uintX);
00621         
00622         uint32 a = TEX32_A(col32);
00623         uint32 ia = 256-a;
00624         uint32 r = (TEX32_R(col32)*a);
00625         uint32 g = (TEX32_G(col32)*a);
00626         uint32 b = (TEX32_B(col32)*a);
00627 
00628         if (tex->format == TEX_FMT_STANDARD)
00629         {
00630                 uint32 *texel = tex->buffer + (sy * tex->width + sx);
00631                 int tex_diff = tex->width - w;
00632 
00633                 while (pixel != end)
00634                 {
00635                         if (!alpha_blend) while (pixel != line_end)
00636                         {
00637                                 uintX* dest = reinterpret_cast<uintX*>(pixel);
00638 
00639                                 if ((*texel & TEX32_A_MASK) && (*dest & RenderSurface::format.a_mask))
00640                                 {
00641                                         *dest = static_cast<uintX>(
00642                                                 PACK_RGB8( 
00643                                                         (TEX32_R(*texel)*ia+r)>>8, 
00644                                                         (TEX32_G(*texel)*ia+g)>>8, 
00645                                                         (TEX32_B(*texel)*ia+b)>>8 
00646                                                         )
00647                                                 );
00648                                 }
00649                                 pixel+=sizeof(uintX);
00650                                 texel++;
00651                         }
00652                         else while (pixel != line_end)
00653                         {
00654                                 uintX* dest = reinterpret_cast<uintX*>(pixel);
00655 
00656                                 if (*dest & RenderSurface::format.a_mask)
00657                                 {
00658                                         uint32 alpha = *texel & TEX32_A_MASK;
00659                                         if (alpha == 0xFF)
00660                                         {
00661                                                 *dest = static_cast<uintX>(
00662                                                         PACK_RGB8( 
00663                                                                 (TEX32_R(*texel)*ia+r)>>8, 
00664                                                                 (TEX32_G(*texel)*ia+g)>>8, 
00665                                                                 (TEX32_B(*texel)*ia+b)>>8 
00666                                                                 )
00667                                                         );
00668                                         }
00669                                         else if (alpha) {
00670                                                 uint32 src= *texel;
00671                                                 uint32 dr, dg, db;
00672                                                 UNPACK_RGB8(*dest,dr,dg,db);
00673 
00674                                                 dr*=256-TEX32_A(src);
00675                                                 dg*=256-TEX32_A(src);
00676                                                 db*=256-TEX32_A(src);
00677                                                 dr+=TEX32_R(src)*ia+((r*TEX32_A(src))>>8);
00678                                                 dg+=TEX32_G(src)*ia+((g*TEX32_A(src))>>8);
00679                                                 db+=TEX32_B(src)*ia+((b*TEX32_A(src))>>8);
00680 
00681                                                 *dest = PACK_RGB16(dr, dg, db);
00682                                         }
00683                                 }
00684                                 pixel+=sizeof(uintX);
00685                                 texel++;
00686                         }
00687 
00688                         line_end += pitch;
00689                         pixel += diff;
00690                         texel+= tex_diff;
00691                 }
00692         }
00693         else if (tex->format == TEX_FMT_NATIVE)
00694         {
00695                 uintX *texel = reinterpret_cast<uintX*>(tex->buffer) + (sy * tex->width + sx);
00696                 int tex_diff = tex->width - w;
00697 
00698                 while (pixel != end)
00699                 {
00700                         while (pixel != line_end)
00701                         {
00702                                 uintX* dest = reinterpret_cast<uintX*>(pixel);
00703 
00704                                 // Uh, not completely supported right now
00705                                 //if ((*texel & RenderSurface::format.a_mask) && (*dest & RenderSurface::format.a_mask))
00706                                 if (*dest & RenderSurface::format.a_mask)
00707                                 {
00708                                         *dest = BlendHighlight(*texel, r, g, b, 1, ia);
00709                                 }
00710                                 pixel+=sizeof(uintX);
00711                                 texel++;
00712                         }
00713 
00714                         line_end += pitch;
00715                         pixel += diff;
00716                         texel+= tex_diff;
00717                 }
00718         }
00719 }
00720 
00721 
00722 
00723 //
00724 // void SoftRenderSurface::StretchBlit(Texture *, sint32 sx, sint32 sy, sint32 sw, sint32 sh, sint32 dx, sint32 dy, sint32 dw, sint32 dh, bool bilinear, bool clampedges)
00725 //
00726 // Desc: Blit a region from a Texture, and arbitrarily stretch it to fit the dest region
00727 //
00728 //
00729 template<class uintX> void SoftRenderSurface<uintX>::StretchBlit(Texture *texture, 
00730                                                                 sint32 sx, sint32 sy, sint32 sw, sint32 sh, 
00731                                                                 sint32 dx, sint32 dy, sint32 dw, sint32 dh, 
00732                                                                 bool bilinear, bool clampedges)
00733 {
00734         // Nothing we can do
00735         if ((sh <= 0) || (dh <= 0) || (sw <= 0) || (dw <= 0)) return;
00736 
00737         // 1x No scaling needed
00738         if (dw == sw && sh == dh)
00739         {
00740                 Blit(texture, sw, sy, sw, sh, dx, dy);
00741                 return;
00742         }
00743 
00744         uint8 *pixel = pixels + dy * pitch + dx * sizeof(uintX);
00745 
00746         if (bilinear)
00747         {
00748                 if (Pentagram::bilinear_scaler.Scale(texture,sx,sy,sw,sh,pixel,dw,dh,pitch,clampedges))
00749                         return;
00750         }
00751         // Ok easy simple scale
00752 
00753         Pentagram::point_scaler.Scale(texture,sx,sy,sw,sh,pixel,dw,dh,pitch,clampedges);
00754 }
00755 
00756 //
00757 // bool SoftRenderSurface::ScalerBlit(Texture *texure, sint32 sx, sint32 sy, sint32 sw, sint32 sh, sint32 dx, sint32 dy, sint32 dw, sint32 dh, const Pentagram::Scaler *scaler, bool clampedges)
00758 //
00759 // Desc: Blit a region from a Texture using a scaler
00760 //
00761 //
00762 template<class uintX> bool SoftRenderSurface<uintX>::ScalerBlit(Texture *texture, sint32 sx, sint32 sy, sint32 sw, sint32 sh, sint32 dx, sint32 dy, sint32 dw, sint32 dh, const Pentagram::Scaler *scaler, bool clampedges)
00763 {
00764         // Nothing we can do
00765         if ((sh <= 0) || (dh <= 0) || (sw <= 0) || (dw <= 0)) return false;
00766 
00767         // 1x No scaling needed (but still do it anyway, could be a filter????)
00768         if (dw == sw && sh == dh)
00769         {
00770                 Blit(texture, sw, sy, sw, sh, dx, dy);
00771                 return true;
00772         }
00773 
00774         uint8 *pixel = pixels + dy * pitch + dx * sizeof(uintX);
00775 
00776         return scaler->Scale(texture,sx,sy,sw,sh,pixel,dw,dh,pitch,clampedges);
00777 }
00778 
00779 //
00780 // SoftRenderSurface::PrintCharFixed(FixedWidthFont *, char character, int x, int y)
00781 //
00782 // Desc: Draw a fixed width character from a Texture buffer
00783 //
00784 template<class uintX> void SoftRenderSurface<uintX>::PrintCharFixed(FixedWidthFont *font, int character, int x, int y)
00785 {
00786         if (character == ' ') return;   // Don't paint spaces
00787 
00788         int align_x = font->align_x;
00789         int align_y = font->align_y;
00790         int char_width = font->width;
00791         int char_height = font->height;
00792         Texture *texture = font->tex;
00793 
00794         if (align_x == 16 && align_y == 16)
00795         {
00796                 SoftRenderSurface::Blit(texture, (character&0x0F) << 4, character&0xF0, char_width, char_height, x, y);
00797         }
00798         else if (align_x == 8 && align_y == 8)
00799         {
00800                 SoftRenderSurface::Blit(texture, (character&0x0F) << 3, (character>>1)&0x78, char_width, char_height, x, y);
00801         }
00802         else
00803         {
00804                 SoftRenderSurface::Blit(texture,  (character&0x0F) * align_x, (character&0xF0>>4) * align_y, char_width, char_height, x, y);
00805         }
00806 }
00807 
00808 
00809 //
00810 // SoftRenderSurface::PrintTextFixed(FixedWidthFont *, const char *text, int x, int y)
00811 //
00812 // Desc: Draw fixed width from a Texture buffer (16x16 characters fixed width and height)
00813 //
00814 template<class uintX> void SoftRenderSurface<uintX>::PrintTextFixed(FixedWidthFont *font, const char *text, int x, int y)
00815 {
00816         int align_x = font->align_x;
00817         int align_y = font->align_y;
00818         int char_width = font->width;
00819         int char_height = font->height;
00820         Texture *texture = font->tex;
00821 
00822         int character;
00823         if (align_x == 16 && align_y == 16) while ( 0 != (character = *text))
00824         {
00825                 SoftRenderSurface::Blit(texture, (character&0x0F) << 4, character&0xF0, char_width, char_height, x, y);
00826                 ++text;
00827                 x+=char_width;
00828         }
00829         else if (align_x == 8 && align_y == 8) while (0 != (character = *text))
00830         {
00831                 SoftRenderSurface::Blit(texture, (character&0x0F) << 3, (character>>1)&0x78, char_width, char_height, x, y);
00832                 ++text;
00833                 x+=char_width;
00834         }
00835         else while (0 != (character = *text))
00836         {
00837                 SoftRenderSurface::Blit(texture,  (character&0x0F) * align_x, (character&0xF0>>4) * align_y, char_width, char_height, x, y);
00838                 ++text;
00839                 x+=char_width;
00840         }
00841 }
00842 
00843 
00844 //
00845 // void SoftRenderSurface::Paint(Shape*s, uint32 framenum, sint32 x, sint32 y)
00846 //
00847 // Desc: Standard shape drawing functions. Clips but doesn't do anything else
00848 //
00849 template<class uintX> void SoftRenderSurface<uintX>::Paint(Shape*s, uint32 framenum, sint32 x, sint32 y, bool untformed_pal)
00850 {
00851         #include "SoftRenderSurface.inl"
00852 }
00853 
00854 
00855 //
00856 // void SoftRenderSurface::PaintNoClip(Shape*s, uint32 framenum, sint32 x, sint32 y)
00857 //
00858 // Desc: Standard shape drawing functions. Doesn't clip
00859 //
00860 template<class uintX> void SoftRenderSurface<uintX>::PaintNoClip(Shape*s, uint32 framenum, sint32 x, sint32 y, bool untformed_pal)
00861 {
00862 #define NO_CLIPPING
00863         #include "SoftRenderSurface.inl"
00864 #undef NO_CLIPPING
00865 }
00866 
00867 
00868 //
00869 // void SoftRenderSurface::PaintTranslucent(Shape*s, uint32 framenum, sint32 x, sint32 y)
00870 //
00871 // Desc: Standard shape drawing functions. Clips and XForms
00872 //
00873 template<class uintX> void SoftRenderSurface<uintX>::PaintTranslucent(Shape* s, uint32 framenum, sint32 x, sint32 y, bool untformed_pal)
00874 {
00875 #define XFORM_SHAPES
00876         #include "SoftRenderSurface.inl"
00877 #undef XFORM_SHAPES
00878 }
00879 
00880 
00881 //
00882 // void SoftRenderSurface::PaintMirrored(Shape*s, uint32 framenum, sint32 x, sint32 y, bool trans)
00883 //
00884 // Desc: Standard shape drawing functions. Clips, Flips and conditionally XForms
00885 //
00886 template<class uintX> void SoftRenderSurface<uintX>::PaintMirrored(Shape* s, uint32 framenum, sint32 x, sint32 y, bool trans, bool untformed_pal)
00887 {
00888 #define FLIP_SHAPES
00889 #define XFORM_SHAPES
00890 #define XFORM_CONDITIONAL trans
00891 
00892         #include "SoftRenderSurface.inl"
00893 
00894 #undef FLIP_SHAPES
00895 #undef XFORM_SHAPES
00896 #undef XFORM_CONDITIONAL
00897 }
00898 
00899 
00900 //
00901 // void SoftRenderSurface::PaintInvisible(Shape* s, uint32 frame, sint32 x, sint32 y, bool mirrored)
00902 //
00903 // Desc: Standard shape drawing functions. Invisible, Clips, and conditionally Flips and Xforms
00904 //
00905 
00906 template<class uintX> void SoftRenderSurface<uintX>::PaintInvisible(Shape* s, uint32 framenum, sint32 x, sint32 y, bool trans, bool mirrored, bool untformed_pal)
00907 {
00908 #define FLIP_SHAPES
00909 #define FLIP_CONDITIONAL mirrored
00910 #define XFORM_SHAPES
00911 #define XFORM_CONDITIONAL trans
00912 #define BLEND_SHAPES(src,dst) BlendInvisible(src,dst)
00913 
00914         #include "SoftRenderSurface.inl"
00915 
00916 #undef FLIP_SHAPES
00917 #undef FLIP_CONDITIONAL
00918 #undef XFORM_SHAPES
00919 #undef XFORM_CONDITIONAL
00920 #undef BLEND_SHAPES
00921 }
00922 
00923 
00924 //
00925 // void SoftRenderSurface::PaintHighlight(Shape* s, uint32 frame, sint32 x, sint32 y, bool mirrored)
00926 //
00927 // Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms
00928 //
00929 
00930 template<class uintX> void SoftRenderSurface<uintX>::PaintHighlight(Shape* s, uint32 framenum, sint32 x, sint32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal)
00931 {
00932 #define FLIP_SHAPES
00933 #define FLIP_CONDITIONAL mirrored
00934 #define XFORM_SHAPES
00935 #define XFORM_CONDITIONAL trans
00936 #define BLEND_SHAPES(src,dst) BlendHighlight(src,cr,cg,cb,ca,255-ca)
00937 
00938         uint32 ca = TEX32_A(col32);
00939         uint32 cr = TEX32_R(col32);
00940         uint32 cg = TEX32_G(col32);
00941         uint32 cb = TEX32_B(col32);
00942 
00943         #include "SoftRenderSurface.inl"
00944 
00945 #undef FLIP_SHAPES
00946 #undef FLIP_CONDITIONAL
00947 #undef XFORM_SHAPES
00948 #undef XFORM_CONDITIONAL
00949 #undef BLEND_SHAPES
00950 }
00951 
00952 //
00953 // void SoftRenderSurface::PaintHighlightInvis(Shape* s, uint32 frame, sint32 x, sint32 y, bool mirrored)
00954 //
00955 // Desc: Standard shape drawing functions. Highlights, Clips, and conditionally Flips and Xforms. 50% translucent
00956 //
00957 
00958 template<class uintX> void SoftRenderSurface<uintX>::PaintHighlightInvis(Shape* s, uint32 framenum, sint32 x, sint32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal)
00959 {
00960 #define FLIP_SHAPES
00961 #define FLIP_CONDITIONAL mirrored
00962 #define XFORM_SHAPES
00963 #define XFORM_CONDITIONAL trans
00964 #define BLEND_SHAPES(src,dst) BlendHighlightInvis(src,dst,cr,cg,cb,ca,255-ca)
00965 
00966         uint32 ca = TEX32_A(col32);
00967         uint32 cr = TEX32_R(col32);
00968         uint32 cg = TEX32_G(col32);
00969         uint32 cb = TEX32_B(col32);
00970 
00971         #include "SoftRenderSurface.inl"
00972 
00973 #undef FLIP_SHAPES
00974 #undef FLIP_CONDITIONAL
00975 #undef XFORM_SHAPES
00976 #undef XFORM_CONDITIONAL
00977 #undef BLEND_SHAPES
00978 }
00979 
00980 //
00981 // void SoftRenderSurface::PaintHighlight(Shape* s, uint32 frame, sint32 x, sint32 y, bool mirrored)
00982 //
00983 // Desc: Standard shape drawing functions. Masked against Dest Alpha. Highlights, Clips, and conditionally Flips and Xforms
00984 //
00985 
00986 template<class uintX> void SoftRenderSurface<uintX>::PaintMasked(Shape* s, uint32 framenum, sint32 x, sint32 y, bool trans, bool mirrored, uint32 col32, bool untformed_pal)
00987 {
00988 #define FLIP_SHAPES
00989 #define FLIP_CONDITIONAL mirrored
00990 #define XFORM_SHAPES
00991 #define XFORM_CONDITIONAL trans
00992 #define BLEND_SHAPES(src,dst) BlendHighlight(src,cr,cg,cb,ca,255-ca)
00993 #define DESTALPHA_MASK
00994 
00995         uint32 ca = TEX32_A(col32);
00996         uint32 cr = TEX32_R(col32);
00997         uint32 cg = TEX32_G(col32);
00998         uint32 cb = TEX32_B(col32);
00999 
01000         #include "SoftRenderSurface.inl"
01001 
01002 #undef FLIP_SHAPES
01003 #undef FLIP_CONDITIONAL
01004 #undef XFORM_SHAPES
01005 #undef XFORM_CONDITIONAL
01006 #undef BLEND_SHAPES
01007 #undef DESTALPHA_MASK
01008 }
01009 
01010 //
01011 // Instantiate the SoftRenderSurface Class
01012 //
01013 template class SoftRenderSurface<uint16>;
01014 template class SoftRenderSurface<uint32>;

Generated on Fri Jul 27 22:27:39 2007 for pentagram by  doxygen 1.4.7