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

Last change on this file since 521 was 521, checked in by Sam Hocevar, 12 years ago

imlib: remove unused image::make_color and timage::make_color. They were
probably used for debugging purposes, but we can still revive them when
we need them.

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