1 /*
2 Copyright (C) 1997-2001 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 //
21 // cg_light.c
22 //
23 
24 #include "cg_local.h"
25 
26 typedef struct cgLightStyle_s {
27 	float		map[MAX_CFGSTRLEN];
28 
29 	int			length;
30 	float		value[3];
31 } cgLightStyle_t;
32 
33 static cgLightStyle_t	cg_lightStyles[MAX_CS_LIGHTSTYLES];
34 static int				cg_lSLastOfs;
35 
36 static cgDLight_t		cg_dLightList[MAX_REF_DLIGHTS];
37 
38 /*
39 =============================================================================
40 
41 	DLIGHT STYLE MANAGEMENT
42 
43 =============================================================================
44 */
45 
46 /*
47 ================
48 CG_ClearLightStyles
49 ================
50 */
CG_ClearLightStyles(void)51 void CG_ClearLightStyles (void)
52 {
53 	memset (cg_lightStyles, 0, sizeof (cg_lightStyles));
54 	cg_lSLastOfs = -1;
55 }
56 
57 
58 /*
59 ================
60 CG_RunLightStyles
61 ================
62 */
CG_RunLightStyles(void)63 void CG_RunLightStyles (void)
64 {
65 	int				ofs;
66 	int				i;
67 	cgLightStyle_t	*ls;
68 	float			backLerp, frac;
69 	float			map;
70 
71 	ofs = cg.realTime / 100;
72 	if (ofs == cg_lSLastOfs)
73 		return;
74 
75 	frac = ofs - cg_lSLastOfs;
76 	backLerp = 1.0f - frac;
77 
78 	for (i=0, ls=cg_lightStyles ; i<MAX_CS_LIGHTSTYLES ; i++, ls++) {
79 		if (!ls->length) {
80 			ls->value[0] = ls->value[1] = ls->value[2] = 1.0;
81 			continue;
82 		}
83 
84 		if (ls->length == 1) {
85 			ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0];
86 		}
87 		else {
88 			map = (ls->map[cg_lSLastOfs%ls->length] * backLerp) + (ls->map[ofs%ls->length] * frac);
89 			ls->value[0] = ls->value[1] = ls->value[2] = map;
90 		}
91 	}
92 
93 	cg_lSLastOfs = ofs;
94 }
95 
96 
97 /*
98 ================
99 CG_SetLightstyle
100 ================
101 */
CG_SetLightstyle(int num)102 void CG_SetLightstyle (int num)
103 {
104 	char	*s;
105 	int		len, i;
106 
107 	s = cg.configStrings[num+CS_LIGHTS];
108 
109 	len = (int)strlen (s);
110 	if (len >= MAX_CFGSTRLEN)
111 		Com_Error (ERR_DROP, "CG_SetLightstyle: svc_lightstyle length=%i", len);
112 
113 	cg_lightStyles[num].length = len;
114 	for (i=0 ; i<len ; i++)
115 		cg_lightStyles[num].map[i] = (float)(s[i]-'a')/(float)('m'-'a');
116 }
117 
118 
119 /*
120 ================
121 CG_AddLightStyles
122 ================
123 */
CG_AddLightStyles(void)124 void CG_AddLightStyles (void)
125 {
126 	int				i;
127 	cgLightStyle_t	*ls;
128 
129 	for (i=0, ls=cg_lightStyles ; i<MAX_CS_LIGHTSTYLES ; i++, ls++)
130 		cgi.R_AddLightStyle (i, ls->value[0], ls->value[1], ls->value[2]);
131 }
132 
133 /*
134 =============================================================================
135 
136 	DLIGHT MANAGEMENT
137 
138 =============================================================================
139 */
140 
141 /*
142 ================
143 CG_ClearDLights
144 ================
145 */
CG_ClearDLights(void)146 void CG_ClearDLights (void)
147 {
148 	memset (cg_dLightList, 0, sizeof (cg_dLightList));
149 }
150 
151 
152 /*
153 ===============
154 CG_AllocDLight
155 ===============
156 */
CG_AllocDLight(int key)157 cgDLight_t *CG_AllocDLight (int key)
158 {
159 	int			i;
160 	cgDLight_t	*dl;
161 
162 	// First look for an exact key match
163 	if (key) {
164 		dl = cg_dLightList;
165 		for (i=0 ; i<MAX_REF_DLIGHTS ; i++, dl++) {
166 			if (dl->key == key) {
167 				memset (dl, 0, sizeof (cgDLight_t));
168 				dl->key = key;
169 				return dl;
170 			}
171 		}
172 	}
173 
174 	// Then look for anything else
175 	dl = cg_dLightList;
176 	for (i=0 ; i<MAX_REF_DLIGHTS ; i++, dl++) {
177 		if (dl->die < cg.realTime) {
178 			memset (dl, 0, sizeof (cgDLight_t));
179 			dl->key = key;
180 			return dl;
181 		}
182 	}
183 
184 	dl = &cg_dLightList[0];
185 	memset (dl, 0, sizeof (cgDLight_t));
186 	dl->key = key;
187 	return dl;
188 }
189 
190 
191 /*
192 ===============
193 CG_RunDLights
194 ===============
195 */
CG_RunDLights(void)196 void CG_RunDLights (void)
197 {
198 	int			i;
199 	cgDLight_t	*dl;
200 
201 	dl = cg_dLightList;
202 	for (i=0 ; i<MAX_REF_DLIGHTS ; i++, dl++) {
203 		if (!dl->radius)
204 			continue;
205 
206 		if (dl->die < cg.realTime) {
207 			dl->radius = 0;
208 			return;
209 		}
210 		dl->radius -= cg.refreshFrameTime*dl->decay;
211 		if (dl->radius < 0)
212 			dl->radius = 0;
213 	}
214 }
215 
216 
217 /*
218 ===============
219 CG_AddDLights
220 ===============
221 */
CG_AddDLights(void)222 void CG_AddDLights (void)
223 {
224 	int			i;
225 	cgDLight_t	*dl;
226 
227 	for (dl=cg_dLightList, i=0 ; i<MAX_REF_DLIGHTS ; i++, dl++) {
228 		if (!dl->radius)
229 			continue;
230 
231 		cgi.R_AddLight (dl->origin, dl->radius, dl->color[0], dl->color[1], dl->color[2]);
232 	}
233 }
234 
235 /*
236 =============================================================================
237 
238 	LIGHT EFFECTS
239 
240 =============================================================================
241 */
242 
243 /*
244 ===============
245 CG_Flashlight
246 ===============
247 */
CG_Flashlight(int ent,vec3_t pos)248 void CG_Flashlight (int ent, vec3_t pos)
249 {
250 	cgDLight_t	*dl;
251 
252 	dl = CG_AllocDLight (ent);
253 	Vec3Copy (pos, dl->origin);
254 	dl->radius = 400;
255 	dl->minlight = 250;
256 	dl->die = cg.realTime + 100.0f;
257 	dl->color[0] = 1;
258 	dl->color[1] = 1;
259 	dl->color[2] = 1;
260 }
261 
262 
263 /*
264 ===============
265 CG_ColorFlash
266 
267 flash of light
268 ===============
269 */
CG_ColorFlash(vec3_t pos,int ent,float intensity,float r,float g,float b)270 void __fastcall CG_ColorFlash (vec3_t pos, int ent, float intensity, float r, float g, float b)
271 {
272 	cgDLight_t	*dl;
273 
274 	dl = CG_AllocDLight (ent);
275 	Vec3Copy (pos, dl->origin);
276 	dl->radius = intensity;
277 	dl->minlight = 250;
278 	dl->die = (float)cg.realTime + 100.0f;
279 	dl->color[0] = r;
280 	dl->color[1] = g;
281 	dl->color[2] = b;
282 }
283 
284 
285 /*
286 ===============
287 CG_WeldingSparkFlash
288 ===============
289 */
CG_WeldingSparkFlash(vec3_t pos)290 void CG_WeldingSparkFlash (vec3_t pos)
291 {
292 	cgDLight_t	*dl;
293 
294 	dl = CG_AllocDLight ((int)((pos[0]+pos[1]+pos[3]) / 3.0));
295 
296 	Vec3Copy (pos, dl->origin);
297 	Vec3Set (dl->color, 1, 1, 0.3f);
298 	dl->decay = 10;
299 	dl->die = (float)cg.realTime + 100.0f;
300 	dl->minlight = 100;
301 	dl->radius = 175;
302 }
303