7 // Define directional 3d sprites in wl_act1.cpp (there are two examples)
8 // Make sure you have according entries in ScanInfoPlane in wl_game.cpp.
11 void Scale3DShaper(int x1
, int x2
, int shapenum
, uint32_t flags
, fixed ny1
, fixed ny2
,
12 fixed nx1
, fixed nx2
, byte
*vbuf
, unsigned vbufPitch
)
15 unsigned scale1
,starty
,endy
;
19 int dx
,len
,i
,newstart
,ycnt
,pixheight
,screndy
,upperedge
,scrstarty
;
21 fixed height
,dheight
,height1
,height2
;
22 int xpos
[TEXTURESIZE
+1];
24 fixed dxx
=(ny2
-ny1
)<<8,dzz
=(nx2
-nx1
)<<8;
28 shape
= (t_compshape
*) PM_GetSprite(shapenum
);
30 len
=shape
->rightpix
-shape
->leftpix
+1;
36 dxa
=-(dxx
>>1),dza
=-(dzz
>>1);
37 dxx
>>=TEXTURESHIFT
,dzz
>>=TEXTURESHIFT
;
38 dxa
+=shape
->leftpix
*dxx
,dza
+=shape
->leftpix
*dzz
;
40 xpos
[0]=(int)((ny1
+(dxa
>>8))*scale
/(nx1
+(dza
>>8))+centerx
);
41 height1
= heightnumerator
/((nx1
+(dza
>>8))>>8);
42 height
=(((fixed
)height1
)<<12)+2048;
47 xpos
[i
]=(int)((ny1
+(dxa
>>8))*scale
/(nx1
+(dza
>>8))+centerx
);
48 if(xpos
[i
-1]>viewwidth
) break;
51 dx
= xpos
[len
] - xpos
[0];
54 height2
= heightnumerator
/((nx1
+(dza
>>8))>>8);
55 dheight
=(((fixed
)height2
-(fixed
)height1
)<<12)/(fixed
)dx
;
57 cmdptr
= (word
*) shape
->dataofs
;
60 if(x2
>viewwidth
) x2
=viewwidth
;
64 for(slinex
=xpos
[i
];slinex
<xpos
[i
+1] && slinex
<x2
;slinex
++)
67 if(slinex
<0) continue;
69 scale1
=(unsigned)(height
>>15);
71 if(wallheight
[slinex
]<(height
>>12) && scale1
/*&& scale1<=maxscale*/)
75 if(flags
& FL_FULLBRIGHT
)
76 curshades
= shadetable
[0];
78 curshades
= shadetable
[GetShade(scale1
<<3)];
81 pixheight
=scale1
*SPRITESCALEFACTOR
;
82 upperedge
=viewheight
/2-scale1
;
84 line
=(byte
*)shape
+ cmdptr
[i
];
86 while((endy
= READWORD(line
)) != 0)
89 newstart
= READWORD(line
);
90 starty
= READWORD(line
) >> 1;
93 screndy
=(ycnt
>>6)+upperedge
;
94 if(screndy
<0) vmem
=vbuf
+slinex
;
95 else vmem
=vbuf
+screndy
*vbufPitch
+slinex
;
100 screndy
=(ycnt
>>6)+upperedge
;
101 if(scrstarty
!=screndy
&& screndy
>0)
104 col
=curshades
[((byte
*)shape
)[newstart
+j
]];
106 col
=((byte
*)shape
)[newstart
+j
];
108 if(scrstarty
<0) scrstarty
=0;
109 if(screndy
>viewheight
) screndy
=viewheight
,j
=endy
;
111 while(scrstarty
<screndy
)
125 void Scale3DShape(byte
*vbuf
, unsigned vbufPitch
, statobj_t
*ob
)
127 fixed nx1
,nx2
,ny1
,ny2
;
134 // the following values for "diradd" aren't optimized yet
135 // if you have problems with sprites being visible through wall edges
136 // where they shouldn't, you can try to adjust these values and SIZEADD
141 switch(ob
->flags
& FL_DIR_POS_MASK
)
143 case FL_DIR_POS_FW
: diradd
=0x7ff0+0x8000; break;
144 case FL_DIR_POS_BW
: diradd
=-0x7ff0+0x8000; break;
145 case FL_DIR_POS_MID
: diradd
=0x8000; break;
147 Quit("Unknown directional 3d sprite position (shapenum = %i)", ob
->shapenum
);
150 if(ob
->flags
& FL_DIR_VERT_FLAG
) // vertical dir 3d sprite
152 fixed gy1
,gy2
,gx
,gyt1
,gyt2
,gxt
;
154 // translate point to view centered coordinates
156 gy1
= (((long)ob
->tiley
) << TILESHIFT
)+0x8000-playy
-0x8000L
-SIZEADD
;
157 gy2
= gy1
+0x10000L
+2*SIZEADD
;
158 gx
= (((long)ob
->tilex
) << TILESHIFT
)+diradd
-playx
;
163 gxt
= FixedMul(gx
,viewcos
);
164 gyt1
= FixedMul(gy1
,viewsin
);
165 gyt2
= FixedMul(gy2
,viewsin
);
172 gxt
= FixedMul(gx
,viewsin
);
173 gyt1
= FixedMul(gy1
,viewcos
);
174 gyt2
= FixedMul(gy2
,viewcos
);
178 else // horizontal dir 3d sprite
180 fixed gx1
,gx2
,gy
,gxt1
,gxt2
,gyt
;
182 // translate point to view centered coordinates
184 gx1
= (((long)ob
->tilex
) << TILESHIFT
)+0x8000-playx
-0x8000L
-SIZEADD
;
185 gx2
= gx1
+0x10000L
+2*SIZEADD
;
186 gy
= (((long)ob
->tiley
) << TILESHIFT
)+diradd
-playy
;
191 gxt1
= FixedMul(gx1
,viewcos
);
192 gxt2
= FixedMul(gx2
,viewcos
);
193 gyt
= FixedMul(gy
,viewsin
);
200 gxt1
= FixedMul(gx1
,viewsin
);
201 gxt2
= FixedMul(gx2
,viewsin
);
202 gyt
= FixedMul(gy
,viewcos
);
207 if(nx1
< 0 || nx2
< 0) return; // TODO: Clip on viewplane
210 // calculate perspective ratio
212 if(nx1
>=0 && nx1
<=1792) nx1
=1792;
213 if(nx1
<0 && nx1
>=-1792) nx1
=-1792;
214 if(nx2
>=0 && nx2
<=1792) nx2
=1792;
215 if(nx2
<0 && nx2
>=-1792) nx2
=-1792;
217 viewx1
=(int)(centerx
+ny1
*scale
/nx1
);
218 viewx2
=(int)(centerx
+ny2
*scale
/nx2
);
222 Scale3DShaper(viewx2
,viewx1
,ob
->shapenum
,ob
->flags
,ny2
,ny1
,nx2
,nx1
,vbuf
,vbufPitch
);
226 Scale3DShaper(viewx1
,viewx2
,ob
->shapenum
,ob
->flags
,ny1
,ny2
,nx1
,nx2
,vbuf
,vbufPitch
);