Ignore:
Timestamp:
Apr 22, 2011, 4:13:08 AM (12 years ago)
Author:
Sam Hocevar
Message:

imlib: merge almost all trans_image blit methods into one large template
function and refactor them for size.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • abuse/trunk/src/imlib/timage.cpp

    r527 r528  
    235235}
    236236
    237 void trans_image::put_image_filled(image *screen, int x, int y,
    238                    uint8_t fill_color)
    239 {
    240   int x1, y1, x2, y2;
    241   int chop_length,ysteps;
    242 
    243   screen->GetClip(x1, y1, x2, y2);
    244   uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
    245           *screen_line;
    246   if (!datap)
    247     return; // if ClipToLine says nothing to draw, return
    248 
    249   screen->Lock();
    250 
    251   screen_line=screen->scan_line(y)+x;
    252   int sw=screen->Size().x-m_size.x;
    253   x1 -= x; x2 -= x;
    254   for (; ysteps>0; ysteps--)
    255   {
    256     int ix,slam_length;
    257     for (ix=0; ix<m_size.x; )
    258     {
    259       int blank=(*datap);
    260       memset(screen_line,fill_color,blank);
    261       ix+=blank;       // skip over empty space
    262       screen_line+=blank;
    263 
    264       datap++;
    265       if (ix<m_size.x)
    266       {
    267     slam_length=*datap;     // find the length of this run
    268     datap++;
    269     if (ix + slam_length < x1 || ix >= x2)  // see if this run is totally clipped
    270     {
    271       datap+=slam_length;
    272       ix+=slam_length;
    273       screen_line+=slam_length;
    274     }
    275     else
    276     {
    277       if (ix<x1)                // the left side needs to be chopped ?
    278       {
    279         chop_length=(x1-ix);
    280 
    281         if (chop_length>=slam_length)  // see if we chopped it all off
    282         {                              // yes, we did
    283           ix+=slam_length;             // advance everything to the end of run
    284           screen_line+=slam_length;
    285           datap+=slam_length;
    286           slam_length=0;
    287         } else
    288         {
    289           slam_length-=chop_length;   // else advance everything to begining of slam
    290           ix+=chop_length;
    291           screen_line+=chop_length;
    292           datap+=chop_length;
    293         }
    294       }
    295 
    296       if (slam_length)   // see if there is anything left to slam
    297       {
    298         if (ix + slam_length >= x2) // see if right side needs to be chopped off
    299           memcpy(screen_line, datap, x2 - ix);
    300         else
    301           memcpy(screen_line,datap,slam_length);
    302         datap+=slam_length;
    303         ix+=slam_length;
    304         screen_line+=slam_length;
    305       }
    306     }
    307       }
    308     }
    309     screen_line+=sw;
    310   }
    311   screen->Unlock();
     237void trans_image::PutFilled(image *screen, int x, int y, uint8_t color)
     238{
     239    PutImageGeneric<FILLED>(screen, x, y, color, NULL, 0, 0, NULL, NULL,
     240                            0, 1, NULL, NULL, NULL);
    312241}
    313242
     
    351280}
    352281
    353 void trans_image::put_image(image *screen, int x, int y)
    354 {
    355   int x1, y1, x2, y2;
    356   int chop_length,ysteps;
    357 
    358   screen->GetClip(x1, y1, x2, y2);
    359   uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
    360           *screen_line;
    361   if (!datap) return; // if ClipToLine says nothing to draw, return
    362 
    363   screen->Lock();
    364   screen_line=screen->scan_line(y)+x;
    365   int sw=screen->Size().x;
    366   x1 -= x; x2 -= x;
    367   for (; ysteps>0; ysteps--)
    368   {
    369     int ix,slam_length;
    370     for (ix=0; ix<m_size.x; )
    371     {
    372       ix+=(*datap);       // skip over empty space
    373       datap++;
    374       if (ix<m_size.x)
    375       {
    376     slam_length=*datap;     // find the length of this run
    377     datap++;
    378     if (ix + slam_length < x1 || ix >= x2)  // see if this run is totally clipped
    379     {
    380       datap+=slam_length;
    381       ix+=slam_length;
    382     }
    383     else
    384     {
    385       if (ix<x1)                // the left side needs to be chopped ?
    386       {
    387         chop_length=(x1-ix);
    388 
    389         if (chop_length>=slam_length)  // see if we chopped it all off
    390         {                              // yes, we did
    391           ix+=slam_length;             // advance everything to the end of run
    392           datap+=slam_length;
    393           slam_length=0;
    394         } else
    395         {
    396           slam_length-=chop_length;   // else advance everything to begining of slam
    397           ix+=chop_length;
    398           datap+=chop_length;
     282template<int N>
     283void trans_image::PutImageGeneric(image *screen, int x, int y, uint8_t color,
     284                                  image *blend, int bx, int by,
     285                                  uint8_t *remap, uint8_t *remap2,
     286                                  int amount, int total_frames,
     287                                  uint8_t *tint, color_filter *f, palette *pal)
     288{
     289    int x1, y1, x2, y2;
     290    int ysteps, mul = 0;
     291
     292    screen->GetClip(x1, y1, x2, y2);
     293    uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
     294            *screen_line, *blend_line = NULL, *paddr = NULL;
     295    if (!datap)
     296        return; // if ClipToLine says nothing to draw, return
     297
     298    CONDITION(N == BLEND && y >= by && y + ysteps < by + blend->Size().y + 1,
     299              "Blend doesn't fit on trans_image");
     300
     301    if (N == FADE || N == FADE_TINT || N == BLEND)
     302        paddr = (uint8_t *)pal->addr();
     303
     304    if (N == FADE || N == FADE_TINT)
     305        mul = (amount << 16) / total_frames;
     306    else if (N == BLEND)
     307        mul = ((16 - amount) << 16 / 16);
     308
     309    if (N == PREDATOR)
     310        ysteps = Min(ysteps, y2 - 1 - y - 2);
     311
     312    screen->Lock();
     313
     314    screen_line = screen->scan_line(y)+x;
     315    int sw = screen->Size().x;
     316    x1 -= x; x2 -= x;
     317
     318    for (; ysteps > 0; ysteps--, y++)
     319    {
     320        if (N == BLEND)
     321            blend_line = blend->scan_line(y - by);
     322
     323        for (int ix = 0; ix < m_size.x; )
     324        {
     325            // Handle a run of transparent pixels
     326            int todo = *datap++;
     327
     328            // FIXME: implement FILLED mode
     329            ix += todo;
     330            screen_line += todo;
     331
     332            if (ix >= m_size.x)
     333                break;
     334
     335            // Handle a run of solid pixels
     336            todo = *datap++;
     337
     338            // Chop left side if necessary, but no more than todo
     339            int tochop = Min(todo, Max(x1 - ix, 0));
     340
     341            ix += tochop;
     342            screen_line += tochop;
     343            datap += tochop;
     344            todo -= tochop;
     345
     346            // Chop right side if necessary and process the remaining pixels
     347            int count = Min(todo, Max(x2 - ix, 0));
     348
     349            if (N == NORMAL)
     350            {
     351                memcpy(screen_line, datap, count);
     352            }
     353            else if (N == COLOR)
     354            {
     355                memset(screen_line, color, count);
     356            }
     357            else if (N == PREDATOR)
     358            {
     359                memcpy(screen_line, screen_line + 2 * m_size.x, count);
     360            }
     361            else if (N == REMAP)
     362            {
     363                uint8_t *sl = screen_line, *sl2 = datap;
     364                while (count--)
     365                    *sl++ = remap[*sl2++];
     366            }
     367            else if (N == DOUBLE_REMAP)
     368            {
     369                uint8_t *sl = screen_line, *sl2 = datap;
     370                while (count--)
     371                    *sl++ = remap2[remap[*sl2++]];
     372            }
     373            else if (N == FADE || N == FADE_TINT || N == BLEND)
     374            {
     375                uint8_t *sl = screen_line;
     376                uint8_t *sl2 = (N == BLEND) ? blend_line + x + ix - bx : sl;
     377                uint8_t *sl3 = datap;
     378
     379                while (count--)
     380                {
     381                    uint8_t *p1 = paddr + 3 * *sl2++;
     382                    uint8_t *p2 = paddr + 3 * (N == FADE_TINT ? tint[*sl3++] : *sl3++);
     383
     384                    uint8_t r = ((((int)p1[0] - p2[0]) * mul) >> 16) + p2[0];
     385                    uint8_t g = ((((int)p1[1] - p2[1]) * mul) >> 16) + p2[1];
     386                    uint8_t b = ((((int)p1[2] - p2[2]) * mul) >> 16) + p2[2];
     387
     388                    *sl++ = f->lookup_color(r >> 3, g >> 3, b >> 3);
     389                }
     390            }
     391
     392            datap += todo;
     393            ix += todo;
     394            screen_line += todo;
    399395        }
    400       }
    401 
    402       if (slam_length)   // see if there is anything left to slam
    403       {
    404         if (ix + slam_length >= x2) // see if right side needs to be chopped off
    405           memcpy(screen_line + ix, datap, x2 - ix);
    406         else
    407           memcpy(screen_line+ix,datap,slam_length);
    408         datap+=slam_length;
    409         ix+=slam_length;
    410       }
    411     }
    412       }
    413     }
    414     screen_line+=sw;
    415   }
    416   screen->Unlock();
    417 }
    418 
    419 void trans_image::put_remaped(image *screen, int x, int y, uint8_t *remap)
    420 {
    421   int x1, y1, x2, y2;
    422   int chop_length, ysteps;
    423 
    424   screen->GetClip(x1, y1, x2, y2);
    425   uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
    426           *screen_line;
    427   if (!datap) return; // if ClipToLine says nothing to draw, return
    428 
    429   screen->Lock();
    430   screen_line=screen->scan_line(y)+x;
    431   int sw=screen->Size().x;
    432   x1 -= x; x2 -= x;
    433   for (; ysteps>0; ysteps--)
    434   {
    435     int ix,slam_length;
    436     for (ix=0; ix<m_size.x; )
    437     {
    438       ix+=(*datap);       // skip over empty space
    439       datap++;
    440       if (ix<m_size.x)
    441       {
    442     slam_length=*datap;     // find the length of this run
    443     datap++;
    444     if (ix + slam_length < x1 || ix >= x2)  // see if this run is totally clipped
    445     {
    446       datap+=slam_length;
    447       ix+=slam_length;
    448     }
    449     else
    450     {
    451       if (ix<x1)                // the left side needs to be chopped ?
    452       {
    453         chop_length=(x1-ix);
    454 
    455         if (chop_length>=slam_length)  // see if we chopped it all off
    456         {                              // yes, we did
    457           ix+=slam_length;             // advance everything to the end of run
    458           datap+=slam_length;
    459           slam_length=0;
    460         } else
    461         {
    462           slam_length-=chop_length;   // else advance everything to begining of slam
    463           ix+=chop_length;
    464           datap+=chop_length;
    465         }
    466       }
    467 
    468 
    469       if (slam_length)   // see if there is anything left to slam
    470       {
    471         int counter;
    472         if (ix + slam_length >= x2) // see if right side needs to be chopped off
    473           counter = x2 - ix;
    474         else
    475           counter = slam_length;
    476 
    477         uint8_t *sl=screen_line+ix,*sl2=datap;
    478         ix+=slam_length;
    479         datap+=slam_length;
    480         while (counter)
    481         {
    482           counter--;
    483           *(sl)=remap[*(sl2)];
    484           sl++;
    485           sl2++;
    486         }
    487       }
    488     }
    489       }
    490     }
    491     screen_line+=sw;
    492   }
    493   screen->Unlock();
    494 }
    495 
    496 
    497 
    498 void trans_image::put_double_remaped(image *screen, int x, int y, uint8_t *remap, uint8_t *remap2)
    499 {
    500   int x1, y1, x2, y2;
    501   int chop_length, ysteps;
    502 
    503   screen->GetClip(x1, y1, x2, y2);
    504   uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
    505           *screen_line;
    506   if (!datap) return; // if ClipToLine says nothing to draw, return
    507 
    508   screen->Lock();
    509   screen_line=screen->scan_line(y)+x;
    510   int sw=screen->Size().x;
    511   x1 -= x; x2 -= x;
    512   for (; ysteps>0; ysteps--)
    513   {
    514     int ix,slam_length;
    515     for (ix=0; ix<m_size.x; )
    516     {
    517       ix+=(*datap);       // skip over empty space
    518       datap++;
    519       if (ix<m_size.x)
    520       {
    521     slam_length=*datap;     // find the length of this run
    522     datap++;
    523     if (ix + slam_length < x1 || ix >= x2)  // see if this run is totally clipped
    524     {
    525       datap+=slam_length;
    526       ix+=slam_length;
    527     }
    528     else
    529     {
    530       if (ix<x1)                // the left side needs to be chopped ?
    531       {
    532         chop_length=(x1-ix);
    533 
    534         if (chop_length>=slam_length)  // see if we chopped it all off
    535         {                              // yes, we did
    536           ix+=slam_length;             // advance everything to the end of run
    537           datap+=slam_length;
    538           slam_length=0;
    539         } else
    540         {
    541           slam_length-=chop_length;   // else advance everything to begining of slam
    542           ix+=chop_length;
    543           datap+=chop_length;
    544         }
    545       }
    546 
    547 
    548       if (slam_length)   // see if there is anything left to slam
    549       {
    550         int counter;
    551         if (ix + slam_length >= x2) // see if right side needs to be chopped off
    552           counter = x2 - ix;
    553         else
    554           counter = slam_length;
    555 
    556         uint8_t *sl=screen_line+ix,*sl2=datap;
    557         ix+=slam_length;
    558         datap+=slam_length;
    559         while (counter)
    560         {
    561           counter--;
    562           *(sl)=remap2[remap[*(sl2)]];
    563           sl++;
    564           sl2++;
    565         }
    566       }
    567     }
    568       }
    569     }
    570     screen_line+=sw;
    571   }
    572   screen->Unlock();
    573 }
    574 
    575 
    576 
    577 void trans_image::put_fade(image *screen, int x, int y,
    578                int frame_on, int total_frames,
    579                color_filter *f, palette *pal)
    580 {
    581   int x1, y1, x2, y2;
    582   int ix,slam_length,chop_length,ysteps;
    583 
    584   screen->GetClip(x1, y1, x2, y2);
    585   uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
    586           *screen_line;
    587   if (!datap) return;
    588 
    589   uint8_t *screen_run,*paddr=(uint8_t *)pal->addr(),
    590                 *caddr1,*caddr2,r_dest,g_dest,b_dest;
    591 
    592   long fixmul=(frame_on<<16)/total_frames;
    593   screen->Lock();
    594   for (; ysteps>0; ysteps--,y++)
    595   {
    596     screen_line=screen->scan_line(y);
    597 
    598     for (ix=0; ix<m_size.x; )
    599     {
    600       ix+=(*datap);       // skip over empty space
    601       datap++;
    602       if (ix<m_size.x)
    603       {
    604     slam_length=*datap;     // find the length of this run
    605     datap++;
    606     if (x + ix + slam_length < x1 || x + ix >= x2)  // see if this run is totally clipped
    607     {
    608       datap+=slam_length;
    609       ix+=slam_length;
    610     }
    611     else
    612     {
    613       if (x+ix<x1)                // the left side needs to be chopped ?
    614       {
    615         chop_length=(x1-x-ix);
    616 
    617         if (chop_length>=slam_length)  // see if we chopped it all off
    618         {                              // yes, we did
    619           ix+=slam_length;             // advance everything to the end of run
    620           datap+=slam_length;
    621           slam_length=0;
    622         } else
    623         {
    624           slam_length-=chop_length;   // else advance everything to begining of slam
    625           ix+=chop_length;
    626           datap+=chop_length;
    627         }
    628       }
    629 
    630       if (slam_length)   // see if there is anything left to slam
    631       {
    632         if (x + ix + slam_length >= x2) // see if right side needs to be chopped off
    633           chop_length = x2 - 1 - x - ix;
    634         else
    635           chop_length = slam_length;
    636         screen_run=screen_line+x+ix;
    637 
    638         slam_length-=chop_length;
    639         ix+=chop_length;
    640 
    641         while (chop_length--)
    642         {
    643           caddr1=paddr+(int)(*screen_run)*3;
    644           caddr2=paddr+(int)(*datap)*3;
    645 
    646           r_dest=((((int)(*caddr1)-(int)(*caddr2))*fixmul)>>16)+(int)(*caddr2);
    647           caddr1++; caddr2++;
    648 
    649           g_dest=((((int)(*caddr1)-(int)(*caddr2))*fixmul)>>16)+(int)(*caddr2);
    650           caddr1++; caddr2++;
    651 
    652           b_dest=((((int)(*caddr1)-(int)(*caddr2))*fixmul)>>16)+(int)(*caddr2);
    653           *screen_run=f->lookup_color(r_dest>>3,g_dest>>3,b_dest>>3);
    654 
    655           screen_run++;
    656           datap++;
    657         }
    658         datap+=slam_length;
    659         ix+=slam_length;
    660       }
    661     }
    662       }
    663     }
    664   }
    665   screen->Unlock();
    666 }
    667 
    668 
    669 
    670 
    671 void trans_image::put_fade_tint(image *screen, int x, int y,
    672                 int frame_on, int total_frames,
    673                 uint8_t *tint,
    674                 color_filter *f, palette *pal)
    675 {
    676   int x1, y1, x2, y2;
    677   int ix,slam_length,chop_length,ysteps;
    678 
    679   screen->GetClip(x1, y1, x2, y2);
    680   uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
    681           *screen_line;
    682   if (!datap) return;
    683 
    684   screen->Lock();
    685   uint8_t *screen_run,*paddr=(uint8_t *)pal->addr(),
    686                 *caddr1,*caddr2,r_dest,g_dest,b_dest;
    687 
    688   long fixmul=(frame_on<<16)/total_frames;
    689   for (; ysteps>0; ysteps--,y++)
    690   {
    691     screen_line=screen->scan_line(y);
    692 
    693     for (ix=0; ix<m_size.x; )
    694     {
    695       ix+=(*datap);       // skip over empty space
    696       datap++;
    697       if (ix<m_size.x)
    698       {
    699     slam_length=*datap;     // find the length of this run
    700     datap++;
    701     if (x + ix + slam_length < x1 || x + ix >= x2)  // see if this run is totally clipped
    702     {
    703       datap+=slam_length;
    704       ix+=slam_length;
    705     }
    706     else
    707     {
    708       if (x+ix<x1)                // the left side needs to be chopped ?
    709       {
    710         chop_length=(x1-x-ix);
    711 
    712         if (chop_length>=slam_length)  // see if we chopped it all off
    713         {                              // yes, we did
    714           ix+=slam_length;             // advance everything to the end of run
    715           datap+=slam_length;
    716           slam_length=0;
    717         } else
    718         {
    719           slam_length-=chop_length;   // else advance everything to begining of slam
    720           ix+=chop_length;
    721           datap+=chop_length;
    722         }
    723       }
    724 
    725       if (slam_length)   // see if there is anything left to slam
    726       {
    727         if (x + ix + slam_length >= x2) // see if right side needs to be chopped off
    728           chop_length = x2 - 1 - x - ix;
    729         else chop_length=slam_length;
    730         screen_run=screen_line+x+ix;
    731 
    732         slam_length-=chop_length;
    733         ix+=chop_length;
    734 
    735         while (chop_length--)
    736         {
    737           caddr1=paddr+(int)(*screen_run)*3;
    738           caddr2=paddr+(int)(tint[*datap])*3;
    739 
    740           r_dest=((((int)(*caddr1)-(int)(*caddr2))*fixmul)>>16)+(int)(*caddr2);
    741           caddr1++; caddr2++;
    742 
    743           g_dest=((((int)(*caddr1)-(int)(*caddr2))*fixmul)>>16)+(int)(*caddr2);
    744           caddr1++; caddr2++;
    745 
    746           b_dest=((((int)(*caddr1)-(int)(*caddr2))*fixmul)>>16)+(int)(*caddr2);
    747           *screen_run=f->lookup_color(r_dest>>3,g_dest>>3,b_dest>>3);
    748 
    749           screen_run++;
    750           datap++;
    751         }
    752         datap+=slam_length;
    753         ix+=slam_length;
    754       }
    755     }
    756       }
    757     }
    758   }
    759   screen->Unlock();
    760 }
    761 
    762 void trans_image::put_color(image *screen, int x, int y, int color)
    763 {
    764   int x1, y1, x2, y2;
    765   int ix,slam_length,chop_length,ysteps;
    766 
    767   screen->GetClip(x1, y1, x2, y2);
    768   uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
    769           *screen_line;
    770   if (!datap) return;
    771 
    772   screen->Lock();
    773   for (; ysteps>0; ysteps--,y++)
    774   {
    775     screen_line=screen->scan_line(y);
    776 
    777     for (ix=0; ix<m_size.x; )
    778     {
    779       ix+=(*datap);       // skip over empty space
    780       datap++;
    781       if (ix<m_size.x)
    782       {
    783     slam_length=*datap;     // find the length of this run
    784     datap++;
    785     if (x + ix + slam_length < x1 || x + ix >= x2)  // see if this run is totally clipped
    786     {
    787       datap+=slam_length;
    788       ix+=slam_length;
    789     }
    790     else
    791     {
    792       if (x+ix<x1)                // the left side needs to be chopped ?
    793       {
    794         chop_length=(x1-x-ix);
    795 
    796         if (chop_length>=slam_length)  // see if we chopped it all off
    797         {                              // yes, we did
    798           ix+=slam_length;             // advance everything to the end of run
    799           datap+=slam_length;
    800           slam_length=0;
    801         } else
    802         {
    803           slam_length-=chop_length;   // else advance everything to begining of slam
    804           ix+=chop_length;
    805           datap+=chop_length;
    806         }
    807       }
    808 
    809       if (slam_length)   // see if there is anything left to slam
    810       {
    811         if (x + ix + slam_length >= x2) // see if right side needs to be chopped off
    812           memset(screen_line + x + ix, color, x2 - x - ix);
    813         else
    814           memset(screen_line + x + ix, color, slam_length);
    815         datap+=slam_length;
    816         ix+=slam_length;
    817       }
    818     }
    819       }
    820     }
    821   }
    822   screen->Unlock();
    823 }
    824 
    825 
    826 // ASSUMES that the blend image completly covers this image
    827 void trans_image::put_blend16(image *screen, image *blend, int x, int y,
    828                   int blendx, int blendy, int blend_amount, color_filter *f, palette *pal)
    829 
    830 {
    831   int x1, y1, x2, y2;
    832   int ix,slam_length,chop_length,ysteps;
    833   uint8_t *paddr=(uint8_t *)pal->addr();
    834 
    835   screen->GetClip(x1, y1, x2, y2);
    836   uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
    837           *blend_line, *screen_line;
    838   if (!datap) return;
    839   CONDITION(y>=blendy && y+ysteps<blendy+blend->Size().y+1,"Blend doesn't fit on trans_image");
    840 
    841   blend_amount=16-blend_amount;
    842 
    843   screen->Lock();
    844   for (; ysteps>0; ysteps--,y++)
    845   {
    846     screen_line=screen->scan_line(y);
    847     blend_line=blend->scan_line(y-blendy);
    848 
    849 
    850     for (ix=0; ix<m_size.x; )
    851     {
    852       ix+=(*datap);       // skip over empty space
    853       datap++;
    854       if (ix<m_size.x)
    855       {
    856     slam_length=*datap;     // find the length of this run
    857     datap++;
    858     if (x + ix + slam_length < x1 || x + ix >= x2)  // see if this run is totally clipped
    859     {
    860       datap+=slam_length;
    861       ix+=slam_length;
    862     }
    863     else
    864     {
    865       if (x+ix<x1)                // the left side needs to be chopped ?
    866       {
    867         chop_length=(x1-x-ix);
    868 
    869         if (chop_length>=slam_length)  // see if we chopped it all off
    870         {                              // yes, we did
    871           ix+=slam_length;             // advance everything to the end of run
    872           datap+=slam_length;
    873           slam_length=0;
    874         } else
    875         {
    876           slam_length-=chop_length;   // else advance everything to begining of slam
    877           ix+=chop_length;
    878           datap+=chop_length;
    879         }
    880       }
    881 
    882       if (slam_length)   // see if there is anything left to slam
    883       {
    884 
    885         if (x + ix + slam_length >= x2) // see if right side needs to be chopped off
    886           chop_length = x2 - 1 - x - ix;
    887         else
    888           chop_length = slam_length;
    889 
    890         uint8_t *screen_run=screen_line+x+ix,
    891                       *blend_run=blend_line+x+ix-blendx,
    892                       *caddr1,*caddr2,r_dest,g_dest,b_dest;
    893 
    894         slam_length-=chop_length;
    895         ix+=chop_length;
    896 
    897 
    898         while (chop_length--)
    899         {
    900           caddr1=paddr+(int)(*blend_run)*3;
    901           caddr2=paddr+(int)(*datap)*3;
    902 
    903           r_dest=((int)(*caddr1)-(int)(*caddr2))*blend_amount/16+(int)(*caddr2);
    904           caddr1++; caddr2++;
    905 
    906           g_dest=((int)(*caddr1)-(int)(*caddr2))*blend_amount/16+(int)(*caddr2);
    907           caddr1++; caddr2++;
    908 
    909           b_dest=((int)(*caddr1)-(int)(*caddr2))*blend_amount/16+(int)(*caddr2);
    910 
    911           *screen_run=f->lookup_color(r_dest>>3,g_dest>>3,b_dest>>3);
    912 
    913 
    914           screen_run++;
    915           blend_run++;
    916           datap++;
    917         }
    918         datap+=slam_length;
    919         ix+=slam_length;
    920       }
    921 
    922     }
    923       }
    924     }
    925   }
    926 
    927   screen->Unlock();
    928 }
    929 
    930 void trans_image::put_predator(image *screen, int x, int y)
    931 {
    932   int x1, y1, x2, y2;
    933   int chop_length,ysteps;
    934 
    935   screen->GetClip(x1, y1, x2, y2);
    936   uint8_t *datap = ClipToLine(screen, x1, y1, x2, y2, x, y, ysteps),
    937           *screen_line;
    938   if (!datap) return; // if ClipToLine says nothing to draw, return
    939 
    940   // see if the last scanline is clipped off
    941   ysteps = Min(ysteps, y2 - 1 - y - 2);
    942 
    943   screen->Lock();
    944   screen_line=screen->scan_line(y)+x;
    945   int sw=screen->Size().x;
    946   x1 -= x; x2 -= x;
    947   for (; ysteps>0; ysteps--)
    948   {
    949     int ix,slam_length;
    950     for (ix=0; ix<m_size.x; )
    951     {
    952       ix+=(*datap);       // skip over empty space
    953       datap++;
    954       if (ix<m_size.x)
    955       {
    956     slam_length=*datap;     // find the length of this run
    957     datap++;
    958     if (ix + slam_length < x1 || ix >= x2)  // see if this run is totally clipped
    959     {
    960       datap+=slam_length;
    961       ix+=slam_length;
    962     }
    963     else
    964     {
    965       if (ix<x1)                // the left side needs to be chopped ?
    966       {
    967         chop_length=(x1-ix);
    968 
    969         if (chop_length>=slam_length)  // see if we chopped it all off
    970         {                              // yes, we did
    971           ix+=slam_length;             // advance everything to the end of run
    972           datap+=slam_length;
    973           slam_length=0;
    974         } else
    975         {
    976           slam_length-=chop_length;   // else advance everything to begining of slam
    977           ix+=chop_length;
    978           datap+=chop_length;
    979         }
    980       }
    981 
    982       if (slam_length)   // see if there is anything left to slam
    983       {
    984         if (ix + slam_length >= x2) // see if right side needs to be chopped off
    985           memcpy(screen_line + ix, screen_line + sw + sw + ix, x2 - ix);
    986         else
    987           memcpy(screen_line + ix, screen_line + sw + sw + ix, slam_length);
    988         datap+=slam_length;
    989         ix+=slam_length;
    990       }
    991     }
    992       }
    993     }
    994     screen_line+=sw;
    995   }
    996   screen->Unlock();
     396        screen_line += sw - m_size.x;
     397    }
     398    screen->Unlock();
     399}
     400
     401void trans_image::PutImage(image *screen, int x, int y)
     402{
     403    PutImageGeneric<NORMAL>(screen, x, y, 0, NULL, 0, 0, NULL, NULL,
     404                            0, 1, NULL, NULL, NULL);
     405}
     406
     407void trans_image::PutRemap(image *screen, int x, int y, uint8_t *remap)
     408{
     409    PutImageGeneric<REMAP>(screen, x, y, 0, NULL, 0, 0, remap, NULL,
     410                           0, 1, NULL, NULL, NULL);
     411}
     412
     413void trans_image::PutDoubleRemap(image *screen, int x, int y,
     414                                 uint8_t *remap, uint8_t *remap2)
     415{
     416    PutImageGeneric<DOUBLE_REMAP>(screen, x, y, 0, NULL, 0, 0, remap, remap2,
     417                                  0, 1, NULL, NULL, NULL);
     418}
     419
     420// Used when eg. the player teleports, or in rocket trails
     421void trans_image::PutFade(image *screen, int x, int y,
     422                          int amount, int total_frames,
     423                          color_filter *f, palette *pal)
     424{
     425    PutImageGeneric<FADE>(screen, x, y, 0, NULL, 0, 0, NULL, NULL,
     426                          amount, total_frames, NULL, f, pal);
     427}
     428
     429void trans_image::PutFadeTint(image *screen, int x, int y,
     430                              int amount, int total_frames,
     431                              uint8_t *tint, color_filter *f, palette *pal)
     432{
     433    PutImageGeneric<FADE_TINT>(screen, x, y, 0, NULL, 0, 0, NULL, NULL,
     434                               amount, total_frames, tint, f, pal);
     435}
     436
     437void trans_image::PutColor(image *screen, int x, int y, uint8_t color)
     438{
     439    PutImageGeneric<COLOR>(screen, x, y, color, NULL, 0, 0, NULL, NULL,
     440                           0, 1, NULL, NULL, NULL);
     441}
     442
     443// This method is unused but is believed to work.
     444// Assumes that the blend image completely covers the transparent image.
     445void trans_image::PutBlend(image *screen, int x, int y,
     446                           image *blend, int bx, int by,
     447                           int amount, color_filter *f, palette *pal)
     448{
     449    PutImageGeneric<BLEND>(screen, x, y, 0, blend, bx, by, NULL, NULL,
     450                           amount, 1, NULL, f, pal);
     451}
     452
     453void trans_image::PutPredator(image *screen, int x, int y)
     454{
     455    PutImageGeneric<PREDATOR>(screen, x, y, 0, NULL, 0, 0, NULL, NULL,
     456                              0, 1, NULL, NULL, NULL);
    997457}
    998458
Note: See TracChangeset for help on using the changeset viewer.