CopperRLE8.cpp
Go to the documentation of this file.00001 //*** CopperRLE8.cpp *** 00002 00003 #include "CopperRLE8.h" 00004 #include "ColorHelper.h" 00005 #include "StandardLibrary.h" 00006 00007 00008 //*** Opaque_Unclipped_Unmasked *** 00009 00010 void CopperRLE8::Opaque_Unclipped_Unmasked(unsigned char* opaqueData, int activeWidth, int activeHeight, unsigned short* palette, unsigned short* colorData, unsigned char* alphaData, int backBufferDelta,int x, int y) 00011 { 00012 unsigned char* dataRLE=opaqueData; 00013 for (int yi=0; yi<activeHeight; ++yi) 00014 { 00015 int xi=0; 00016 while (xi<activeWidth) 00017 { 00018 // Get run length 00019 int len=*dataRLE; 00020 ++dataRLE; 00021 00022 RunLength_Opaque_Unclipped_Unmasked(len,colorData,alphaData,&dataRLE,palette); 00023 len&=0x7f; 00024 colorData+=len; 00025 alphaData+=len; 00026 00027 xi+=len; 00028 } 00029 00030 colorData+=backBufferDelta; 00031 alphaData+=backBufferDelta; 00032 } 00033 } 00034 00035 00036 //*** Opaque_Unclipped_Masked *** 00037 00038 void CopperRLE8::Opaque_Unclipped_Masked(unsigned char* opaqueData, int activeWidth, int activeHeight, unsigned short* palette, unsigned short* colorData, unsigned char* alphaData, int backBufferDelta,int x, int y) 00039 { 00040 unsigned char* dataRLE=opaqueData; 00041 for (int yi=0; yi<activeHeight; ++yi) 00042 { 00043 int xi=0; 00044 while (xi<activeWidth) 00045 { 00046 // Get run length 00047 int len=*dataRLE; 00048 ++dataRLE; 00049 00050 RunLength_Opaque_Unclipped_Masked(len,colorData,alphaData,&dataRLE,palette); 00051 len&=0x7f; 00052 colorData+=len; 00053 alphaData+=len; 00054 00055 xi+=len; 00056 } 00057 colorData+=backBufferDelta; 00058 alphaData+=backBufferDelta; 00059 } 00060 } 00061 00062 00063 //*** Opaque_Clipped_Unmasked *** 00064 00065 void CopperRLE8::Opaque_Clipped_Unmasked(unsigned char* opaqueData, int activeWidth, int activeHeight, unsigned short* palette, unsigned short* colorData, unsigned char* alphaData, int backBufferDelta,int x, int y, int xStart, int yStart, int xEnd, int yEnd) 00066 { 00067 unsigned char* dataRLE=opaqueData; 00068 00069 // Skip clipped rows 00070 for (int i=0; i<yStart; i++) 00071 { 00072 int xi=0; 00073 while (xi<activeWidth) 00074 { 00075 // Get run length 00076 int len=*dataRLE; 00077 ++dataRLE; 00078 00079 IgnoreOpaque(len,&dataRLE); 00080 len&=0x7f; 00081 00082 xi+=len; 00083 } 00084 } 00085 00086 colorData+=yStart*(backBufferDelta+activeWidth); 00087 alphaData+=yStart*(backBufferDelta+activeWidth); 00088 00089 for (int yi=yStart; yi<(activeHeight-yEnd); yi++) 00090 { 00091 int xi=0; 00092 while (xi<activeWidth) 00093 { 00094 // Get run length 00095 int len=*dataRLE; 00096 ++dataRLE; 00097 00098 // Are we on the edge? 00099 int runLength=(len&0x7f); 00100 if (xi<xStart || (xi+runLength)>(activeWidth-xEnd)) 00101 { 00102 // yes, on the edge, but is the whole segment off screen? 00103 if ((xi+runLength)<xStart || xi>(activeWidth-xEnd)) 00104 { 00105 // Yes, whole segment is out of view, so ignore 00106 IgnoreOpaque(len,&dataRLE); 00107 } 00108 else 00109 { 00110 // No, only part of the segment is out of view, so need to draw with clipping 00111 int clipStart=xStart-xi; 00112 int clipEnd=(activeWidth-xEnd)-xi; 00113 RunLength_Opaque_Clipped_Masked(len,colorData,alphaData,&dataRLE,palette,clipStart,clipEnd); 00114 // Yes, we use the masked version here, because it doesn't give enough speed benefit to have a special 00115 // unmasked version of the clipped one 00116 } 00117 } 00118 else // nope, not near edge, so just barge ahead 00119 { 00120 RunLength_Opaque_Unclipped_Unmasked(len,colorData,alphaData,&dataRLE,palette); 00121 } 00122 00123 len&=0x7f; 00124 colorData+=len; 00125 alphaData+=len; 00126 00127 xi+=len; 00128 } 00129 colorData+=backBufferDelta; 00130 alphaData+=backBufferDelta; 00131 } 00132 } 00133 00134 00135 //*** Opaque_Clipped_Masked *** 00136 00137 void CopperRLE8::Opaque_Clipped_Masked(unsigned char* opaqueData, int activeWidth, int activeHeight, unsigned short* palette, unsigned short* colorData, unsigned char* alphaData, int backBufferDelta,int x, int y, int xStart, int yStart, int xEnd, int yEnd) 00138 { 00139 if (yStart>activeHeight-yEnd) 00140 return; 00141 if (xStart>activeWidth-xEnd) 00142 return; 00143 unsigned char* dataRLE=opaqueData; 00144 00145 // Skip clipped rows 00146 for (int i=0; i<yStart; i++) 00147 { 00148 int xi=0; 00149 while (xi<activeWidth) 00150 { 00151 // Get run length 00152 int len=*dataRLE; 00153 ++dataRLE; 00154 00155 IgnoreOpaque(len,&dataRLE); 00156 len&=0x7f; 00157 00158 xi+=len; 00159 } 00160 } 00161 00162 colorData+=yStart*(backBufferDelta+activeWidth); 00163 alphaData+=yStart*(backBufferDelta+activeWidth); 00164 00165 for (int yi=yStart; yi<(activeHeight-yEnd); ++yi) 00166 { 00167 int xi=0; 00168 while (xi<activeWidth) 00169 { 00170 // Get run length 00171 int len=*dataRLE; 00172 ++dataRLE; 00173 00174 // Are we on the edge? 00175 int runLength=(len&0x7f); 00176 if (xi<xStart || (xi+runLength)>(activeWidth-xEnd)) 00177 { 00178 // yes, on the edge, but is the whole segment off screen? 00179 if ((xi+runLength)<xStart || xi>(activeWidth-xEnd)) 00180 { 00181 // Yes, whole segment is out of view, so ignore 00182 IgnoreOpaque(len,&dataRLE); 00183 } 00184 else 00185 { 00186 // No, only part of the segment is out of view, so need to draw with clipping 00187 int clipStart=xStart-xi; 00188 int clipEnd=(activeWidth-xEnd)-xi; 00189 00190 RunLength_Opaque_Clipped_Masked(len,colorData, alphaData,&dataRLE,palette,clipStart,clipEnd); 00191 } 00192 } 00193 else // nope, not near edge, so just barge ahead 00194 { 00195 RunLength_Opaque_Unclipped_Masked(len,colorData,alphaData,&dataRLE,palette); 00196 } 00197 00198 len&=0x7f; 00199 colorData+=len; 00200 alphaData+=len; 00201 00202 xi+=len; 00203 } 00204 colorData+=backBufferDelta; 00205 alphaData+=backBufferDelta; 00206 } 00207 } 00208 00209 00210 00211 //*** Alpha_Unclipped *** 00212 00213 void CopperRLE8::Alpha_Unclipped(unsigned char* alphaRLEData, int activeWidth, int activeHeight, unsigned short* palette, unsigned short* colorData, unsigned char* alphaData, int backBufferDelta,int x, int y) 00214 { 00215 unsigned char* dataRLE=alphaRLEData; 00216 for (int yi=0; yi<activeHeight; ++yi) 00217 { 00218 int xi=0; 00219 while (xi<activeWidth) 00220 { 00221 // Get run length 00222 unsigned int len=*dataRLE; 00223 ++dataRLE; 00224 if (len&0x80) 00225 { 00226 len&=0x7f; 00227 // Unique values 00228 for (unsigned int i=0; i<len; ++i) 00229 { 00230 unsigned char alpha=*dataRLE; 00231 ++dataRLE; 00232 *colorData=palette[*dataRLE]; 00233 *alphaData=alpha; 00234 ++dataRLE; 00235 ++colorData; 00236 ++alphaData; 00237 } 00238 } 00239 else 00240 { 00241 unsigned char alpha=*dataRLE; 00242 ++dataRLE; 00243 if (alpha!=0) 00244 { 00245 unsigned short color=palette[*dataRLE]; 00246 ++dataRLE; 00247 00248 for (unsigned int i=0; i<len; ++i) 00249 { 00250 *colorData=color; 00251 *alphaData=alpha; 00252 ++colorData; 00253 ++alphaData; 00254 } 00255 } 00256 else 00257 { 00258 ++dataRLE; 00259 colorData+=len; 00260 alphaData+=len; 00261 } 00262 } 00263 xi+=len; 00264 } 00265 colorData+=backBufferDelta; 00266 alphaData+=backBufferDelta; 00267 } 00268 } 00269 00270 00271 00272 //*** Alpha_Clipped *** 00273 00274 void CopperRLE8::Alpha_Clipped(unsigned char* alphaRLEData, int activeWidth, int activeHeight, unsigned short* palette, unsigned short* colorData, unsigned char* alphaData, int backBufferDelta,int x, int y, int xStart, int yStart, int xEnd, int yEnd) 00275 { 00276 unsigned char* dataRLE=alphaRLEData; 00277 00278 // Skip clipped rows 00279 for (int i=0; i<yStart; i++) 00280 { 00281 int xi=0; 00282 while (xi<activeWidth) 00283 { 00284 // Get run length 00285 int len=*dataRLE; 00286 ++dataRLE; 00287 00288 IgnoreAlpha(len,&dataRLE); 00289 len&=0x7f; 00290 00291 xi+=len; 00292 } 00293 } 00294 00295 colorData+=yStart*(backBufferDelta+activeWidth); 00296 alphaData+=yStart*(backBufferDelta+activeWidth); 00297 00298 for (int yi=yStart; yi<activeHeight-yEnd; ++yi) 00299 { 00300 int xi=0; 00301 while (xi<activeWidth) 00302 { 00303 // Get run length 00304 int len=*dataRLE; 00305 ++dataRLE; 00306 if (len&0x80) 00307 { 00308 len&=0x7f; 00309 // Unique values 00310 for (int i=0; i<len; ++i) 00311 { 00312 unsigned char alpha=*dataRLE; 00313 ++dataRLE; 00314 if (alpha!=0 && (xi+i)>=xStart && (xi+i)<=(activeWidth-xEnd)) 00315 { 00316 *colorData=palette[*dataRLE]; 00317 *alphaData=alpha; 00318 } 00319 ++dataRLE; 00320 ++colorData; 00321 ++alphaData; 00322 } 00323 } 00324 else 00325 { 00326 unsigned char alpha=*dataRLE; 00327 ++dataRLE; 00328 if (alpha!=0) 00329 { 00330 unsigned short color=palette[*dataRLE]; 00331 ++dataRLE; 00332 00333 for (int i=0; i<len; ++i) 00334 { 00335 if ((xi+i)>=xStart && (xi+i)<=(activeWidth-xEnd)) 00336 { 00337 *colorData=color; 00338 *alphaData=alpha; 00339 } 00340 ++colorData; 00341 ++alphaData; 00342 } 00343 } 00344 else 00345 { 00346 ++dataRLE; 00347 colorData+=len; 00348 alphaData+=len; 00349 } 00350 } 00351 xi+=len; 00352 } 00353 colorData+=backBufferDelta; 00354 alphaData+=backBufferDelta; 00355 } 00356 } 00357 00358 00359 00360 //*** RunLength_Opaque_Unclipped_Unmasked *** 00361 00362 void CopperRLE8::RunLength_Opaque_Unclipped_Unmasked(int len,unsigned short* colorData, unsigned char* alphaData, unsigned char** source, unsigned short* palette) 00363 { 00364 unsigned char* dataRLE=*source; 00365 if (len&0x80) 00366 { 00367 len&=0x7f; 00368 // Unique values 00369 for (int i=0; i<len; ++i) 00370 { 00371 *colorData=palette[*dataRLE]; 00372 *alphaData=255; 00373 ++colorData; 00374 ++alphaData; 00375 ++(dataRLE); 00376 } 00377 } 00378 else 00379 { 00380 // Run of values 00381 #ifdef _DEBUG 00382 Fill(colorData,palette[*dataRLE],len); 00383 AlphaFill(alphaData,len); 00384 #else 00385 BurstFill(colorData,palette[*dataRLE],len); 00386 AlphaBurstFill(alphaData,len); 00387 #endif 00388 ++(dataRLE); 00389 } 00390 *source=dataRLE; 00391 } 00392 00393 00394 //*** RunLength_Opaque_Clipped_Masked *** 00395 00396 void CopperRLE8::RunLength_Opaque_Clipped_Masked(int len,unsigned short* colorData, unsigned char* alphaData, unsigned char** source, unsigned short* palette, int clipStart, int clipEnd) 00397 { 00398 unsigned char* dataRLE=*source; 00399 int x=0; 00400 if (len&0x80) 00401 { 00402 len&=0x7f; 00403 // Unique values 00404 for (int i=0; i<len; ++i) 00405 { 00406 if ((*dataRLE)<255 && x>=clipStart && x<=clipEnd) 00407 { 00408 *colorData=palette[*dataRLE]; 00409 *alphaData=0xff; 00410 } 00411 ++x; 00412 ++colorData; 00413 ++alphaData; 00414 ++(dataRLE); 00415 } 00416 } 00417 else 00418 { 00419 // Run of values 00420 int colorIndex=*dataRLE; 00421 if(colorIndex<255) 00422 { 00423 unsigned short color=palette[colorIndex]; 00424 for (int i=0; i<len; ++i) 00425 { 00426 if (colorIndex<255 && x>=clipStart && x<=clipEnd) 00427 { 00428 *colorData=color; 00429 *alphaData=0xff; 00430 } 00431 ++x; 00432 ++colorData; 00433 ++alphaData; 00434 } 00435 } 00436 else 00437 { 00438 x+=len; 00439 colorData+=len; 00440 alphaData+=len; 00441 } 00442 00443 ++(dataRLE); 00444 } 00445 *source=dataRLE; 00446 } 00447 00448 00449 //*** RunLength_Opaque_Unclipped_Masked *** 00450 00451 void CopperRLE8::RunLength_Opaque_Unclipped_Masked(int len,unsigned short* colorData, unsigned char* alphaData, unsigned char** source, unsigned short* palette) 00452 { 00453 unsigned char* dataRLE=*source; 00454 if (len&0x80) 00455 { 00456 len&=0x7f; 00457 // Unique values 00458 for (int i=0; i<len; ++i) 00459 { 00460 if ((*dataRLE)<255) 00461 { 00462 *colorData=palette[*dataRLE]; 00463 *alphaData=0xff; 00464 } 00465 ++colorData; 00466 ++alphaData; 00467 ++(dataRLE); 00468 } 00469 } 00470 else 00471 { 00472 // Run of values 00473 if ((*dataRLE)<255) 00474 { 00475 #ifdef _DEBUG 00476 Fill(colorData,palette[*dataRLE],len); 00477 AlphaFill(alphaData,len); 00478 #else 00479 BurstFill(colorData,palette[*dataRLE],len); 00480 AlphaBurstFill(alphaData,len); 00481 #endif 00482 } 00483 ++(dataRLE); 00484 } 00485 *source=dataRLE; 00486 } 00487 00488 00489 //*** Fill *** 00490 00491 void CopperRLE8::Fill(unsigned short* data, unsigned short color, int len) 00492 { 00493 for (int i=0; i<len; ++i) 00494 { 00495 *data=color; 00496 data++; 00497 } 00498 } 00499 00500 00501 00502 //*** BurstFill *** 00503 00504 // This is to make sure we fill on 4 byte alignment as much as possible 00505 void CopperRLE8::BurstFill(unsigned short* data, unsigned short color, int len) 00506 { 00507 int len2=len; 00508 00509 00510 #pragma warning (push) 00511 #pragma warning( disable: 4311) 00512 #ifdef _WIN32 00513 if (((int)data)!=(((int)data)&(0xfffffffc))) 00514 #else 00515 if (((long long)data)!=(((long long)data)&(0xfffffffffffffffc))) 00516 #endif 00517 #pragma warning (pop) 00518 { 00519 *data=color; 00520 ++data; 00521 --len2; 00522 if (len2==1) 00523 { 00524 *data=color; 00525 ++data; 00526 --len2; 00527 } 00528 } 00529 if (len2) 00530 { 00531 unsigned int color32=color | (color<<16); 00532 int halflen=len2/2; 00533 unsigned int* data32=reinterpret_cast<unsigned int*>(data); 00534 for (int i=0; i<halflen; ++i) 00535 { 00536 *data32=color32; 00537 ++data32; 00538 } 00539 data=reinterpret_cast<unsigned short*>(data32); 00540 if (len2-halflen*2) 00541 { 00542 *data=color; 00543 ++data; 00544 } 00545 } 00546 } 00547 00548 00549 00550 //*** AlphaFill *** 00551 00552 void CopperRLE8::AlphaFill(unsigned char*data, int len) 00553 { 00554 for (int i=0; i<len; ++i) 00555 { 00556 *data=0xff; 00557 data++; 00558 } 00559 } 00560 00561 00562 //*** AlphaBurstFill *** 00563 00564 // This is to make sure we fill on 4 byte alignment as much as possible 00565 void CopperRLE8::AlphaBurstFill(unsigned char* data, int len) 00566 { 00567 int len2=len; 00568 00569 #pragma warning (push) 00570 #pragma warning( disable: 4311) 00571 #ifdef _WIN32 00572 while (((int)data)!=(((int)data)&(0xfffffffc))) 00573 #else 00574 while (((long long)data)!=(((long long)data)&(0xfffffffffffffffc))) 00575 #endif 00576 #pragma warning (pop) 00577 00578 { 00579 *data=0xff; 00580 ++data; 00581 --len2; 00582 } 00583 if (len2) 00584 { 00585 int quarterlen=len2/4; 00586 unsigned int* data32=reinterpret_cast<unsigned int*>(data); 00587 for (int i=0; i<quarterlen; ++i) 00588 { 00589 *data32=0xffffffff; 00590 ++data32; 00591 } 00592 data=reinterpret_cast<unsigned char*>(data32); 00593 while (len2-quarterlen*4) 00594 { 00595 *data=0xff; 00596 ++data; 00597 len2--; 00598 } 00599 } 00600 } 00601 00602 00603 00604 00605 00606 //*** IgnoreOpaque *** 00607 00608 void CopperRLE8::IgnoreOpaque(int len, unsigned char** source) 00609 { 00610 unsigned char* dataRLE=*source; 00611 if (len&0x80) 00612 { 00613 len&=0x7f; 00614 dataRLE+=len; 00615 } 00616 else 00617 { 00618 ++dataRLE; 00619 } 00620 *source=dataRLE; 00621 } 00622 00623 00624 //*** IgnoreAlpha *** 00625 00626 void CopperRLE8::IgnoreAlpha(int len, unsigned char** source) 00627 { 00628 unsigned char* dataRLE=*source; 00629 if (len&0x80) 00630 { 00631 len&=0x7f; 00632 dataRLE+=len*2; 00633 } 00634 else 00635 { 00636 dataRLE+=2; 00637 } 00638 *source=dataRLE; 00639 } 00640 00641
Reproduction/republishing of any material on this site without permission is strictly prohibited.
