84bbd123 |
1 | /* |
2 | * Elite - The New Kind. |
3 | * |
4 | * Reverse engineered from the BBC disk version of Elite. |
5 | * Additional material by C.J.Pinder. |
6 | * |
7 | * The original Elite code is (C) I.Bell & D.Braben 1984. |
8 | * This version re-engineered in C by C.J.Pinder 1999-2001. |
9 | * |
10 | * email: <christian@newkind.co.uk> |
11 | * |
12 | * |
13 | */ |
14 | |
15 | #include <stdlib.h> |
16 | #include <math.h> |
17 | |
18 | #include "config.h" |
19 | #include "elite.h" |
20 | #include "gfx.h" |
21 | #include "vector.h" |
22 | #include "stars.h" |
23 | #include "random.h" |
24 | |
25 | int warp_stars; |
26 | |
27 | struct star |
28 | { |
29 | double x; |
30 | double y; |
31 | double z; |
32 | }; |
33 | |
34 | struct star stars[20]; |
35 | |
36 | |
37 | void create_new_stars (void) |
38 | { |
39 | int i; |
40 | int nstars; |
41 | |
42 | nstars = witchspace ? 3 : 12; |
43 | |
44 | for (i = 0; i < nstars; i++) |
45 | { |
46 | stars[i].x = (rand255() - 128) | 8; |
47 | stars[i].y = (rand255() - 128) | 4; |
48 | stars[i].z = rand255() | 0x90; |
49 | } |
50 | |
51 | warp_stars = 0; |
52 | } |
53 | |
54 | |
55 | void front_starfield (void) |
56 | { |
57 | int i; |
58 | double Q; |
59 | double delta; |
60 | double alpha = 0; |
61 | double beta = 0; |
62 | double xx,yy,zz; |
63 | int sx; |
64 | int sy; |
65 | int nstars; |
66 | |
67 | nstars = witchspace ? 3 : 12; |
68 | |
69 | delta = warp_stars ? 50 : flight_speed; |
70 | alpha = (double)flight_roll; |
71 | beta = (double)flight_climb; |
72 | |
73 | alpha /= 256.0; |
74 | delta /= 2.0; |
75 | |
76 | for (i = 0; i < nstars; i++) |
77 | { |
78 | /* Plot the stars in their current locations... */ |
79 | |
80 | sy = stars[i].y; |
81 | sx = stars[i].x; |
82 | zz = stars[i].z; |
83 | |
84 | sx += 128; |
85 | sy += 96; |
86 | |
87 | sx *= GFX_SCALE; |
88 | sy *= GFX_SCALE; |
89 | |
90 | if ((!warp_stars) && |
91 | (sx >= GFX_VIEW_TX) && (sx <= GFX_VIEW_BX) && |
92 | (sy >= GFX_VIEW_TY) && (sy <= GFX_VIEW_BY)) |
93 | { |
94 | gfx_plot_pixel (sx, sy, GFX_COL_WHITE); |
95 | |
96 | if (zz < 0xC0) |
97 | gfx_plot_pixel (sx+1, sy, GFX_COL_WHITE); |
98 | |
99 | if (zz < 0x90) |
100 | { |
101 | gfx_plot_pixel (sx, sy+1, GFX_COL_WHITE); |
102 | gfx_plot_pixel (sx+1, sy+1, GFX_COL_WHITE); |
103 | } |
104 | } |
105 | |
106 | |
107 | /* Move the stars to their new locations...*/ |
108 | |
109 | Q = delta / stars[i].z; |
110 | |
111 | stars[i].z -= delta; |
112 | yy = stars[i].y + (stars[i].y * Q); |
113 | xx = stars[i].x + (stars[i].x * Q); |
114 | zz = stars[i].z; |
115 | |
116 | yy = yy + (xx * alpha); |
117 | xx = xx - (yy * alpha); |
118 | |
119 | /* |
120 | tx = yy * beta; |
121 | xx = xx + (tx * tx * 2); |
122 | */ |
123 | yy = yy + beta; |
124 | |
125 | stars[i].y = yy; |
126 | stars[i].x = xx; |
127 | |
128 | |
129 | if (warp_stars) |
130 | gfx_draw_line (sx, sy, (xx + 128) * GFX_SCALE, (yy + 96) * GFX_SCALE); |
131 | |
132 | sx = xx; |
133 | sy = yy; |
134 | |
135 | if ((sx > 120) || (sx < -120) || |
136 | (sy > 120) || (sy < -120) || (zz < 16)) |
137 | { |
138 | stars[i].x = (rand255() - 128) | 8; |
139 | stars[i].y = (rand255() - 128) | 4; |
140 | stars[i].z = rand255() | 0x90; |
141 | continue; |
142 | } |
143 | |
144 | } |
145 | |
146 | warp_stars = 0; |
147 | } |
148 | |
149 | |
150 | |
151 | void rear_starfield (void) |
152 | { |
153 | int i; |
154 | double Q; |
155 | double delta; |
156 | double alpha = 0; |
157 | double beta = 0; |
158 | double xx,yy,zz; |
159 | int sx,sy; |
160 | int ex,ey; |
161 | int nstars; |
162 | |
163 | nstars = witchspace ? 3 : 12; |
164 | |
165 | delta = warp_stars ? 50 : flight_speed; |
166 | alpha = -flight_roll; |
167 | beta = -flight_climb; |
168 | |
169 | alpha /= 256.0; |
170 | delta /= 2.0; |
171 | |
172 | for (i = 0; i < nstars; i++) |
173 | { |
174 | /* Plot the stars in their current locations... */ |
175 | |
176 | sy = stars[i].y; |
177 | sx = stars[i].x; |
178 | zz = stars[i].z; |
179 | |
180 | sx += 128; |
181 | sy += 96; |
182 | |
183 | sx *= GFX_SCALE; |
184 | sy *= GFX_SCALE; |
185 | |
186 | if ((!warp_stars) && |
187 | (sx >= GFX_VIEW_TX) && (sx <= GFX_VIEW_BX) && |
188 | (sy >= GFX_VIEW_TY) && (sy <= GFX_VIEW_BY)) |
189 | { |
190 | gfx_plot_pixel (sx, sy, GFX_COL_WHITE); |
191 | |
192 | if (zz < 0xC0) |
193 | gfx_plot_pixel (sx+1, sy, GFX_COL_WHITE); |
194 | |
195 | if (zz < 0x90) |
196 | { |
197 | gfx_plot_pixel (sx, sy+1, GFX_COL_WHITE); |
198 | gfx_plot_pixel (sx+1, sy+1, GFX_COL_WHITE); |
199 | } |
200 | } |
201 | |
202 | |
203 | /* Move the stars to their new locations...*/ |
204 | |
205 | Q = delta / stars[i].z; |
206 | |
207 | stars[i].z += delta; |
208 | yy = stars[i].y - (stars[i].y * Q); |
209 | xx = stars[i].x - (stars[i].x * Q); |
210 | zz = stars[i].z; |
211 | |
212 | yy = yy + (xx * alpha); |
213 | xx = xx - (yy * alpha); |
214 | |
215 | /* |
216 | tx = yy * beta; |
217 | xx = xx + (tx * tx * 2); |
218 | */ |
219 | yy = yy + beta; |
220 | |
221 | if (warp_stars) |
222 | { |
223 | ey = yy; |
224 | ex = xx; |
225 | ex = (ex + 128) * GFX_SCALE; |
226 | ey = (ey + 96) * GFX_SCALE; |
227 | |
228 | if ((sx >= GFX_VIEW_TX) && (sx <= GFX_VIEW_BX) && |
229 | (sy >= GFX_VIEW_TY) && (sy <= GFX_VIEW_BY) && |
230 | (ex >= GFX_VIEW_TX) && (ex <= GFX_VIEW_BX) && |
231 | (ey >= GFX_VIEW_TY) && (ey <= GFX_VIEW_BY)) |
232 | gfx_draw_line (sx, sy, (xx + 128) * GFX_SCALE, (yy + 96) * GFX_SCALE); |
233 | } |
234 | |
235 | stars[i].y = yy; |
236 | stars[i].x = xx; |
237 | |
238 | if ((zz >= 300) || (abs(yy) >= 110)) |
239 | { |
240 | stars[i].z = (rand255() & 127) + 51; |
241 | |
242 | if (rand255() & 1) |
243 | { |
244 | stars[i].x = rand255() - 128; |
245 | stars[i].y = (rand255() & 1) ? -115 : 115; |
246 | } |
247 | else |
248 | { |
249 | stars[i].x = (rand255() & 1) ? -126 : 126; |
250 | stars[i].y = rand255() - 128; |
251 | } |
252 | } |
253 | |
254 | } |
255 | |
256 | warp_stars = 0; |
257 | } |
258 | |
259 | |
260 | void side_starfield (void) |
261 | { |
262 | int i; |
263 | double delta; |
264 | double alpha; |
265 | double beta; |
266 | double xx,yy,zz; |
267 | int sx; |
268 | int sy; |
269 | double delt8; |
270 | int nstars; |
271 | |
272 | nstars = witchspace ? 3 : 12; |
273 | |
274 | delta = warp_stars ? 50 : flight_speed; |
275 | alpha = flight_roll; |
276 | beta = flight_climb; |
277 | |
278 | if (current_screen == SCR_LEFT_VIEW) |
279 | { |
280 | delta = -delta; |
281 | alpha = -alpha; |
282 | beta = -beta; |
283 | } |
284 | |
285 | for (i = 0; i < nstars; i++) |
286 | { |
287 | sy = stars[i].y; |
288 | sx = stars[i].x; |
289 | zz = stars[i].z; |
290 | |
291 | sx += 128; |
292 | sy += 96; |
293 | |
294 | sx *= GFX_SCALE; |
295 | sy *= GFX_SCALE; |
296 | |
297 | if ((!warp_stars) && |
298 | (sx >= GFX_VIEW_TX) && (sx <= GFX_VIEW_BX) && |
299 | (sy >= GFX_VIEW_TY) && (sy <= GFX_VIEW_BY)) |
300 | { |
301 | gfx_plot_pixel (sx, sy, GFX_COL_WHITE); |
302 | |
303 | if (zz < 0xC0) |
304 | gfx_plot_pixel (sx+1, sy, GFX_COL_WHITE); |
305 | |
306 | if (zz < 0x90) |
307 | { |
308 | gfx_plot_pixel (sx, sy+1, GFX_COL_WHITE); |
309 | gfx_plot_pixel (sx+1, sy+1, GFX_COL_WHITE); |
310 | } |
311 | } |
312 | |
313 | yy = stars[i].y; |
314 | xx = stars[i].x; |
315 | zz = stars[i].z; |
316 | |
317 | delt8 = delta / (zz / 32); |
318 | xx = xx + delt8; |
319 | |
320 | xx += (yy * (beta / 256)); |
321 | yy -= (xx * (beta / 256)); |
322 | |
323 | xx += ((yy / 256) * (alpha / 256)) * (-xx); |
324 | yy += ((yy / 256) * (alpha / 256)) * (yy); |
325 | |
326 | yy += alpha; |
327 | |
328 | stars[i].y = yy; |
329 | stars[i].x = xx; |
330 | |
331 | if (warp_stars) |
332 | gfx_draw_line (sx, sy, (xx + 128) * GFX_SCALE, (yy + 96) * GFX_SCALE); |
333 | |
334 | |
335 | if (abs(stars[i].x) >= 116) |
336 | { |
337 | stars[i].y = rand255() - 128; |
338 | stars[i].x = (current_screen == SCR_LEFT_VIEW) ? 115 : -115; |
339 | stars[i].z = rand255() | 8; |
340 | } |
341 | else if (abs(stars[i].y) >= 116) |
342 | { |
343 | stars[i].x = rand255() - 128; |
344 | stars[i].y = (alpha > 0) ? -110 : 110; |
345 | stars[i].z = rand255() | 8; |
346 | } |
347 | |
348 | } |
349 | |
350 | warp_stars = 0; |
351 | } |
352 | |
353 | |
354 | /* |
355 | * When we change view, flip the stars over so they look like other stars. |
356 | */ |
357 | |
358 | void flip_stars (void) |
359 | { |
360 | int i; |
361 | int nstars; |
362 | int sx; |
363 | int sy; |
364 | |
365 | nstars = witchspace ? 3 : 12; |
366 | for (i = 0; i < nstars; i++) |
367 | { |
368 | sy = stars[i].y; |
369 | sx = stars[i].x; |
370 | stars[i].x = sy; |
371 | stars[i].y = sx; |
372 | } |
373 | } |
374 | |
375 | |
376 | void update_starfield (void) |
377 | { |
378 | switch (current_screen) |
379 | { |
380 | case SCR_FRONT_VIEW: |
381 | case SCR_INTRO_ONE: |
382 | case SCR_INTRO_TWO: |
383 | case SCR_ESCAPE_POD: |
384 | front_starfield(); |
385 | break; |
386 | |
387 | case SCR_REAR_VIEW: |
388 | case SCR_GAME_OVER: |
389 | rear_starfield(); |
390 | break; |
391 | |
392 | case SCR_LEFT_VIEW: |
393 | case SCR_RIGHT_VIEW: |
394 | side_starfield(); |
395 | break; |
396 | } |
397 | } |