e079b9e74a95afed778f5c309437845dce1e64d5
[summerhack] / src / 3dengfx / libs / lib3ds / atmosphere.c
1 /*
2  * The 3D Studio File Format Library
3  * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
4  * All rights reserved.
5  *
6  * This program is  free  software;  you can redistribute it and/or modify it
7  * under the terms of the  GNU Lesser General Public License  as published by 
8  * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
9  * your option) any later version.
10  *
11  * This  program  is  distributed in  the  hope that it will  be useful,  but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
14  * License for more details.
15  *
16  * You should  have received  a copy of the GNU Lesser General Public License
17  * along with  this program;  if not, write to the  Free Software Foundation,
18  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * $Id: atmosphere.c,v 1.9 2001/07/07 19:05:30 jeh Exp $
21  */
22 #define LIB3DS_EXPORT
23 #include <lib3ds/atmosphere.h>
24 #include <lib3ds/chunk.h>
25 #include <lib3ds/io.h>
26
27
28 /*!
29  * \defgroup atmosphere Atmosphere Settings
30  *
31  * \author J.E. Hoffmann <je-h@gmx.net>
32  */
33
34
35 static Lib3dsBool
36 fog_read(Lib3dsFog *fog, Lib3dsIo *io)
37 {
38   Lib3dsChunk c;
39   Lib3dsWord chunk;
40
41   if (!lib3ds_chunk_read_start(&c, LIB3DS_FOG, io)) {
42     return(LIB3DS_FALSE);
43   }
44   fog->near_plane = lib3ds_io_read_float(io);
45   fog->near_density=lib3ds_io_read_float(io);
46   fog->far_plane=lib3ds_io_read_float(io);
47   fog->far_density=lib3ds_io_read_float(io);
48   lib3ds_chunk_read_tell(&c, io);
49   
50   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
51     switch (chunk) {
52       case LIB3DS_LIN_COLOR_F:
53         {
54           int i;
55           for (i=0; i<3; ++i) {
56             fog->col[i]=lib3ds_io_read_float(io);
57           }
58         }
59         break;
60       case LIB3DS_COLOR_F:
61         break;
62       case LIB3DS_FOG_BGND:
63         {
64           fog->fog_background=LIB3DS_TRUE;
65         }
66         break;
67       default:
68         lib3ds_chunk_unknown(chunk);
69     }
70   }
71   
72   lib3ds_chunk_read_end(&c, io);
73   return(LIB3DS_TRUE);
74 }
75
76
77 static Lib3dsBool
78 layer_fog_read(Lib3dsLayerFog *fog, Lib3dsIo *io)
79 {
80   Lib3dsChunk c;
81   Lib3dsWord chunk;
82   Lib3dsBool have_lin=LIB3DS_FALSE;
83
84   if (!lib3ds_chunk_read_start(&c, LIB3DS_LAYER_FOG, io)) {
85     return(LIB3DS_FALSE);
86   }
87   fog->near_y=lib3ds_io_read_float(io);
88   fog->far_y=lib3ds_io_read_float(io);
89   fog->density=lib3ds_io_read_float(io);
90   fog->flags=lib3ds_io_read_dword(io);
91   lib3ds_chunk_read_tell(&c, io);
92   
93   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
94     switch (chunk) {
95       case LIB3DS_LIN_COLOR_F:
96         lib3ds_io_read_rgb(io, fog->col);
97         have_lin=LIB3DS_TRUE;
98         break;
99       case LIB3DS_COLOR_F:
100         lib3ds_io_read_rgb(io, fog->col);
101         break;
102       default:
103         lib3ds_chunk_unknown(chunk);
104     }
105   }
106   
107   lib3ds_chunk_read_end(&c, io);
108   return(LIB3DS_TRUE);
109 }
110
111
112 static Lib3dsBool
113 distance_cue_read(Lib3dsDistanceCue *cue, Lib3dsIo *io)
114 {
115   Lib3dsChunk c;
116   Lib3dsWord chunk;
117
118   if (!lib3ds_chunk_read_start(&c, LIB3DS_DISTANCE_CUE, io)) {
119     return(LIB3DS_FALSE);
120   }
121   cue->near_plane=lib3ds_io_read_float(io);
122   cue->near_dimming=lib3ds_io_read_float(io);
123   cue->far_plane=lib3ds_io_read_float(io);
124   cue->far_dimming=lib3ds_io_read_float(io);
125   lib3ds_chunk_read_tell(&c, io);
126   
127   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
128     switch (chunk) {
129       case LIB3DS_DCUE_BGND:
130         {
131           cue->cue_background=LIB3DS_TRUE;
132         }
133         break;
134       default:
135         lib3ds_chunk_unknown(chunk);
136     }
137   }
138   
139   lib3ds_chunk_read_end(&c, io);
140   return(LIB3DS_TRUE);
141 }
142
143
144 /*!
145  * \ingroup atmosphere
146  */
147 Lib3dsBool
148 lib3ds_atmosphere_read(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io)
149 {
150   Lib3dsChunk c;
151
152   if (!lib3ds_chunk_read(&c, io)) {
153     return(LIB3DS_FALSE);
154   }
155   
156   switch (c.chunk) {
157       case LIB3DS_FOG:
158         {
159           lib3ds_chunk_read_reset(&c, io);
160           if (!fog_read(&atmosphere->fog, io)) {
161             return(LIB3DS_FALSE);
162           }
163         }
164         break;
165       case LIB3DS_LAYER_FOG:
166         {
167           lib3ds_chunk_read_reset(&c, io);
168           if (!layer_fog_read(&atmosphere->layer_fog, io)) {
169             return(LIB3DS_FALSE);
170           }
171         }
172         break;
173       case LIB3DS_DISTANCE_CUE:
174         {
175           lib3ds_chunk_read_reset(&c, io);
176           if (!distance_cue_read(&atmosphere->dist_cue, io)) {
177             return(LIB3DS_FALSE);
178           }
179         }
180         break;
181       case LIB3DS_USE_FOG:
182         {
183           atmosphere->fog.use=LIB3DS_TRUE;
184         }
185         break;
186       case LIB3DS_USE_LAYER_FOG:
187         {
188           atmosphere->fog.use=LIB3DS_TRUE;
189         }
190         break;
191       case LIB3DS_USE_DISTANCE_CUE:
192         {
193           atmosphere->dist_cue.use=LIB3DS_TRUE;
194         }
195         break;
196   }
197
198   return(LIB3DS_TRUE);
199 }
200
201
202 /*!
203  * \ingroup atmosphere
204  */
205 Lib3dsBool
206 lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io)
207 {
208   if (atmosphere->fog.use) { /*---- LIB3DS_FOG ----*/
209     Lib3dsChunk c;
210     c.chunk=LIB3DS_FOG;
211     if (!lib3ds_chunk_write_start(&c,io)) {
212       return(LIB3DS_FALSE);
213     }
214     lib3ds_io_write_float(io, atmosphere->fog.near_plane);
215     lib3ds_io_write_float(io, atmosphere->fog.near_density);
216     lib3ds_io_write_float(io, atmosphere->fog.far_plane);
217     lib3ds_io_write_float(io, atmosphere->fog.far_density);
218     {
219       Lib3dsChunk c;
220       c.chunk=LIB3DS_COLOR_F;
221       c.size=18;
222       lib3ds_chunk_write(&c,io);
223       lib3ds_io_write_rgb(io, atmosphere->fog.col);
224     }
225     if (atmosphere->fog.fog_background) {
226       Lib3dsChunk c;
227       c.chunk=LIB3DS_FOG_BGND;
228       c.size=6;
229       lib3ds_chunk_write(&c,io);
230     }
231     if (!lib3ds_chunk_write_end(&c,io)) {
232       return(LIB3DS_FALSE);
233     }
234   }
235
236   if (atmosphere->layer_fog.use) { /*---- LIB3DS_LAYER_FOG ----*/
237     Lib3dsChunk c;
238     c.chunk=LIB3DS_LAYER_FOG;
239     c.size=40;
240     lib3ds_chunk_write(&c,io);
241     lib3ds_io_write_float(io, atmosphere->layer_fog.near_y);
242     lib3ds_io_write_float(io, atmosphere->layer_fog.far_y);
243     lib3ds_io_write_float(io, atmosphere->layer_fog.near_y);
244     lib3ds_io_write_dword(io, atmosphere->layer_fog.flags);
245     {
246       Lib3dsChunk c;
247       c.chunk=LIB3DS_COLOR_F;
248       c.size=18;
249       lib3ds_chunk_write(&c,io);
250       lib3ds_io_write_rgb(io, atmosphere->fog.col);
251     }
252   }
253
254   if (atmosphere->dist_cue.use) { /*---- LIB3DS_DISTANCE_CUE ----*/
255     Lib3dsChunk c;
256     c.chunk=LIB3DS_DISTANCE_CUE;
257     if (!lib3ds_chunk_write_start(&c,io)) {
258       return(LIB3DS_FALSE);
259     }
260     lib3ds_io_write_float(io, atmosphere->dist_cue.near_plane);
261     lib3ds_io_write_float(io, atmosphere->dist_cue.near_dimming);
262     lib3ds_io_write_float(io, atmosphere->dist_cue.far_plane);
263     lib3ds_io_write_float(io, atmosphere->dist_cue.far_dimming);
264     if (atmosphere->dist_cue.cue_background) {
265       Lib3dsChunk c;
266       c.chunk=LIB3DS_DCUE_BGND;
267       c.size=6;
268       lib3ds_chunk_write(&c,io);
269     }
270     if (!lib3ds_chunk_write_end(&c,io)) {
271       return(LIB3DS_FALSE);
272     }
273   }
274
275   if (atmosphere->fog.use) { /*---- LIB3DS_USE_FOG ----*/
276     Lib3dsChunk c;
277     c.chunk=LIB3DS_USE_FOG;
278     c.size=6;
279     lib3ds_chunk_write(&c,io);
280   }
281
282   if (atmosphere->layer_fog.use) { /*---- LIB3DS_USE_LAYER_FOG ----*/
283     Lib3dsChunk c;
284     c.chunk=LIB3DS_USE_LAYER_FOG;
285     c.size=6;
286     lib3ds_chunk_write(&c,io);
287   }
288
289   if (atmosphere->dist_cue.use) { /*---- LIB3DS_USE_DISTANCE_CUE ----*/
290     Lib3dsChunk c;
291     c.chunk=LIB3DS_USE_V_GRADIENT;
292     c.size=6;
293     lib3ds_chunk_write(&c,io);
294   }
295   
296   return(LIB3DS_TRUE);
297 }
298
299
300 /*!
301
302 \typedef Lib3dsAtmosphere
303   \ingroup atmosphere
304   \sa _Lib3dsAtmosphere
305
306 */
307