source: abuse/trunk/src/imlib/filter.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: 5.2 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 "image.h"
13#include "macs.h"
14#include "filter.h"
15
16extern unsigned char current_background;
17
18filter::filter(palette *from, palette *to)   // creates a conversion filter from one palette to another
19{
20  nc=from->pal_size() > to->pal_size() ? from->pal_size() : to->pal_size();
21  unsigned char *p=fdat=(unsigned char *)malloc(nc);
22  unsigned char *r,*g,*b;
23  r=g=b=(unsigned char *)from->addr();
24  g++;
25  b+=2;
26
27  int dk=to->darkest(1);
28  for (int i=0;i<nc;i++,p++,r+=3,g+=3,b+=3)
29  {
30    *p=to->find_closest(*r,*g,*b);
31
32    // make sure non-blacks don't get remapped to the transparency
33    if ((*r!=0 || *g!=0 || *b!=0) && (to->red(*p)==0 && to->green(*p)==0 && to->blue(*p)==0))
34      *p=dk;
35  }
36
37}
38
39void filter::clear()
40{
41  int i;
42  for (i=0;i<nc;i++)
43    fdat[i]=i;
44}
45
46void filter::max_threshold(int minv, char blank)
47{
48  int i;
49  CONDITION(minv>=0 && minv<nc,"Bad minv");
50  for (i=0;i<minv;i++)
51    fdat[i]=blank;
52}
53
54void filter::min_threshold(int maxv, char blank)
55{
56  int i;
57  CONDITION(maxv>=0 && maxv<nc,"bad maxv value in filter::max_thresh");
58  for (i=nc-1;i>=maxv;i--)
59    fdat[i]=(unsigned) blank;
60}
61
62
63void filter::set(int color_num, char change_to)
64{
65  CONDITION(color_num>=0 && color_num<nc,"Bad colors_num");
66  fdat[color_num]=(unsigned) change_to;
67}
68
69
70filter::filter(int colors)
71{
72  CONDITION(colors>=0 && colors<=256,"bad colors value");
73  nc=colors;
74  make_block(nc);
75  fdat=(unsigned char *)malloc(nc);
76  clear();
77}
78
79void filter::apply(image *im)
80{
81  int x,y;
82  unsigned char *c;
83  CONDITION(im,"null image passed in filter::apply\n");
84  im->lock();
85  for (y=im->height()-1;y>=0;y--)
86  {
87    c=im->scan_line(y);
88    for (x=im->width()-1;x>=0;x--)
89    {
90      CONDITION((unsigned) c[x]<nc,"not enough filter colors");
91      c[x]=fdat[(unsigned) c[x]];
92    }
93  }
94  im->unlock();
95}
96
97
98palette *compare_pal;
99
100int color_compare(void *c1, void *c2)
101{
102  long v1,v2;
103  unsigned char r1,g1,b1,r2,g2,b2;
104  compare_pal->get(  *((unsigned char *)c1),r1,g1,b1);
105  compare_pal->get(  *((unsigned char *)c2),r2,g2,b2);
106  v1=(int)r1*(int)r1+(int)g1*(int)g1+(int)b1*(int)b1;
107  v2=(int)r2*(int)r2+(int)g2*(int)g2+(int)b2*(int)b2;
108  if (v1<v2) return -1;
109  else if (v1>v2) return 1;
110  else return 0;
111}
112
113color_filter::color_filter(palette *pal, int color_bits, void (*stat_fun)(int))
114{
115  color_bits=5;      // hard code 5 for now
116  int r,g,b,rv,gv,bv,
117      c=0,i,max=pal->pal_size(),
118      lshift=8-color_bits;
119  unsigned char *pp;
120
121  long dist_sqr,best;
122  int colors=1<<color_bits;
123  color_table=(unsigned char *)malloc(colors*colors*colors);
124  for (r=0;r<colors;r++)
125  {
126    if (stat_fun) stat_fun(r);
127    rv=r<<lshift;
128    for (g=0;g<colors;g++)
129    {
130      gv=g<<lshift;
131      for (b=0;b<colors;b++)
132      {
133    bv=b<<lshift;
134        best=0x7fffffff;
135        for (i=0,pp=(unsigned char *)pal->addr();i<max;i++)
136        {
137          register long rd=*(pp++)-rv,
138                        gd=*(pp++)-gv,
139                        bd=*(pp++)-bv;
140   
141          dist_sqr=(long)rd*rd+(long)bd*bd+(long)gd*gd;
142          if (dist_sqr<best)
143          { best=dist_sqr;
144            c=i;
145          }
146        }
147        color_table[r*colors*colors+g*colors+b]=c;
148      }
149    }
150  }
151}
152
153color_filter::color_filter(spec_entry *e, bFILE *fp)
154{
155  fp->seek(e->offset,0);
156  fp->read_uint16();
157  int colors=32;
158  color_table=(unsigned char *)malloc(colors*colors*colors);
159  fp->read(color_table,colors*colors*colors);
160}
161
162int color_filter::size()
163{
164  int colors=32;
165  return 2+colors*colors*colors;
166}
167
168int color_filter::write(bFILE *fp)
169{
170  int colors=32;
171  fp->write_uint16(colors);
172  return fp->write(color_table,colors*colors*colors)==colors*colors*colors;
173}
174
175
176void filter::put_image(image *screen, image *im, short x, short y,
177                       char transparent)
178{
179    short cx1, cy1, cx2, cy2, x1 = 0, y1 = 0,
180          x2 = im->width() - 1, y2 = im->height() - 1;
181    screen->get_clip(cx1,cy1,cx2,cy2);
182
183    // see if the image gets clipped off the screen
184    if(x > cx2 || y > cy2 || x + (x2 - x1) < cx1 || y + (y2 - y1) < cy1)
185        return;
186
187    if(x < cx1)
188    {
189        x1 += (cx1 - x);
190        x = cx1;
191    }
192    if(y < cy1)
193    {
194        y1 += (cy1 - y);
195         y = cy1;
196    }
197
198    if(x + x2 - x1 + 1 > cx2)
199        x2 = cx2 - x + x1;
200
201    if(y + y2 - y1 + 1 > cy2)
202        y2 = cy2 - y + y1;
203
204    if(x1 > x2 || y1 > y2)
205        return;
206
207    int xl = x2 - x1 + 1;
208    int yl = y2 - y1 + 1;
209
210    screen->add_dirty(x, y, x + xl - 1, y + yl - 1);
211
212    screen->lock();
213    im->lock();
214
215    uint8_t *pg1 = screen->scan_line(y), *source, *dest;
216    uint8_t *pg2 = im->scan_line(y1);
217    int i;
218    for(int j = 0; j < yl; j++)
219    {
220        for(i = 0, source = &pg2[x1], dest = &pg1[x];
221            i < xl;
222            i++, source++, dest++)   
223        {
224            if(!transparent || *source != current_background)
225                *dest=fdat[*source];
226        }
227        pg1 = screen->next_line(y + j, pg1);
228        pg2 = im->next_line(y1 + j, pg2);
229    }
230
231    im->unlock();
232    screen->unlock();
233}
234
Note: See TracBrowser for help on using the repository browser.