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

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