Replaced Exit() by exit() because Exit() is like abort().
[AROS-Contrib.git] / Games / Quake / d_edge.c
blob7a2881676517a25d8014e6d72d5b9c8ec08d4f16
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // d_edge.c
22 #include "quakedef.h"
23 #include "d_local.h"
25 static int miplevel;
27 float scale_for_mip;
28 int screenwidth;
29 int ubasestep, errorterm, erroradjustup, erroradjustdown;
30 int vstartscan;
32 // FIXME: should go away
33 extern void R_RotateBmodel (void);
34 extern void R_TransformFrustum (void);
36 vec3_t transformed_modelorg;
39 ==============
40 D_DrawPoly
42 ==============
44 void D_DrawPoly (void)
46 // this driver takes spans, not polygons
51 =============
52 D_MipLevelForScale
53 =============
55 int D_MipLevelForScale (float scale)
57 int lmiplevel;
59 if (scale >= d_scalemip[0] )
60 lmiplevel = 0;
61 else if (scale >= d_scalemip[1] )
62 lmiplevel = 1;
63 else if (scale >= d_scalemip[2] )
64 lmiplevel = 2;
65 else
66 lmiplevel = 3;
68 if (lmiplevel < d_minmip)
69 lmiplevel = d_minmip;
71 return lmiplevel;
76 ==============
77 D_DrawSolidSurface
78 ==============
81 // FIXME: clean this up
83 void D_DrawSolidSurface (surf_t *surf, int color)
85 espan_t *span;
86 byte *pdest;
87 int u, u2, pix;
89 pix = (color<<24) | (color<<16) | (color<<8) | color;
90 for (span=surf->spans ; span ; span=span->pnext)
92 pdest = (byte *)d_viewbuffer + screenwidth*span->v;
93 u = span->u;
94 u2 = span->u + span->count - 1;
95 ((byte *)pdest)[u] = pix;
97 if (u2 - u < 8)
99 for (u++ ; u <= u2 ; u++)
100 ((byte *)pdest)[u] = pix;
102 else
104 for (u++ ; u & 3 ; u++)
105 ((byte *)pdest)[u] = pix;
107 u2 -= 4;
108 for ( ; u <= u2 ; u+=4)
109 *(int *)((byte *)pdest + u) = pix;
110 u2 += 4;
111 for ( ; u <= u2 ; u++)
112 ((byte *)pdest)[u] = pix;
119 ==============
120 D_CalcGradients
121 ==============
123 void D_CalcGradients (msurface_t *pface)
125 float mipscale;
126 vec3_t p_temp1;
127 vec3_t p_saxis, p_taxis;
128 float t;
130 mipscale = 1.0 / (float)(1 << miplevel);
132 TransformVector (pface->texinfo->vecs[0], p_saxis);
133 TransformVector (pface->texinfo->vecs[1], p_taxis);
135 t = xscaleinv * mipscale;
136 d_sdivzstepu = p_saxis[0] * t;
137 d_tdivzstepu = p_taxis[0] * t;
139 t = yscaleinv * mipscale;
140 d_sdivzstepv = -p_saxis[1] * t;
141 d_tdivzstepv = -p_taxis[1] * t;
143 d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
144 ycenter * d_sdivzstepv;
145 d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
146 ycenter * d_tdivzstepv;
148 VectorScale (transformed_modelorg, mipscale, p_temp1);
150 t = 0x10000*mipscale;
151 sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
152 ((pface->texturemins[0] << 16) >> miplevel)
153 + pface->texinfo->vecs[0][3]*t;
154 tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
155 ((pface->texturemins[1] << 16) >> miplevel)
156 + pface->texinfo->vecs[1][3]*t;
159 // -1 (-epsilon) so we never wander off the edge of the texture
161 bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
162 bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
167 ==============
168 D_DrawSurfaces
169 ==============
171 void D_DrawSurfaces (void)
173 surf_t *s;
174 msurface_t *pface;
175 surfcache_t *pcurrentcache;
176 vec3_t world_transformed_modelorg;
177 vec3_t local_modelorg;
179 currententity = &cl_entities[0];
180 TransformVector (modelorg, transformed_modelorg);
181 VectorCopy (transformed_modelorg, world_transformed_modelorg);
183 // TODO: could preset a lot of this at mode set time
184 if (r_drawflat.value)
186 for (s = &surfaces[1] ; s<surface_p ; s++)
188 if (!s->spans)
189 continue;
191 d_zistepu = s->d_zistepu;
192 d_zistepv = s->d_zistepv;
193 d_ziorigin = s->d_ziorigin;
195 D_DrawSolidSurface (s, (int)s->data & 0xFF);
196 D_DrawZSpans (s->spans);
199 else
201 for (s = &surfaces[1] ; s<surface_p ; s++)
203 if (!s->spans)
204 continue;
206 r_drawnpolycount++;
208 d_zistepu = s->d_zistepu;
209 d_zistepv = s->d_zistepv;
210 d_ziorigin = s->d_ziorigin;
212 if (s->flags & SURF_DRAWSKY)
214 if (!r_skymade)
216 R_MakeSky ();
219 D_DrawSkyScans8 (s->spans);
220 D_DrawZSpans (s->spans);
222 else if (s->flags & SURF_DRAWBACKGROUND)
224 // set up a gradient for the background surface that places it
225 // effectively at infinity distance from the viewpoint
226 d_zistepu = 0;
227 d_zistepv = 0;
228 d_ziorigin = -0.9;
230 D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
231 D_DrawZSpans (s->spans);
233 else if (s->flags & SURF_DRAWTURB)
235 pface = s->data;
236 miplevel = 0;
237 cacheblock = (pixel_t *)
238 ((byte *)pface->texinfo->texture +
239 pface->texinfo->texture->offsets[0]);
240 cachewidth = 64;
242 if (s->insubmodel)
244 // FIXME: we don't want to do all this for every polygon!
245 // TODO: store once at start of frame
246 currententity = s->entity; //FIXME: make this passed in to
247 // R_RotateBmodel ()
248 VectorSubtract (r_origin, currententity->origin,
249 local_modelorg);
250 TransformVector (local_modelorg, transformed_modelorg);
252 R_RotateBmodel (); // FIXME: don't mess with the frustum,
253 // make entity passed in
256 D_CalcGradients (pface);
257 Turbulent8 (s->spans);
258 D_DrawZSpans (s->spans);
260 if (s->insubmodel)
263 // restore the old drawing state
264 // FIXME: we don't want to do this every time!
265 // TODO: speed up
267 currententity = &cl_entities[0];
268 VectorCopy (world_transformed_modelorg,
269 transformed_modelorg);
270 VectorCopy (base_vpn, vpn);
271 VectorCopy (base_vup, vup);
272 VectorCopy (base_vright, vright);
273 VectorCopy (base_modelorg, modelorg);
274 R_TransformFrustum ();
277 else
279 if (s->insubmodel)
281 // FIXME: we don't want to do all this for every polygon!
282 // TODO: store once at start of frame
283 currententity = s->entity; //FIXME: make this passed in to
284 // R_RotateBmodel ()
285 VectorSubtract (r_origin, currententity->origin, local_modelorg);
286 TransformVector (local_modelorg, transformed_modelorg);
288 R_RotateBmodel (); // FIXME: don't mess with the frustum,
289 // make entity passed in
292 pface = s->data;
293 miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
294 * pface->texinfo->mipadjust);
296 // FIXME: make this passed in to D_CacheSurface
297 pcurrentcache = D_CacheSurface (pface, miplevel);
299 cacheblock = (pixel_t *)pcurrentcache->data;
300 cachewidth = pcurrentcache->width;
302 D_CalcGradients (pface);
304 (*d_drawspans) (s->spans);
306 D_DrawZSpans (s->spans);
308 if (s->insubmodel)
311 // restore the old drawing state
312 // FIXME: we don't want to do this every time!
313 // TODO: speed up
315 currententity = &cl_entities[0];
316 VectorCopy (world_transformed_modelorg,
317 transformed_modelorg);
318 VectorCopy (base_vpn, vpn);
319 VectorCopy (base_vup, vup);
320 VectorCopy (base_vright, vright);
321 VectorCopy (base_modelorg, modelorg);
322 R_TransformFrustum ();