summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/d_edge.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2018-02-11 15:34:30 -0500
committerFranklin Wei <git@fwei.tk>2019-07-19 22:37:40 -0400
commit5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4 (patch)
tree84406e21639529a185556a33e5de7f43cffc277b /apps/plugins/sdl/progs/quake/d_edge.c
parentb70fecf21ddc21877ec1ae7888d9c18a979e37ad (diff)
downloadrockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.tar.gz
rockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.zip
Quake!
This ports id Software's Quake to run on the SDL plugin runtime. The source code originated from id under the GPLv2 license. I used https://github.com/ahefner/sdlquake as the base of my port. Performance is, unsurprisingly, not on par with what you're probably used to on PC. I average about 10FPS on ipod6g, but it's still playable. Sound works well enough, but in-game music is not supported. I've written ARM assembly routines for the inner sound loop. Make sure you turn the "brightness" all the way down, or colors will look funky. To run, extract Quake's data files to /.rockbox/quake. Have fun! Change-Id: I4285036e967d7f0722802d43cf2096c808ca5799
Diffstat (limited to 'apps/plugins/sdl/progs/quake/d_edge.c')
-rw-r--r--apps/plugins/sdl/progs/quake/d_edge.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/d_edge.c b/apps/plugins/sdl/progs/quake/d_edge.c
new file mode 100644
index 0000000000..52cc8eb276
--- /dev/null
+++ b/apps/plugins/sdl/progs/quake/d_edge.c
@@ -0,0 +1,331 @@
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20// d_edge.c
21
22#include "quakedef.h"
23#include "d_local.h"
24
25static int miplevel;
26
27float scale_for_mip;
28int screenwidth;
29int ubasestep, errorterm, erroradjustup, erroradjustdown;
30int vstartscan;
31
32// FIXME: should go away
33extern void R_RotateBmodel (void);
34extern void R_TransformFrustum (void);
35
36vec3_t transformed_modelorg;
37
38/*
39==============
40D_DrawPoly
41
42==============
43*/
44void D_DrawPoly (void)
45{
46// this driver takes spans, not polygons
47}
48
49
50/*
51=============
52D_MipLevelForScale
53=============
54*/
55int D_MipLevelForScale (float scale)
56{
57 int lmiplevel;
58
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;
67
68 if (lmiplevel < d_minmip)
69 lmiplevel = d_minmip;
70
71 return lmiplevel;
72}
73
74
75/*
76==============
77D_DrawSolidSurface
78==============
79*/
80
81// FIXME: clean this up
82
83void D_DrawSolidSurface (surf_t *surf, int color)
84{
85 espan_t *span;
86 byte *pdest;
87 int u, u2, pix;
88
89 pix = (color<<24) | (color<<16) | (color<<8) | color;
90 for (span=surf->spans ; span ; span=span->pnext)
91 {
92 pdest = (byte *)d_viewbuffer + screenwidth*span->v;
93 u = span->u;
94 u2 = span->u + span->count - 1;
95 ((byte *)pdest)[u] = pix;
96
97 if (u2 - u < 8)
98 {
99 for (u++ ; u <= u2 ; u++)
100 ((byte *)pdest)[u] = pix;
101 }
102 else
103 {
104 for (u++ ; u & 3 ; u++)
105 ((byte *)pdest)[u] = pix;
106
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;
113 }
114 }
115}
116
117
118/*
119==============
120D_CalcGradients
121==============
122*/
123void D_CalcGradients (msurface_t *pface)
124{
125 mplane_t *pplane;
126 float mipscale;
127 vec3_t p_temp1;
128 vec3_t p_saxis, p_taxis;
129 float t;
130
131 pplane = pface->plane;
132
133 mipscale = 1.0 / (float)(1 << miplevel);
134
135 TransformVector (pface->texinfo->vecs[0], p_saxis);
136 TransformVector (pface->texinfo->vecs[1], p_taxis);
137
138 t = xscaleinv * mipscale;
139 d_sdivzstepu = p_saxis[0] * t;
140 d_tdivzstepu = p_taxis[0] * t;
141
142 t = yscaleinv * mipscale;
143 d_sdivzstepv = -p_saxis[1] * t;
144 d_tdivzstepv = -p_taxis[1] * t;
145
146 d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
147 ycenter * d_sdivzstepv;
148 d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
149 ycenter * d_tdivzstepv;
150
151 VectorScale (transformed_modelorg, mipscale, p_temp1);
152
153 t = 0x10000*mipscale;
154 sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
155 ((pface->texturemins[0] << 16) >> miplevel)
156 + pface->texinfo->vecs[0][3]*t;
157 tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
158 ((pface->texturemins[1] << 16) >> miplevel)
159 + pface->texinfo->vecs[1][3]*t;
160
161//
162// -1 (-epsilon) so we never wander off the edge of the texture
163//
164 bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
165 bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
166}
167
168
169/*
170==============
171D_DrawSurfaces
172==============
173*/
174void D_DrawSurfaces (void)
175{
176 surf_t *s;
177 msurface_t *pface;
178 surfcache_t *pcurrentcache;
179 vec3_t world_transformed_modelorg;
180 vec3_t local_modelorg;
181
182 currententity = &cl_entities[0];
183 TransformVector (modelorg, transformed_modelorg);
184 VectorCopy (transformed_modelorg, world_transformed_modelorg);
185
186// TODO: could preset a lot of this at mode set time
187 if (r_drawflat.value)
188 {
189 for (s = &surfaces[1] ; s<surface_p ; s++)
190 {
191 if (!s->spans)
192 continue;
193
194 d_zistepu = s->d_zistepu;
195 d_zistepv = s->d_zistepv;
196 d_ziorigin = s->d_ziorigin;
197
198 D_DrawSolidSurface (s, (int)s->data & 0xFF);
199 D_DrawZSpans (s->spans);
200 }
201 }
202 else
203 {
204 for (s = &surfaces[1] ; s<surface_p ; s++)
205 {
206 if (!s->spans)
207 continue;
208
209 r_drawnpolycount++;
210
211 d_zistepu = s->d_zistepu;
212 d_zistepv = s->d_zistepv;
213 d_ziorigin = s->d_ziorigin;
214
215 if (s->flags & SURF_DRAWSKY)
216 {
217 if (!r_skymade)
218 {
219 R_MakeSky ();
220 }
221
222 D_DrawSkyScans8 (s->spans);
223 D_DrawZSpans (s->spans);
224 }
225 else if (s->flags & SURF_DRAWBACKGROUND)
226 {
227 // set up a gradient for the background surface that places it
228 // effectively at infinity distance from the viewpoint
229 d_zistepu = 0;
230 d_zistepv = 0;
231 d_ziorigin = -0.9;
232
233 D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
234 D_DrawZSpans (s->spans);
235 }
236 else if (s->flags & SURF_DRAWTURB)
237 {
238 pface = s->data;
239 miplevel = 0;
240 cacheblock = (pixel_t *)
241 ((byte *)pface->texinfo->texture +
242 pface->texinfo->texture->offsets[0]);
243 cachewidth = 64;
244
245 if (s->insubmodel)
246 {
247 // FIXME: we don't want to do all this for every polygon!
248 // TODO: store once at start of frame
249 currententity = s->entity; //FIXME: make this passed in to
250 // R_RotateBmodel ()
251 VectorSubtract (r_origin, currententity->origin,
252 local_modelorg);
253 TransformVector (local_modelorg, transformed_modelorg);
254
255 R_RotateBmodel (); // FIXME: don't mess with the frustum,
256 // make entity passed in
257 }
258
259 D_CalcGradients (pface);
260 Turbulent8 (s->spans);
261 D_DrawZSpans (s->spans);
262
263 if (s->insubmodel)
264 {
265 //
266 // restore the old drawing state
267 // FIXME: we don't want to do this every time!
268 // TODO: speed up
269 //
270 currententity = &cl_entities[0];
271 VectorCopy (world_transformed_modelorg,
272 transformed_modelorg);
273 VectorCopy (base_vpn, vpn);
274 VectorCopy (base_vup, vup);
275 VectorCopy (base_vright, vright);
276 VectorCopy (base_modelorg, modelorg);
277 R_TransformFrustum ();
278 }
279 }
280 else
281 {
282 if (s->insubmodel)
283 {
284 // FIXME: we don't want to do all this for every polygon!
285 // TODO: store once at start of frame
286 currententity = s->entity; //FIXME: make this passed in to
287 // R_RotateBmodel ()
288 VectorSubtract (r_origin, currententity->origin, local_modelorg);
289 TransformVector (local_modelorg, transformed_modelorg);
290
291 R_RotateBmodel (); // FIXME: don't mess with the frustum,
292 // make entity passed in
293 }
294
295 pface = s->data;
296 miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
297 * pface->texinfo->mipadjust);
298
299 // FIXME: make this passed in to D_CacheSurface
300 pcurrentcache = D_CacheSurface (pface, miplevel);
301
302 cacheblock = (pixel_t *)pcurrentcache->data;
303 cachewidth = pcurrentcache->width;
304
305 D_CalcGradients (pface);
306
307 (*d_drawspans) (s->spans);
308
309 D_DrawZSpans (s->spans);
310
311 if (s->insubmodel)
312 {
313 //
314 // restore the old drawing state
315 // FIXME: we don't want to do this every time!
316 // TODO: speed up
317 //
318 currententity = &cl_entities[0];
319 VectorCopy (world_transformed_modelorg,
320 transformed_modelorg);
321 VectorCopy (base_vpn, vpn);
322 VectorCopy (base_vup, vup);
323 VectorCopy (base_vright, vright);
324 VectorCopy (base_modelorg, modelorg);
325 R_TransformFrustum ();
326 }
327 }
328 }
329 }
330}
331