source: abuse/trunk/src/imlib/timage.cpp @ 56

Last change on this file since 56 was 56, checked in by Sam Hocevar, 11 years ago
  • Add licensing terms to most C / C++ files (Ref #5).
File size: 24.9 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *
5 *  This software was released into the Public Domain. As with most public
6 *  domain software, no warranty is made or implied by Crack dot Com or
7 *  Jonathan Clark.
8 */
9
10#include "config.h"
11
12#include "timage.hpp"
13
14void trans_image::make_color(int c)
15{
16  uint8_t *dp=data;
17  int y,x;
18  for (y=0;y<h;y++)
19  {
20    x=0;
21    while(x<w)
22    {
23      x+=*(dp++);
24      if (x<w)
25      {     
26        int run=*(dp++);
27        memset(dp,c,run);
28        x+=run;
29        dp+=run;
30      }
31    }
32  }
33}
34
35image *trans_image::make_image()
36{
37  image *im=new image(w,h);
38  uint8_t *d=im->scan_line(0),*dp=data,*dline;
39  int y,x;
40  for (y=0;y<h;y++)
41  {
42    x=0;
43    dline=d;
44    memset(dline,0,w);
45    while(x<w)
46    {
47      int skip=*(dp++);
48      dline+=skip;
49      x+=skip;
50      if (x<w)
51      {     
52        int run=*(dp++);
53        memcpy(dline,dp,run);
54        x+=run;
55        dline+=run;
56        dp+=run;
57      }
58    }
59    d=im->next_line(y,d);
60  }
61  return im;
62}
63
64trans_image::trans_image(image *im, char const *name)
65{
66  int size=0,x,y;
67  uint8_t *sl,*datap,*marker;
68  w=im->width();
69  h=im->height();
70 
71  // first we must find out how much data to allocate
72  for (y=0;y<im->height();y++)
73  {
74    sl=im->scan_line(y);
75    x=0;   
76    while (x<w)
77    {     
78      size++;     
79      while (x<w && *sl==0) { sl++; x++; }     
80                                                               
81      if (x<w)
82      {
83        size++;  // byte for the size of the run       
84        while (x<w && (*sl)!=0)
85        {
86          size++;
87          x++;
88          sl++;   
89        }       
90      }
91    }       
92  } 
93
94#ifdef MEM_CHECK
95  char st[80];
96  sprintf(st,"trans_image::data (%s)",name);
97  data=(uint8_t *)jmalloc(size,st);
98#else
99  data=(uint8_t *)jmalloc(size,"");
100#endif
101  int ww=im->width(),hh=im->height();
102  datap=data;
103  if (!datap)
104  { printf("size = %d %d (%d)\n",im->width(),im->height(),size);  }
105  CONDITION(datap,"malloc error for trans_image::data");
106 
107  for (y=0;y<hh;y++)  // now actually make the runs
108  {
109    sl=im->scan_line(y);
110    x=0;   
111    while (x<ww)
112    {     
113      *datap=0;  // start the skip at 0       
114      while (x<im->width() && (*sl)==0)
115      { sl++; x++; (*datap)++; }     
116      datap++;     
117                                                               
118      if (x<ww)
119      {
120        marker=datap;   // let marker be the run size
121        *marker=0;
122        datap++;    // skip over this spot             
123        while (x<im->width() && (*sl)!=0)
124        {       
125          (*marker)++;   
126          (*datap)=*sl;
127          datap++;       
128          x++;
129          sl++;           
130        }       
131      }
132    }       
133  } 
134}
135
136void trans_image::put_scan_line(image *screen, int x, int y, int line)   // always transparent   
137{
138  int16_t x1,y1,x2,y2;
139  screen->get_clip(x1,y1,x2,y2);
140  if (y+line<y1 || y+line>y2 || x>x2 || x+w-1<x1)            // clipped off completely?
141    return;
142
143  uint8_t *datap=data;
144  int ix; 
145  while (line)            // skip scan line data until we get to the line of interest
146  {
147    for (ix=0;ix<w;)     
148    {     
149      ix+=*datap;        // skip blank space
150      datap++;
151      if (ix<w)         
152      {
153        int run_length=*datap;     // skip run
154        ix+=run_length;
155        datap+=run_length+1;
156      }     
157    }
158    line--;   
159    y++;   
160  }
161 
162 
163  // now slam this list of runs to the screen
164  uint8_t *screen_line=screen->scan_line(y)+x;
165   
166  for (ix=0;ix<w;)             
167  {     
168    int skip=*datap;              // how much space to skip?
169    datap++;
170    screen_line+=skip;
171    ix+=skip;   
172   
173    if (ix<w)
174    {     
175      int run_length=*datap;
176      datap++;
177
178      if (x+ix+run_length-1<x1)      // is this run clipped out totally?
179      {
180        datap+=run_length;
181        ix+=run_length;
182        screen_line+=run_length;
183      }
184      else
185      {     
186        if (x+ix<x1)                 // is the run clipped partially?
187        {       
188          int clip=(x1-(x+ix));
189          datap+=clip; 
190          run_length-=clip;
191          screen_line+=clip;
192          ix+=clip;     
193        }
194
195        if (x+ix>x2)                      // clipped totally on the right? 
196          return ;                        // we are done, return!
197        else if (x+ix+run_length-1>x2)    // partially clipped?
198        {
199          memcpy(screen_line,datap,(x+ix+run_length-1)-x2);   // slam what we can
200          return ;    // and return 'cause we are done with the line
201        } else
202        {
203          memcpy(screen_line,datap,run_length);
204          screen_line+=run_length;
205          datap+=run_length;
206          ix+=run_length;           
207        }     
208      }   
209    }
210  }
211
212}
213
214
215inline uint8_t *trans_image::clip_y(image *screen, int x1, int y1, int x2, int y2,
216                                   int x, int &y, int &ysteps)
217{
218  // check to see if it is total clipped out first
219  if (y+h<=y1 || y>y2 || x>x2 || x+w<=x1)
220    return NULL;
221
222  register uint8_t *datap=data; 
223
224
225  ysteps=height();
226 
227  if (y<y1)  // check to see if the image gets clipped at the top
228  {
229
230
231    // because data is stored in runs, we need to skip over the top clipped portion
232    int skips=(y1-y);     // how many lines do we need to skip?   
233    ysteps-=skips;        // reduce h (number of lines to draw)
234    y=y1;                // start drawing here now
235    while (skips--)
236    {     
237      register int ix=0;
238      while (ix<w)
239      {
240        ix+=(*datap);       // skip over empty space
241        datap++;
242        if (ix<w)                 
243        { ix+=*datap;         
244          datap+=(*datap)+1;   // skip over data
245        }       
246      }     
247    }
248  }
249 
250  if (y+ysteps>y2)  // check to see if it gets clipped at the bottom
251    ysteps-=(y+ysteps-y2-1);
252
253  screen->add_dirty(max(x,x1),y,min(x+width()-1,x2),y+h-1); 
254  return datap;
255}
256
257void trans_image::put_image_filled(image *screen, int x, int y,
258                                   uint8_t fill_color)
259{
260 int16_t x1,y1,x2,y2;
261  int chop_length,ysteps;
262
263  screen->get_clip(x1,y1,x2,y2);
264  register uint8_t *datap=clip_y(screen,x1,y1,x2,y2,x,y,ysteps),*screen_line;
265  if (!datap) return ;     // if clip_y says nothing to draw, return
266 
267  screen_line=screen->scan_line(y)+x; 
268  int sw=screen->width()-w;
269  x1-=x; x2-=x;
270  for (;ysteps>0;ysteps--)
271  {         
272    register int ix,slam_length;
273    for (ix=0;ix<w;)
274    {
275      int blank=(*datap);
276      memset(screen_line,fill_color,blank);
277      ix+=blank;       // skip over empty space
278      screen_line+=blank;
279     
280      datap++;
281      if (ix<w)           
282      {
283        slam_length=*datap;     // find the length of this run   
284        datap++;         
285        if (ix+slam_length<x1 || ix>x2)  // see if this run is totally clipped
286        {
287          datap+=slam_length;
288          ix+=slam_length;
289          screen_line+=slam_length;
290        }
291        else
292        {                   
293          if (ix<x1)                // the left side needs to be chopped ?
294          {                   
295            chop_length=(x1-ix);
296           
297            if (chop_length>=slam_length)  // see if we chopped it all off
298            {                              // yes, we did
299              ix+=slam_length;             // advance everything to the end of run
300              screen_line+=slam_length;
301              datap+=slam_length;             
302              slam_length=0;           
303            } else
304            {       
305              slam_length-=chop_length;   // else advance everything to begining of slam 
306              ix+=chop_length;
307              screen_line+=chop_length;
308              datap+=chop_length;           
309            }       
310          }               
311
312          if (slam_length)   // see if there is anything left to slam
313          {
314            if (ix+slam_length>x2) // see if right side needs to be chopped off
315              memcpy(screen_line,datap,x2-ix+1);
316            else
317              memcpy(screen_line,datap,slam_length);
318            datap+=slam_length;
319            ix+=slam_length;       
320            screen_line+=slam_length;
321          }                   
322        }
323      }     
324    }
325    screen_line+=sw;
326  }   
327}
328
329void trans_image::put_image_offseted(image *screen, uint8_t *s_off)   // if screen x & y offset already calculated save a mul
330{
331  int ix,ysteps=height();
332  int screen_skip=screen->width()-w;
333  uint8_t skip,*datap=data;
334  for (;ysteps;ysteps--)
335  {
336    for (ix=0;ix<w;)
337    {
338      skip=*datap;       // skip leading blank space
339      datap++;
340      ix+=skip;
341      s_off+=skip;
342
343      if (s_off<screen->scan_line(0))
344        printf("bad write");
345
346
347      if (ix<w)
348      {
349        skip=*datap;
350        datap++;
351        memcpy(s_off,datap,skip);
352        datap+=skip;
353        s_off+=skip;
354        ix+=skip;
355
356        if (s_off>=screen->scan_line(screen->height()+1))
357          printf("bad write");
358      }
359    }
360    s_off+=screen_skip;
361  }
362}
363
364void trans_image::put_image(image *screen, int x, int y)
365{
366  int16_t x1,y1,x2,y2;
367  int chop_length,ysteps;
368
369  screen->get_clip(x1,y1,x2,y2);
370  register uint8_t *datap=clip_y(screen,x1,y1,x2,y2,x,y,ysteps),*screen_line;
371  if (!datap) return ;     // if clip_y says nothing to draw, return
372 
373  screen_line=screen->scan_line(y)+x; 
374  int sw=screen->width();
375  x1-=x; x2-=x;
376  for (;ysteps>0;ysteps--)
377  {         
378    register int ix,slam_length;
379    for (ix=0;ix<w;)
380    {
381      ix+=(*datap);       // skip over empty space
382      datap++;
383      if (ix<w)           
384      {
385        slam_length=*datap;     // find the length of this run   
386        datap++;         
387        if (ix+slam_length<x1 || ix>x2)  // see if this run is totally clipped
388        {
389          datap+=slam_length;
390          ix+=slam_length;         
391        }
392        else
393        {                   
394          if (ix<x1)                // the left side needs to be chopped ?
395          {                   
396            chop_length=(x1-ix);
397           
398            if (chop_length>=slam_length)  // see if we chopped it all off
399            {                              // yes, we did
400              ix+=slam_length;             // advance everything to the end of run
401              datap+=slam_length;             
402              slam_length=0;           
403            } else
404            {       
405              slam_length-=chop_length;   // else advance everything to begining of slam 
406              ix+=chop_length;
407              datap+=chop_length;           
408            }       
409          }               
410
411          if (slam_length)   // see if there is anything left to slam
412          {
413            if (ix+slam_length>x2) // see if right side needs to be chopped off
414              memcpy(screen_line+ix,datap,x2-ix+1);
415            else
416              memcpy(screen_line+ix,datap,slam_length);
417            datap+=slam_length;
418            ix+=slam_length;       
419          }                   
420        }
421      }     
422    }
423    screen_line+=sw;
424  }   
425}
426
427void trans_image::put_remaped(image *screen, int x, int y, uint8_t *remap)
428{
429  int16_t x1,y1,x2,y2;
430  int chop_length,ysteps;
431
432  screen->get_clip(x1,y1,x2,y2);
433  register uint8_t *datap=clip_y(screen,x1,y1,x2,y2,x,y,ysteps),*screen_line;
434  if (!datap) return ;     // if clip_y says nothing to draw, return
435 
436  screen_line=screen->scan_line(y)+x; 
437  int sw=screen->width();
438  x1-=x; x2-=x;
439  for (;ysteps>0;ysteps--)
440  {         
441    register int ix,slam_length;
442    for (ix=0;ix<w;)
443    {
444      ix+=(*datap);       // skip over empty space
445      datap++;
446      if (ix<w)           
447      {
448        slam_length=*datap;     // find the length of this run   
449        datap++;         
450        if (ix+slam_length<x1 || ix>x2)  // see if this run is totally clipped
451        {
452          datap+=slam_length;
453          ix+=slam_length;         
454        }
455        else
456        {                   
457          if (ix<x1)                // the left side needs to be chopped ?
458          {                   
459            chop_length=(x1-ix);
460           
461            if (chop_length>=slam_length)  // see if we chopped it all off
462            {                              // yes, we did
463              ix+=slam_length;             // advance everything to the end of run
464              datap+=slam_length;             
465              slam_length=0;           
466            } else
467            {       
468              slam_length-=chop_length;   // else advance everything to begining of slam 
469              ix+=chop_length;
470              datap+=chop_length;           
471            }       
472          }               
473
474
475          if (slam_length)   // see if there is anything left to slam
476          {
477            register int counter;
478            if (ix+slam_length>x2) // see if right side needs to be chopped off     
479              counter=x2-ix+1;
480            else
481              counter=slam_length;
482
483            register uint8_t *sl=screen_line+ix,*sl2=datap;
484            ix+=slam_length;       
485            datap+=slam_length;
486            while (counter)
487            {
488              counter--;
489              *(sl)=remap[*(sl2)];
490              sl++;
491              sl2++;
492            }
493          }                   
494        }
495      }     
496    }
497    screen_line+=sw;
498  }   
499}
500
501
502
503void trans_image::put_double_remaped(image *screen, int x, int y, uint8_t *remap, uint8_t *remap2)
504{
505  int16_t x1,y1,x2,y2;
506  int chop_length,ysteps;
507
508  screen->get_clip(x1,y1,x2,y2);
509  register uint8_t *datap=clip_y(screen,x1,y1,x2,y2,x,y,ysteps),*screen_line;
510  if (!datap) return ;     // if clip_y says nothing to draw, return
511 
512  screen_line=screen->scan_line(y)+x; 
513  int sw=screen->width();
514  x1-=x; x2-=x;
515  for (;ysteps>0;ysteps--)
516  {         
517    register int ix,slam_length;
518    for (ix=0;ix<w;)
519    {
520      ix+=(*datap);       // skip over empty space
521      datap++;
522      if (ix<w)           
523      {
524        slam_length=*datap;     // find the length of this run   
525        datap++;         
526        if (ix+slam_length<x1 || ix>x2)  // see if this run is totally clipped
527        {
528          datap+=slam_length;
529          ix+=slam_length;         
530        }
531        else
532        {                   
533          if (ix<x1)                // the left side needs to be chopped ?
534          {                   
535            chop_length=(x1-ix);
536           
537            if (chop_length>=slam_length)  // see if we chopped it all off
538            {                              // yes, we did
539              ix+=slam_length;             // advance everything to the end of run
540              datap+=slam_length;             
541              slam_length=0;           
542            } else
543            {       
544              slam_length-=chop_length;   // else advance everything to begining of slam 
545              ix+=chop_length;
546              datap+=chop_length;           
547            }       
548          }               
549
550
551          if (slam_length)   // see if there is anything left to slam
552          {
553            register int counter;
554            if (ix+slam_length>x2) // see if right side needs to be chopped off     
555              counter=x2-ix+1;
556            else
557              counter=slam_length;
558
559            register uint8_t *sl=screen_line+ix,*sl2=datap;
560            ix+=slam_length;       
561            datap+=slam_length;
562            while (counter)
563            {
564              counter--;
565              *(sl)=remap2[remap[*(sl2)]];
566              sl++;
567              sl2++;
568            }
569          }                   
570        }
571      }     
572    }
573    screen_line+=sw;
574  }   
575}
576
577
578
579void trans_image::put_fade(image *screen, int x, int y,
580                           int frame_on, int total_frames,
581                           color_filter *f, palette *pal)
582{
583  int16_t x1,y1,x2,y2;
584  int ix,slam_length,chop_length,ysteps;
585
586  screen->get_clip(x1,y1,x2,y2);
587  uint8_t *datap=clip_y(screen,x1,y1,x2,y2,x,y,ysteps),
588                *screen_line;
589  if (!datap) return ;
590
591  uint8_t *screen_run,*paddr=(uint8_t *)pal->addr(),
592                *caddr1,*caddr2,r_dest,g_dest,b_dest;
593
594  long fixmul=(frame_on<<16)/total_frames;
595  for (;ysteps>0;ysteps--,y++)
596  {         
597    screen_line=screen->scan_line(y);
598     
599    for (ix=0;ix<w;)
600    {
601      ix+=(*datap);       // skip over empty space
602      datap++;
603      if (ix<w)           
604      {
605        slam_length=*datap;     // find the length of this run   
606        datap++;         
607        if (x+ix+slam_length<x1 || x+ix>x2)  // see if this run is totally clipped
608        {
609          datap+=slam_length;
610          ix+=slam_length;         
611        }
612        else
613        {                   
614          if (x+ix<x1)                // the left side needs to be chopped ?
615          {                   
616            chop_length=(x1-x-ix);
617           
618            if (chop_length>=slam_length)  // see if we chopped it all off
619            {                              // yes, we did
620              ix+=slam_length;             // advance everything to the end of run
621              datap+=slam_length;             
622              slam_length=0;           
623            } else
624            {       
625              slam_length-=chop_length;   // else advance everything to begining of slam 
626              ix+=chop_length;
627              datap+=chop_length;           
628            }       
629          }               
630
631          if (slam_length)   // see if there is anything left to slam
632          {
633            if (x+ix+slam_length>x2) // see if right side needs to be chopped off
634              chop_length=x2-x-ix;
635            else 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}
666
667
668
669
670void trans_image::put_fade_tint(image *screen, int x, int y,
671                                int frame_on, int total_frames,
672                                uint8_t *tint,
673                                color_filter *f, palette *pal)
674{
675  int16_t x1,y1,x2,y2;
676  int ix,slam_length,chop_length,ysteps;
677
678  screen->get_clip(x1,y1,x2,y2);
679  uint8_t *datap=clip_y(screen,x1,y1,x2,y2,x,y,ysteps),
680                *screen_line;
681  if (!datap) return ;
682
683  uint8_t *screen_run,*paddr=(uint8_t *)pal->addr(),
684                *caddr1,*caddr2,r_dest,g_dest,b_dest;
685
686  long fixmul=(frame_on<<16)/total_frames;
687  for (;ysteps>0;ysteps--,y++)
688  {         
689    screen_line=screen->scan_line(y);
690     
691    for (ix=0;ix<w;)
692    {
693      ix+=(*datap);       // skip over empty space
694      datap++;
695      if (ix<w)           
696      {
697        slam_length=*datap;     // find the length of this run   
698        datap++;         
699        if (x+ix+slam_length<x1 || x+ix>x2)  // see if this run is totally clipped
700        {
701          datap+=slam_length;
702          ix+=slam_length;         
703        }
704        else
705        {                   
706          if (x+ix<x1)                // the left side needs to be chopped ?
707          {                   
708            chop_length=(x1-x-ix);
709           
710            if (chop_length>=slam_length)  // see if we chopped it all off
711            {                              // yes, we did
712              ix+=slam_length;             // advance everything to the end of run
713              datap+=slam_length;             
714              slam_length=0;           
715            } else
716            {       
717              slam_length-=chop_length;   // else advance everything to begining of slam 
718              ix+=chop_length;
719              datap+=chop_length;           
720            }       
721          }               
722
723          if (slam_length)   // see if there is anything left to slam
724          {
725            if (x+ix+slam_length>x2) // see if right side needs to be chopped off
726              chop_length=x2-x-ix;
727            else chop_length=slam_length;
728            screen_run=screen_line+x+ix;
729             
730            slam_length-=chop_length;
731            ix+=chop_length;
732             
733            while (chop_length--)
734            {
735              caddr1=paddr+(int)(*screen_run)*3;
736              caddr2=paddr+(int)(tint[*datap])*3;
737             
738              r_dest=((((int)(*caddr1)-(int)(*caddr2))*fixmul)>>16)+(int)(*caddr2);
739              caddr1++; caddr2++;
740
741              g_dest=((((int)(*caddr1)-(int)(*caddr2))*fixmul)>>16)+(int)(*caddr2);
742              caddr1++; caddr2++;
743
744              b_dest=((((int)(*caddr1)-(int)(*caddr2))*fixmul)>>16)+(int)(*caddr2);
745              *screen_run=f->lookup_color(r_dest>>3,g_dest>>3,b_dest>>3);
746
747              screen_run++;
748              datap++;         
749            }
750            datap+=slam_length;
751            ix+=slam_length;       
752          }                   
753        }
754      }     
755    }     
756  }   
757}
758
759
760
761
762
763
764void trans_image::put_color(image *screen, int x, int y, int color)
765{
766  int16_t x1,y1,x2,y2;
767  int ix,slam_length,chop_length,ysteps;
768 
769  screen->get_clip(x1,y1,x2,y2);
770  uint8_t *datap=clip_y(screen,x1,y1,x2,y2,x,y,ysteps),
771                *screen_line;
772  if (!datap) return ;
773 
774 
775  for (;ysteps>0;ysteps--,y++)
776  {         
777    screen_line=screen->scan_line(y);
778     
779    for (ix=0;ix<w;)
780    {
781      ix+=(*datap);       // skip over empty space
782      datap++;
783      if (ix<w)           
784      {
785        slam_length=*datap;     // find the length of this run   
786        datap++;         
787        if (x+ix+slam_length<x1 || x+ix>x2)  // see if this run is totally clipped
788        {
789          datap+=slam_length;
790          ix+=slam_length;         
791        }
792        else
793        {                   
794          if (x+ix<x1)                // the left side needs to be chopped ?
795          {                   
796            chop_length=(x1-x-ix);
797           
798            if (chop_length>=slam_length)  // see if we chopped it all off
799            {                              // yes, we did
800              ix+=slam_length;             // advance everything to the end of run
801              datap+=slam_length;             
802              slam_length=0;           
803            } else
804            {       
805              slam_length-=chop_length;   // else advance everything to begining of slam 
806              ix+=chop_length;
807              datap+=chop_length;           
808            }       
809          }               
810
811          if (slam_length)   // see if there is anything left to slam
812          {
813            if (x+ix+slam_length>x2) // see if right side needs to be chopped off
814              memset(screen_line+x+ix,color,x2-x-ix+1);
815            else
816              memset(screen_line+x+ix,color,slam_length);
817            datap+=slam_length;
818            ix+=slam_length;       
819          }     
820        }
821      }     
822    }     
823  }   
824}
825
826
827// ASSUMES that the blend image completly covers this image
828void trans_image::put_blend16(image *screen, image *blend, int x, int y,
829                   int blendx, int blendy, int blend_amount, color_filter *f, palette *pal)
830
831{
832  int16_t x1,y1,x2,y2;
833  int ix,slam_length,chop_length,ysteps;
834  uint8_t *paddr=(uint8_t *)pal->addr(); 
835 
836  screen->get_clip(x1,y1,x2,y2);
837  uint8_t *datap=clip_y(screen,x1,y1,x2,y2,x,y,ysteps),
838                *blend_line,*screen_line;
839  if (!datap) return ;
840  CONDITION(y>=blendy && y+ysteps<blendy+blend->height()+1,"Blend doesn't fit on trans_image");
841 
842  blend_amount=16-blend_amount;
843 
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<w;)
851    {
852      ix+=(*datap);       // skip over empty space
853      datap++;
854      if (ix<w)           
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-x-ix;
887            else chop_length=slam_length;
888
889            uint8_t *screen_run=screen_line+x+ix,
890                          *blend_run=blend_line+x+ix-blendx,
891                          *caddr1,*caddr2,r_dest,g_dest,b_dest;     
892             
893            slam_length-=chop_length;
894            ix+=chop_length;   
895
896
897            while (chop_length--)
898            {
899              caddr1=paddr+(int)(*blend_run)*3;
900              caddr2=paddr+(int)(*datap)*3;
901             
902              r_dest=((int)(*caddr1)-(int)(*caddr2))*blend_amount/16+(int)(*caddr2);
903              caddr1++; caddr2++;
904
905              g_dest=((int)(*caddr1)-(int)(*caddr2))*blend_amount/16+(int)(*caddr2);
906              caddr1++; caddr2++;
907
908              b_dest=((int)(*caddr1)-(int)(*caddr2))*blend_amount/16+(int)(*caddr2);
909
910              *screen_run=f->lookup_color(r_dest>>3,g_dest>>3,b_dest>>3);
911
912             
913              screen_run++;
914              blend_run++;
915              datap++;         
916            }
917            datap+=slam_length;
918            ix+=slam_length;       
919          }                 
920
921        }
922      }     
923    }     
924  }   
925
926
927}
928
929void trans_image::put_predator(image *screen, int x, int y)
930{
931  int16_t x1,y1,x2,y2;
932  int chop_length,ysteps;
933
934  screen->get_clip(x1,y1,x2,y2);
935  register uint8_t *datap=clip_y(screen,x1,y1,x2,y2,x,y,ysteps),*screen_line;
936  if (!datap) return ;     // if clip_y says nothing to draw, return
937
938  // see if the last scanline is clipped off
939  if (y+ysteps==y2) ysteps-=2;
940  else if (y+ysteps==y2-1) ysteps--;
941/*  {
942    for (int x=0;x<w;)
943    {
944      int skip=*datap; datap++;
945      x+=skip;
946      if (x<w)
947      {
948        int run_size=*datap;
949        datap+=run_size+1;
950        x+=run_size;
951      }
952    }
953    if (y==y2)
954      return;
955    else
956      y++;   
957  }*/
958 
959  screen_line=screen->scan_line(y)+x; 
960  int sw=screen->width();
961  x1-=x; x2-=x;
962  for (;ysteps>0;ysteps--)
963  {         
964    register int ix,slam_length;
965    for (ix=0;ix<w;)
966    {
967      ix+=(*datap);       // skip over empty space
968      datap++;
969      if (ix<w)           
970      {
971        slam_length=*datap;     // find the length of this run   
972        datap++;         
973        if (ix+slam_length<x1 || ix>x2)  // see if this run is totally clipped
974        {
975          datap+=slam_length;
976          ix+=slam_length;         
977        }
978        else
979        {                   
980          if (ix<x1)                // the left side needs to be chopped ?
981          {                   
982            chop_length=(x1-ix);
983           
984            if (chop_length>=slam_length)  // see if we chopped it all off
985            {                              // yes, we did
986              ix+=slam_length;             // advance everything to the end of run
987              datap+=slam_length;             
988              slam_length=0;           
989            } else
990            {       
991              slam_length-=chop_length;   // else advance everything to begining of slam 
992              ix+=chop_length;
993              datap+=chop_length;           
994            }       
995          }               
996
997          if (slam_length)   // see if there is anything left to slam
998          {
999            if (ix+slam_length>x2) // see if right side needs to be chopped off
1000              memcpy(screen_line+ix,screen_line+sw+sw+ix,x2-ix+1);
1001            else
1002              memcpy(screen_line+ix,screen_line+sw+sw+ix,slam_length);
1003            datap+=slam_length;
1004            ix+=slam_length;       
1005          }                   
1006        }
1007      }     
1008    }
1009    screen_line+=sw;
1010  }   
1011}
1012
1013int trans_image::size()
1014{
1015  uint8_t *d=data;
1016  int t=0;
1017  for (int y=0;y<h;y++)
1018  {
1019    int x=0;
1020    while (x<w)
1021    {
1022      x+=*d; d++; t++;
1023      if (x<w)
1024      {
1025        int s=*d; d++; t+=s+1;
1026        d+=s;
1027        x+=s;
1028      }     
1029    }
1030  }
1031  return t+4+4;
1032}
Note: See TracBrowser for help on using the repository browser.