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

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

style: remove trailing spaces, fix copyright statements.

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