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