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

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