• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3 
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.
8 
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.
12 
13 See the GNU General Public License for more details.
14 
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.
18 
19 */
20 // r_sky.c
21 
22 #include "quakedef.h"
23 #include "r_local.h"
24 #include "d_local.h"
25 
26 
27 int		iskyspeed = 8;
28 int		iskyspeed2 = 2;
29 float	skyspeed, skyspeed2;
30 
31 float		skytime;
32 
33 byte		*r_skysource;
34 
35 int r_skymade;
36 int r_skydirect;		// not used?
37 
38 
39 // TODO: clean up these routines
40 
41 byte	bottomsky[128*131];
42 byte	bottommask[128*131];
43 byte	newsky[128*256];	// newsky and topsky both pack in here, 128 bytes
44 							//  of newsky on the left of each scan, 128 bytes
45 							//  of topsky on the right, because the low-level
46 							//  drawers need 256-byte scan widths
47 
48 
49 /*
50 =============
51 R_InitSky
52 
53 A sky texture is 256*128, with the right side being a masked overlay
54 ==============
55 */
R_InitSky(texture_t * mt)56 void R_InitSky (texture_t *mt)
57 {
58 	int			i, j;
59 	byte		*src;
60 
61 	src = (byte *)mt + mt->offsets[0];
62 
63 	for (i=0 ; i<128 ; i++)
64 	{
65 		for (j=0 ; j<128 ; j++)
66 		{
67 			newsky[(i*256) + j + 128] = src[i*256 + j + 128];
68 		}
69 	}
70 
71 	for (i=0 ; i<128 ; i++)
72 	{
73 		for (j=0 ; j<131 ; j++)
74 		{
75 			if (src[i*256 + (j & 0x7F)])
76 			{
77 				bottomsky[(i*131) + j] = src[i*256 + (j & 0x7F)];
78 				bottommask[(i*131) + j] = 0;
79 			}
80 			else
81 			{
82 				bottomsky[(i*131) + j] = 0;
83 				bottommask[(i*131) + j] = 0xff;
84 			}
85 		}
86 	}
87 
88 	r_skysource = newsky;
89 }
90 
91 
92 /*
93 =================
94 R_MakeSky
95 =================
96 */
R_MakeSky(void)97 void R_MakeSky (void)
98 {
99 	int			x, y;
100 	int			ofs, baseofs;
101 	int			xshift, yshift;
102 	unsigned	*pnewsky;
103 	static int	xlast = -1, ylast = -1;
104 
105 	xshift = skytime*skyspeed;
106 	yshift = skytime*skyspeed;
107 
108 	if ((xshift == xlast) && (yshift == ylast))
109 		return;
110 
111 	xlast = xshift;
112 	ylast = yshift;
113 
114 	pnewsky = (unsigned *)&newsky[0];
115 
116 	for (y=0 ; y<SKYSIZE ; y++)
117 	{
118 		baseofs = ((y+yshift) & SKYMASK) * 131;
119 
120 // FIXME: clean this up
121 #if UNALIGNED_OK
122 
123 		for (x=0 ; x<SKYSIZE ; x += 4)
124 		{
125 			ofs = baseofs + ((x+xshift) & SKYMASK);
126 
127 		// PORT: unaligned dword access to bottommask and bottomsky
128 
129 			*pnewsky = (*(pnewsky + (128 / sizeof (unsigned))) &
130 						*(unsigned *)&bottommask[ofs]) |
131 						*(unsigned *)&bottomsky[ofs];
132 			pnewsky++;
133 		}
134 
135 #else
136 
137 		for (x=0 ; x<SKYSIZE ; x++)
138 		{
139 			ofs = baseofs + ((x+xshift) & SKYMASK);
140 
141 			*(byte *)pnewsky = (*((byte *)pnewsky + 128) &
142 						*(byte *)&bottommask[ofs]) |
143 						*(byte *)&bottomsky[ofs];
144 			pnewsky = (unsigned *)((byte *)pnewsky + 1);
145 		}
146 
147 #endif
148 
149 		pnewsky += 128 / sizeof (unsigned);
150 	}
151 
152 	r_skymade = 1;
153 }
154 
155 
156 /*
157 =================
158 R_GenSkyTile
159 =================
160 */
R_GenSkyTile(void * pdest)161 void R_GenSkyTile (void *pdest)
162 {
163 	int			x, y;
164 	int			ofs, baseofs;
165 	int			xshift, yshift;
166 	unsigned	*pnewsky;
167 	unsigned	*pd;
168 
169 	xshift = skytime*skyspeed;
170 	yshift = skytime*skyspeed;
171 
172 	pnewsky = (unsigned *)&newsky[0];
173 	pd = (unsigned *)pdest;
174 
175 	for (y=0 ; y<SKYSIZE ; y++)
176 	{
177 		baseofs = ((y+yshift) & SKYMASK) * 131;
178 
179 // FIXME: clean this up
180 #if UNALIGNED_OK
181 
182 		for (x=0 ; x<SKYSIZE ; x += 4)
183 		{
184 			ofs = baseofs + ((x+xshift) & SKYMASK);
185 
186 		// PORT: unaligned dword access to bottommask and bottomsky
187 
188 			*pd = (*(pnewsky + (128 / sizeof (unsigned))) &
189 				   *(unsigned *)&bottommask[ofs]) |
190 				   *(unsigned *)&bottomsky[ofs];
191 			pnewsky++;
192 			pd++;
193 		}
194 
195 #else
196 
197 		for (x=0 ; x<SKYSIZE ; x++)
198 		{
199 			ofs = baseofs + ((x+xshift) & SKYMASK);
200 
201 			*(byte *)pd = (*((byte *)pnewsky + 128) &
202 						*(byte *)&bottommask[ofs]) |
203 						*(byte *)&bottomsky[ofs];
204 			pnewsky = (unsigned *)((byte *)pnewsky + 1);
205 			pd = (unsigned *)((byte *)pd + 1);
206 		}
207 
208 #endif
209 
210 		pnewsky += 128 / sizeof (unsigned);
211 	}
212 }
213 
214 
215 /*
216 =================
217 R_GenSkyTile16
218 =================
219 */
R_GenSkyTile16(void * pdest)220 void R_GenSkyTile16 (void *pdest)
221 {
222 	int				x, y;
223 	int				ofs, baseofs;
224 	int				xshift, yshift;
225 	byte			*pnewsky;
226 	unsigned short	*pd;
227 
228 	xshift = skytime * skyspeed;
229 	yshift = skytime * skyspeed;
230 
231 	pnewsky = (byte *)&newsky[0];
232 	pd = (unsigned short *)pdest;
233 
234 	for (y=0 ; y<SKYSIZE ; y++)
235 	{
236 		baseofs = ((y+yshift) & SKYMASK) * 131;
237 
238 // FIXME: clean this up
239 // FIXME: do faster unaligned version?
240 		for (x=0 ; x<SKYSIZE ; x++)
241 		{
242 			ofs = baseofs + ((x+xshift) & SKYMASK);
243 
244 			*pd = d_8to16table[(*(pnewsky + 128) &
245 					*(byte *)&bottommask[ofs]) |
246 					*(byte *)&bottomsky[ofs]];
247 			pnewsky++;
248 			pd++;
249 		}
250 
251 		pnewsky += TILE_SIZE;
252 	}
253 }
254 
255 
256 /*
257 =============
258 R_SetSkyFrame
259 ==============
260 */
R_SetSkyFrame(void)261 void R_SetSkyFrame (void)
262 {
263 	int		g, s1, s2;
264 	float	temp;
265 
266 	skyspeed = iskyspeed;
267 	skyspeed2 = iskyspeed2;
268 
269 	g = GreatestCommonDivisor (iskyspeed, iskyspeed2);
270 	s1 = iskyspeed / g;
271 	s2 = iskyspeed2 / g;
272 	temp = SKYSIZE * s1 * s2;
273 
274 	skytime = cl.time - ((int)(cl.time / temp) * temp);
275 
276 
277 	r_skymade = 0;
278 }
279 
280 
281