added 3dengfx into the repo, probably not the correct version for this
[summerhack] / src / 3dengfx / libs / lib3ds / background.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: background.c,v 1.8 2001/07/07 19:05:30 jeh Exp $
21  */
22 #define LIB3DS_EXPORT
23 #include <lib3ds/background.h>
24 #include <lib3ds/chunk.h>
25 #include <lib3ds/io.h>
26 #include <string.h>
27 #include <math.h>
28
29
30 /*!
31  * \defgroup background Background Settings
32  *
33  * \author J.E. Hoffmann <je-h@gmx.net>
34  */
35
36
37 static Lib3dsBool
38 solid_bgnd_read(Lib3dsBackground *background, Lib3dsIo *io)
39 {
40   Lib3dsChunk c;
41   Lib3dsWord chunk;
42   Lib3dsBool have_lin=LIB3DS_FALSE;
43           
44   if (!lib3ds_chunk_read_start(&c, LIB3DS_SOLID_BGND, io)) {
45     return(LIB3DS_FALSE);
46   }
47
48   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
49     switch (chunk) {
50       case LIB3DS_LIN_COLOR_F:
51         lib3ds_io_read_rgb(io, background->solid.col);
52         have_lin=LIB3DS_TRUE;
53         break;
54       case LIB3DS_COLOR_F:
55         lib3ds_io_read_rgb(io, background->solid.col);
56         break;
57       default:
58         lib3ds_chunk_unknown(chunk);
59     }
60   }
61   
62   lib3ds_chunk_read_end(&c, io);
63   return(LIB3DS_TRUE);
64 }
65
66
67 static Lib3dsBool
68 v_gradient_read(Lib3dsBackground *background, Lib3dsIo *io)
69 {
70   Lib3dsChunk c;
71   Lib3dsWord chunk;
72   int index[2];
73   Lib3dsRgb col[2][3];
74   int have_lin=0;
75   
76
77   if (!lib3ds_chunk_read_start(&c, LIB3DS_V_GRADIENT, io)) {
78     return(LIB3DS_FALSE);
79   }
80   background->gradient.percent=lib3ds_io_read_float(io);
81   lib3ds_chunk_read_tell(&c, io);
82
83   index[0]=index[1]=0;
84   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
85     switch (chunk) {
86       case LIB3DS_COLOR_F:
87         lib3ds_io_read_rgb(io, col[0][index[0]]);
88         index[0]++;
89         break;
90       case LIB3DS_LIN_COLOR_F:
91         lib3ds_io_read_rgb(io, col[1][index[1]]);
92         index[1]++;
93         have_lin=1;
94         break;
95       default:
96         lib3ds_chunk_unknown(chunk);
97     }
98   }
99   {
100     int i;
101     for (i=0; i<3; ++i) {
102       background->gradient.top[i]=col[have_lin][0][i];
103       background->gradient.middle[i]=col[have_lin][1][i];
104       background->gradient.bottom[i]=col[have_lin][2][i];
105     }
106   }
107   lib3ds_chunk_read_end(&c, io);
108   return(LIB3DS_TRUE);
109 }
110
111
112 /*!
113  * \ingroup background
114  */
115 Lib3dsBool
116 lib3ds_background_read(Lib3dsBackground *background, Lib3dsIo *io)
117 {
118   Lib3dsChunk c;
119
120   if (!lib3ds_chunk_read(&c, io)) {
121     return(LIB3DS_FALSE);
122   }
123   
124   switch (c.chunk) {
125     case LIB3DS_BIT_MAP:
126       {
127         if (!lib3ds_io_read_string(io, background->bitmap.name, 64)) {
128             return(LIB3DS_FALSE);
129         }
130       }
131       break;
132     case LIB3DS_SOLID_BGND:
133       {
134         lib3ds_chunk_read_reset(&c, io);
135         if (!solid_bgnd_read(background, io)) {
136           return(LIB3DS_FALSE);
137         }
138       }
139       break;
140     case LIB3DS_V_GRADIENT:
141       {
142         lib3ds_chunk_read_reset(&c, io);
143         if (!v_gradient_read(background, io)) {
144           return(LIB3DS_FALSE);
145         }
146       }
147       break;
148     case LIB3DS_USE_BIT_MAP:
149       {
150         background->bitmap.use=LIB3DS_TRUE;
151       }
152       break;
153     case LIB3DS_USE_SOLID_BGND:
154       {
155         background->solid.use=LIB3DS_TRUE;
156       }
157       break;
158     case LIB3DS_USE_V_GRADIENT:
159       {
160         background->gradient.use=LIB3DS_TRUE;
161       }
162       break;
163   }
164   
165   return(LIB3DS_TRUE);
166 }
167
168
169 static Lib3dsBool
170 colorf_write(Lib3dsRgba rgb, Lib3dsIo *io)
171 {
172   Lib3dsChunk c;
173
174   c.chunk=LIB3DS_COLOR_F;
175   c.size=18;
176   lib3ds_chunk_write(&c,io);
177   lib3ds_io_write_rgb(io, rgb);
178
179   c.chunk=LIB3DS_LIN_COLOR_F;
180   c.size=18;
181   lib3ds_chunk_write(&c,io);
182   lib3ds_io_write_rgb(io, rgb);
183   return(LIB3DS_TRUE);
184 }
185
186
187 static Lib3dsBool
188 colorf_defined(Lib3dsRgba rgb)
189 {
190   int i;
191   for (i=0; i<3; ++i) {
192     if (fabs(rgb[i])>LIB3DS_EPSILON) {
193       break;
194     }
195   }
196   return(i<3);
197 }
198
199
200 /*!
201  * \ingroup background
202  */
203 Lib3dsBool
204 lib3ds_background_write(Lib3dsBackground *background, Lib3dsIo *io)
205 {
206   if (strlen(background->bitmap.name)) { /*---- LIB3DS_BIT_MAP ----*/
207     Lib3dsChunk c;
208     c.chunk=LIB3DS_BIT_MAP;
209     c.size=6+1+strlen(background->bitmap.name);
210     lib3ds_chunk_write(&c,io);
211     lib3ds_io_write_string(io, background->bitmap.name);
212   }
213
214   if (colorf_defined(background->solid.col)) { /*---- LIB3DS_SOLID_BGND ----*/
215     Lib3dsChunk c;
216     c.chunk=LIB3DS_SOLID_BGND;
217     c.size=42;
218     lib3ds_chunk_write(&c,io);
219     colorf_write(background->solid.col, io);
220   }
221
222   if (colorf_defined(background->gradient.top) ||
223     colorf_defined(background->gradient.middle) ||
224     colorf_defined(background->gradient.bottom)) { /*---- LIB3DS_V_GRADIENT ----*/
225     Lib3dsChunk c;
226     c.chunk=LIB3DS_V_GRADIENT;
227     c.size=118;
228     lib3ds_chunk_write(&c,io);
229     lib3ds_io_write_float(io, background->gradient.percent);
230     colorf_write(background->gradient.top,io);
231     colorf_write(background->gradient.middle,io);
232     colorf_write(background->gradient.bottom,io);
233   }
234
235   if (background->bitmap.use) { /*---- LIB3DS_USE_BIT_MAP ----*/
236     Lib3dsChunk c;
237     c.chunk=LIB3DS_USE_BIT_MAP;
238     c.size=6;
239     lib3ds_chunk_write(&c,io);
240   }
241
242   if (background->solid.use) { /*---- LIB3DS_USE_SOLID_BGND ----*/
243     Lib3dsChunk c;
244     c.chunk=LIB3DS_USE_SOLID_BGND;
245     c.size=6;
246     lib3ds_chunk_write(&c,io);
247   }
248
249   if (background->gradient.use) { /*---- LIB3DS_USE_V_GRADIENT ----*/
250     Lib3dsChunk c;
251     c.chunk=LIB3DS_USE_V_GRADIENT;
252     c.size=6;
253     lib3ds_chunk_write(&c,io);
254   }
255   
256   return(LIB3DS_TRUE);
257 }
258
259
260 /*!
261
262 \typedef Lib3dsBackground
263   \ingroup background
264   \sa _Lib3dsBackground
265
266 */