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

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

Fuck the history, I'm renaming all .hpp files to .h for my own sanity.

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