source: abuse/trunk/src/imlib/texture.cpp @ 90

Last change on this file since 90 was 66, checked in by Sam Hocevar, 12 years ago
  • Added the proper .h and .hpp files to _SOURCES variables. As a result, "make dist" now generates a buildable tarball.
File size: 9.6 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 <math.h>
13
14#include "image.hpp"
15#include "video.hpp"
16#include "macs.hpp"
17#include "event.hpp"
18#include "texture.hpp"
19
20#define SHB 7
21
22class vect
23{
24public :
25  long screenx, screeny, screendx, screendy,
26       imagex,  imagey,  imagedx,  imagedy;
27  short steps;
28  void init(short imagex1,  short imagey1,  short imagex2, short imagey2,
29       short screenx1, short screeny1, short screenx2, short screeny2);
30  short step();
31} ;
32
33inline short vect::step()
34{
35  long oy;
36  do
37  {
38    oy=screeny>>SHB;
39    screenx+=screendx;
40    screeny+=screendy;
41    imagex+=imagedx;
42    imagey+=imagedy;
43    steps--;
44  } while (steps && (screeny>>SHB)==oy);
45  return steps>=0;
46}
47
48void vect::init(short imagex1,  short imagey1,  short imagex2, short imagey2,
49           short screenx1, short screeny1, short screenx2, short screeny2)
50{
51  steps=abs(screeny1-screeny2)+1;
52  screenx=(long)screenx1<<SHB;
53  screeny=(long)screeny1<<SHB;
54  if (screenx2>=screenx1)
55    screendx=((long)(screenx2-screenx1+1)<<(SHB*2))/((long)(steps<<SHB));
56  else screendx=((long)(screenx2-screenx1-1)<<(SHB*2))/((long)(steps<<SHB));
57  if (screeny2>=screeny1)
58    screendy=((long)(screeny2-screeny1+1)<<(SHB*2))/((long)(steps<<SHB));
59  else
60    screendy=((long)(screeny2-screeny1-1)<<(SHB*2))/((long)(steps<<SHB));
61  imagex =(long)imagex1<<SHB;
62  imagey =(long)imagey1<<SHB;
63  if (imagex2>=imagex1)
64    imagedx=((long)(imagex2-imagex1)<<(SHB*2))/((long)(steps<<SHB));
65  else
66    imagedx=((long)(imagex2-imagex1)<<(SHB*2))/((long)(steps<<SHB));
67  if (imagey2>=imagey1)
68    imagedy=((long)(imagey2-imagey1)<<(SHB*2))/((long)(steps<<SHB));
69  else
70    imagedy=((long)(imagey2-imagey1)<<(SHB*2))/((long)(steps<<SHB));
71}
72
73
74void texture_map(image *screen, image *tx, short *points)
75{
76  vect right[2],left[2];
77  unsigned char *sl;
78  short l=0,r=0,y,sa,min,max,i,x1,x2,screeny;
79  short cx1,cy1,cx2,cy2;
80  long ix,iy,idx,idy,steps,scx;
81  screen->get_clip(cx1,cy1,cx2,cy2);
82  x1=0;
83  x2=0;
84  for (i=1;i<4;i++)
85    if (points[i*2]<points[x1*2])
86      x1=i;
87    else if (points[i*2]>points[x2*2])
88      x2=i;
89  min=0;
90  max=0;
91  for (i=1;i<4;i++)
92    if (points[i*2+1]<points[min*2+1])
93      min=i;
94    else if (points[i*2+1]>points[max*2+1])
95      max=i;
96
97  if (min==0)
98  {
99    right[0].init(0,0,tx->width()-1,0,                         points[0],points[1],points[2],points[3]);
100    right[1].init(tx->width()-1,0,tx->width()-1,tx->height()-1,points[2],points[3],points[4],points[5]);
101    left[0].init(0,0,0,tx->height()-1,                         points[0],points[1],points[6],points[7]);
102    left[1].init(0,tx->height()-1,tx->width()-1,tx->height()-1,points[6],points[7],points[4],points[5]);
103  }
104  else if (min==1)
105  {
106    right[0].init(tx->width()-1,0,tx->width()-1,tx->height()-1, points[2],points[3],points[4],points[5]);
107    right[1].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
108    left[0].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
109    left[1].init(0,0,0,tx->height()-1,                          points[0],points[1],points[6],points[7]);
110  } else if (min==2)
111  {
112    right[0].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
113    right[1].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
114
115    left[0].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
116    left[1].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
117  } else
118  {
119    right[0].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
120    right[1].init(0,0,tx->width()-1,0,                          points[0],points[1],points[2],points[3]);
121
122    left[0].init(0,tx->height()-1,tx->width()-1,tx->height()-1, points[6],points[7],points[4],points[5]);
123    left[1].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
124  }
125
126
127  do
128  {
129    screeny=right[r].screeny>>SHB;
130    if (screeny>=cy1 && screeny<=cy2)
131    {
132      sl=screen->scan_line(screeny);
133      ix=left[l].imagex;
134      iy=left[l].imagey;
135
136      if (left[l].screenx<right[r].screenx)
137      { sa=1; steps=right[r].screenx-left[l].screenx; }
138      else { sa=-1; steps=left[l].screenx-right[r].screenx; }
139      steps+=1<<SHB;
140      if (right[r].imagex>ix)
141        idx=((right[r].imagex-ix)<<SHB)/steps;
142      else idx=((right[r].imagex-ix)<<SHB)/steps;
143
144      if (right[r].imagey>iy)
145        idy=((right[r].imagey-iy)<<SHB)/steps;
146      else idy=((right[r].imagey-iy)<<SHB)/steps;
147      scx=left[l].screenx>>SHB;
148
149      steps=steps>>SHB;
150      if (left[l].screenx<right[r].screenx)
151        sa=1; else sa=-1;
152      while (steps--)
153      {
154        if (scx>=cx1 && scx<=cx2)
155          sl[scx]=tx->scan_line(iy>>SHB)[ix>>SHB];
156        ix+=idx; iy+=idy;
157        scx+=sa;
158      }
159    }
160
161    do
162    { y=right[r].screeny>>SHB;
163      if (!right[r].step())
164        r++;
165    } while (r!=2 && y==right[r].screeny>>SHB);
166
167    do
168    { y=left[l].screeny>>SHB;
169      if (!left[l].step())
170        l++;
171    } while (l!=2 && y==left[l].screeny>>SHB);
172
173  } while (r!=2 && l!=2);
174
175}
176
177
178// slower, but allows transparency textures
179void clear_texture_map(image *screen, image *tx, short *points)
180{
181  vect right[3],left[3];
182  unsigned char *sl;
183  short l=0,r=0,y,sa,min,max,i,x1,x2,screeny;
184  short cx1,cy1,cx2,cy2;
185  long ix,iy,idx,idy,steps,scx;
186  screen->get_clip(cx1,cy1,cx2,cy2);
187  x1=0;
188  x2=0;
189  for (i=1;i<4;i++)
190    if (points[i*2]<points[x1*2])
191      x1=i;
192    else if (points[i*2]>points[x2*2])
193      x2=i;
194  min=0;
195  max=0;
196  for (i=1;i<4;i++)
197    if (points[i*2+1]<points[min*2+1])
198      min=i;
199    else if (points[i*2+1]>points[max*2+1])
200      max=i;
201
202
203
204  if (min==0)
205  {
206    right[0].init(0,0,tx->width()-1,0,                         points[0],points[1],points[2],points[3]);
207    right[1].init(tx->width()-1,0,tx->width()-1,tx->height()-1,points[2],points[3],points[4],points[5]);
208    right[2].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
209
210    left[0].init(0,0,0,tx->height()-1,                         points[0],points[1],points[6],points[7]);
211    left[1].init(0,tx->height()-1,tx->width()-1,tx->height()-1,points[6],points[7],points[4],points[5]);
212    left[2].init(tx->width()-1,tx->height()-1,tx->width()-1,0, points[4],points[5],points[2],points[3]);
213  }
214  else if (min==1)
215  {
216    right[0].init(tx->width()-1,0,tx->width()-1,tx->height()-1, points[2],points[3],points[4],points[5]);
217    right[1].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
218    right[2].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
219
220    left[0].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
221    left[1].init(0,0,0,tx->height()-1,                          points[0],points[1],points[6],points[7]);
222    left[2].init(0,tx->height()-1,tx->width()-1,tx->height()-1, points[6],points[7],points[4],points[5]);
223  } else if (min==2)
224  {
225    right[0].init(tx->width()-1,tx->height()-1,0,tx->height()-1,points[4],points[5],points[6],points[7]);
226    right[1].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
227    right[2].init(0,0,tx->width()-1,0,                          points[0],points[1],points[2],points[3]);
228
229    left[0].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
230    left[1].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
231    left[2].init(0,0,0,tx->height()-1,                          points[0],points[1],points[6],points[7]);
232  } else
233  {
234    right[0].init(0,tx->height()-1,0,0,                         points[6],points[7],points[0],points[1]);
235    right[1].init(0,0,tx->width()-1,0,                          points[0],points[1],points[2],points[3]);
236    right[2].init(tx->width()-1,0,tx->width()-1,tx->height(),   points[2],points[3],points[4],points[5]);
237
238    left[0].init(0,tx->height()-1,tx->width()-1,tx->height()-1, points[6],points[7],points[4],points[5]);
239    left[1].init(tx->width()-1,tx->height()-1, tx->width()-1,0, points[4],points[5],points[2],points[3]);
240    left[2].init(tx->width()-1,0,0,0,                           points[2],points[3],points[0],points[1]);
241  }
242
243
244  do
245  {
246    screeny=right[r].screeny>>SHB;
247    if (screeny>=cy1 && screeny<=cy2)
248    {
249      sl=screen->scan_line(screeny);
250      ix=left[l].imagex;
251      iy=left[l].imagey;
252
253      if (left[l].screenx<right[r].screenx)
254      { sa=1; steps=right[r].screenx-left[l].screenx; }
255      else { sa=-1; steps=left[l].screenx-right[r].screenx; }
256      steps+=1<<SHB;
257      if (right[r].imagex>ix)
258        idx=((right[r].imagex-ix)<<SHB)/steps;
259      else idx=((right[r].imagex-ix)<<SHB)/steps;
260
261      if (right[r].imagey>iy)
262        idy=((right[r].imagey-iy)<<SHB)/steps;
263      else idy=((right[r].imagey-iy)<<SHB)/steps;
264      scx=left[l].screenx>>SHB;
265
266      steps=steps>>SHB;
267      if (left[l].screenx<right[r].screenx)
268        sa=1; else sa=-1;
269      while (steps--)
270      {
271        if (scx>=cx1 && scx<=cx2)
272        {
273          unsigned char c=tx->scan_line(iy>>SHB)[ix>>SHB];
274          if (c!=current_background)
275            sl[scx]=c;
276        }
277        ix+=idx; iy+=idy;
278        scx+=sa;
279      }
280    }
281
282    do
283    { y=right[r].screeny>>SHB;
284      if (!right[r].step())
285        r++;
286    } while (r!=2 && y==(right[r].screeny>>SHB));
287
288    do
289    { y=left[l].screeny>>SHB;
290      if (!left[l].step())
291        l++;
292    } while (l!=2 && y==(left[l].screeny>>SHB));
293
294  } while ((r!=2 || l==0) && (l!=2 || r==0));
295
296}
297
298
299
Note: See TracBrowser for help on using the repository browser.