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