]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/mediasource/netradiant-src/libs/picomodel/pm_mdc.c
Move all other sources in a separate subfolder
[voretournament/voretournament.git] / misc / mediasource / netradiant-src / libs / picomodel / pm_mdc.c
1 /* -----------------------------------------------------------------------------
2
3 PicoModel Library 
4
5 Copyright (c) 2002, Randy Reddig & seaw0lf
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without modification,
9 are permitted provided that the following conditions are met:
10
11 Redistributions of source code must retain the above copyright notice, this list
12 of conditions and the following disclaimer.
13
14 Redistributions in binary form must reproduce the above copyright notice, this
15 list of conditions and the following disclaimer in the documentation and/or
16 other materials provided with the distribution.
17
18 Neither the names of the copyright holders nor the names of its contributors may
19 be used to endorse or promote products derived from this software without
20 specific prior written permission. 
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33 ----------------------------------------------------------------------------- */
34
35
36
37 /* marker */
38 #define PM_MDC_C
39
40
41
42 /* dependencies */
43 #include "picointernal.h"
44
45 /* mdc model format */
46 #define MDC_MAGIC                       "IDPC"
47 #define MDC_VERSION                     2
48
49 /* mdc vertex scale */
50 #define MDC_SCALE                       (1.0f / 64.0f)
51 #define MDC_MAX_OFS                     127.0f
52 #define MDC_DIST_SCALE          0.05f
53
54 /* mdc decoding normal table */
55 double mdcNormals[ 256 ][ 3 ] =
56 {
57         { 1.000000, 0.000000, 0.000000 },
58         { 0.980785, 0.195090, 0.000000 },
59         { 0.923880, 0.382683, 0.000000 },
60         { 0.831470, 0.555570, 0.000000 },
61         { 0.707107, 0.707107, 0.000000 },
62         { 0.555570, 0.831470, 0.000000 },
63         { 0.382683, 0.923880, 0.000000 },
64         { 0.195090, 0.980785, 0.000000 },
65         { -0.000000, 1.000000, 0.000000 },
66         { -0.195090, 0.980785, 0.000000 },
67         { -0.382683, 0.923880, 0.000000 },
68         { -0.555570, 0.831470, 0.000000 },
69         { -0.707107, 0.707107, 0.000000 },
70         { -0.831470, 0.555570, 0.000000 },
71         { -0.923880, 0.382683, 0.000000 },
72         { -0.980785, 0.195090, 0.000000 },
73         { -1.000000, -0.000000, 0.000000 },
74         { -0.980785, -0.195090, 0.000000 },
75         { -0.923880, -0.382683, 0.000000 },
76         { -0.831470, -0.555570, 0.000000 },
77         { -0.707107, -0.707107, 0.000000 },
78         { -0.555570, -0.831469, 0.000000 },
79         { -0.382684, -0.923880, 0.000000 },
80         { -0.195090, -0.980785, 0.000000 },
81         { 0.000000, -1.000000, 0.000000 },
82         { 0.195090, -0.980785, 0.000000 },
83         { 0.382684, -0.923879, 0.000000 },
84         { 0.555570, -0.831470, 0.000000 },
85         { 0.707107, -0.707107, 0.000000 },
86         { 0.831470, -0.555570, 0.000000 },
87         { 0.923880, -0.382683, 0.000000 },
88         { 0.980785, -0.195090, 0.000000 },
89         { 0.980785, 0.000000, -0.195090 },
90         { 0.956195, 0.218245, -0.195090 },
91         { 0.883657, 0.425547, -0.195090 },
92         { 0.766809, 0.611510, -0.195090 },
93         { 0.611510, 0.766809, -0.195090 },
94         { 0.425547, 0.883657, -0.195090 },
95         { 0.218245, 0.956195, -0.195090 },
96         { -0.000000, 0.980785, -0.195090 },
97         { -0.218245, 0.956195, -0.195090 },
98         { -0.425547, 0.883657, -0.195090 },
99         { -0.611510, 0.766809, -0.195090 },
100         { -0.766809, 0.611510, -0.195090 },
101         { -0.883657, 0.425547, -0.195090 },
102         { -0.956195, 0.218245, -0.195090 },
103         { -0.980785, -0.000000, -0.195090 },
104         { -0.956195, -0.218245, -0.195090 },
105         { -0.883657, -0.425547, -0.195090 },
106         { -0.766809, -0.611510, -0.195090 },
107         { -0.611510, -0.766809, -0.195090 },
108         { -0.425547, -0.883657, -0.195090 },
109         { -0.218245, -0.956195, -0.195090 },
110         { 0.000000, -0.980785, -0.195090 },
111         { 0.218245, -0.956195, -0.195090 },
112         { 0.425547, -0.883657, -0.195090 },
113         { 0.611510, -0.766809, -0.195090 },
114         { 0.766809, -0.611510, -0.195090 },
115         { 0.883657, -0.425547, -0.195090 },
116         { 0.956195, -0.218245, -0.195090 },
117         { 0.923880, 0.000000, -0.382683 },
118         { 0.892399, 0.239118, -0.382683 },
119         { 0.800103, 0.461940, -0.382683 },
120         { 0.653281, 0.653281, -0.382683 },
121         { 0.461940, 0.800103, -0.382683 },
122         { 0.239118, 0.892399, -0.382683 },
123         { -0.000000, 0.923880, -0.382683 },
124         { -0.239118, 0.892399, -0.382683 },
125         { -0.461940, 0.800103, -0.382683 },
126         { -0.653281, 0.653281, -0.382683 },
127         { -0.800103, 0.461940, -0.382683 },
128         { -0.892399, 0.239118, -0.382683 },
129         { -0.923880, -0.000000, -0.382683 },
130         { -0.892399, -0.239118, -0.382683 },
131         { -0.800103, -0.461940, -0.382683 },
132         { -0.653282, -0.653281, -0.382683 },
133         { -0.461940, -0.800103, -0.382683 },
134         { -0.239118, -0.892399, -0.382683 },
135         { 0.000000, -0.923880, -0.382683 },
136         { 0.239118, -0.892399, -0.382683 },
137         { 0.461940, -0.800103, -0.382683 },
138         { 0.653281, -0.653282, -0.382683 },
139         { 0.800103, -0.461940, -0.382683 },
140         { 0.892399, -0.239117, -0.382683 },
141         { 0.831470, 0.000000, -0.555570 },
142         { 0.790775, 0.256938, -0.555570 },
143         { 0.672673, 0.488726, -0.555570 },
144         { 0.488726, 0.672673, -0.555570 },
145         { 0.256938, 0.790775, -0.555570 },
146         { -0.000000, 0.831470, -0.555570 },
147         { -0.256938, 0.790775, -0.555570 },
148         { -0.488726, 0.672673, -0.555570 },
149         { -0.672673, 0.488726, -0.555570 },
150         { -0.790775, 0.256938, -0.555570 },
151         { -0.831470, -0.000000, -0.555570 },
152         { -0.790775, -0.256938, -0.555570 },
153         { -0.672673, -0.488726, -0.555570 },
154         { -0.488725, -0.672673, -0.555570 },
155         { -0.256938, -0.790775, -0.555570 },
156         { 0.000000, -0.831470, -0.555570 },
157         { 0.256938, -0.790775, -0.555570 },
158         { 0.488725, -0.672673, -0.555570 },
159         { 0.672673, -0.488726, -0.555570 },
160         { 0.790775, -0.256938, -0.555570 },
161         { 0.707107, 0.000000, -0.707107 },
162         { 0.653281, 0.270598, -0.707107 },
163         { 0.500000, 0.500000, -0.707107 },
164         { 0.270598, 0.653281, -0.707107 },
165         { -0.000000, 0.707107, -0.707107 },
166         { -0.270598, 0.653282, -0.707107 },
167         { -0.500000, 0.500000, -0.707107 },
168         { -0.653281, 0.270598, -0.707107 },
169         { -0.707107, -0.000000, -0.707107 },
170         { -0.653281, -0.270598, -0.707107 },
171         { -0.500000, -0.500000, -0.707107 },
172         { -0.270598, -0.653281, -0.707107 },
173         { 0.000000, -0.707107, -0.707107 },
174         { 0.270598, -0.653281, -0.707107 },
175         { 0.500000, -0.500000, -0.707107 },
176         { 0.653282, -0.270598, -0.707107 },
177         { 0.555570, 0.000000, -0.831470 },
178         { 0.481138, 0.277785, -0.831470 },
179         { 0.277785, 0.481138, -0.831470 },
180         { -0.000000, 0.555570, -0.831470 },
181         { -0.277785, 0.481138, -0.831470 },
182         { -0.481138, 0.277785, -0.831470 },
183         { -0.555570, -0.000000, -0.831470 },
184         { -0.481138, -0.277785, -0.831470 },
185         { -0.277785, -0.481138, -0.831470 },
186         { 0.000000, -0.555570, -0.831470 },
187         { 0.277785, -0.481138, -0.831470 },
188         { 0.481138, -0.277785, -0.831470 },
189         { 0.382683, 0.000000, -0.923880 },
190         { 0.270598, 0.270598, -0.923880 },
191         { -0.000000, 0.382683, -0.923880 },
192         { -0.270598, 0.270598, -0.923880 },
193         { -0.382683, -0.000000, -0.923880 },
194         { -0.270598, -0.270598, -0.923880 },
195         { 0.000000, -0.382683, -0.923880 },
196         { 0.270598, -0.270598, -0.923880 },
197         { 0.195090, 0.000000, -0.980785 },
198         { -0.000000, 0.195090, -0.980785 },
199         { -0.195090, -0.000000, -0.980785 },
200         { 0.000000, -0.195090, -0.980785 },
201         { 0.980785, 0.000000, 0.195090 },
202         { 0.956195, 0.218245, 0.195090 },
203         { 0.883657, 0.425547, 0.195090 },
204         { 0.766809, 0.611510, 0.195090 },
205         { 0.611510, 0.766809, 0.195090 },
206         { 0.425547, 0.883657, 0.195090 },
207         { 0.218245, 0.956195, 0.195090 },
208         { -0.000000, 0.980785, 0.195090 },
209         { -0.218245, 0.956195, 0.195090 },
210         { -0.425547, 0.883657, 0.195090 },
211         { -0.611510, 0.766809, 0.195090 },
212         { -0.766809, 0.611510, 0.195090 },
213         { -0.883657, 0.425547, 0.195090 },
214         { -0.956195, 0.218245, 0.195090 },
215         { -0.980785, -0.000000, 0.195090 },
216         { -0.956195, -0.218245, 0.195090 },
217         { -0.883657, -0.425547, 0.195090 },
218         { -0.766809, -0.611510, 0.195090 },
219         { -0.611510, -0.766809, 0.195090 },
220         { -0.425547, -0.883657, 0.195090 },
221         { -0.218245, -0.956195, 0.195090 },
222         { 0.000000, -0.980785, 0.195090 },
223         { 0.218245, -0.956195, 0.195090 },
224         { 0.425547, -0.883657, 0.195090 },
225         { 0.611510, -0.766809, 0.195090 },
226         { 0.766809, -0.611510, 0.195090 },
227         { 0.883657, -0.425547, 0.195090 },
228         { 0.956195, -0.218245, 0.195090 },
229         { 0.923880, 0.000000, 0.382683 },
230         { 0.892399, 0.239118, 0.382683 },
231         { 0.800103, 0.461940, 0.382683 },
232         { 0.653281, 0.653281, 0.382683 },
233         { 0.461940, 0.800103, 0.382683 },
234         { 0.239118, 0.892399, 0.382683 },
235         { -0.000000, 0.923880, 0.382683 },
236         { -0.239118, 0.892399, 0.382683 },
237         { -0.461940, 0.800103, 0.382683 },
238         { -0.653281, 0.653281, 0.382683 },
239         { -0.800103, 0.461940, 0.382683 },
240         { -0.892399, 0.239118, 0.382683 },
241         { -0.923880, -0.000000, 0.382683 },
242         { -0.892399, -0.239118, 0.382683 },
243         { -0.800103, -0.461940, 0.382683 },
244         { -0.653282, -0.653281, 0.382683 },
245         { -0.461940, -0.800103, 0.382683 },
246         { -0.239118, -0.892399, 0.382683 },
247         { 0.000000, -0.923880, 0.382683 },
248         { 0.239118, -0.892399, 0.382683 },
249         { 0.461940, -0.800103, 0.382683 },
250         { 0.653281, -0.653282, 0.382683 },
251         { 0.800103, -0.461940, 0.382683 },
252         { 0.892399, -0.239117, 0.382683 },
253         { 0.831470, 0.000000, 0.555570 },
254         { 0.790775, 0.256938, 0.555570 },
255         { 0.672673, 0.488726, 0.555570 },
256         { 0.488726, 0.672673, 0.555570 },
257         { 0.256938, 0.790775, 0.555570 },
258         { -0.000000, 0.831470, 0.555570 },
259         { -0.256938, 0.790775, 0.555570 },
260         { -0.488726, 0.672673, 0.555570 },
261         { -0.672673, 0.488726, 0.555570 },
262         { -0.790775, 0.256938, 0.555570 },
263         { -0.831470, -0.000000, 0.555570 },
264         { -0.790775, -0.256938, 0.555570 },
265         { -0.672673, -0.488726, 0.555570 },
266         { -0.488725, -0.672673, 0.555570 },
267         { -0.256938, -0.790775, 0.555570 },
268         { 0.000000, -0.831470, 0.555570 },
269         { 0.256938, -0.790775, 0.555570 },
270         { 0.488725, -0.672673, 0.555570 },
271         { 0.672673, -0.488726, 0.555570 },
272         { 0.790775, -0.256938, 0.555570 },
273         { 0.707107, 0.000000, 0.707107 },
274         { 0.653281, 0.270598, 0.707107 },
275         { 0.500000, 0.500000, 0.707107 },
276         { 0.270598, 0.653281, 0.707107 },
277         { -0.000000, 0.707107, 0.707107 },
278         { -0.270598, 0.653282, 0.707107 },
279         { -0.500000, 0.500000, 0.707107 },
280         { -0.653281, 0.270598, 0.707107 },
281         { -0.707107, -0.000000, 0.707107 },
282         { -0.653281, -0.270598, 0.707107 },
283         { -0.500000, -0.500000, 0.707107 },
284         { -0.270598, -0.653281, 0.707107 },
285         { 0.000000, -0.707107, 0.707107 },
286         { 0.270598, -0.653281, 0.707107 },
287         { 0.500000, -0.500000, 0.707107 },
288         { 0.653282, -0.270598, 0.707107 },
289         { 0.555570, 0.000000, 0.831470 },
290         { 0.481138, 0.277785, 0.831470 },
291         { 0.277785, 0.481138, 0.831470 },
292         { -0.000000, 0.555570, 0.831470 },
293         { -0.277785, 0.481138, 0.831470 },
294         { -0.481138, 0.277785, 0.831470 },
295         { -0.555570, -0.000000, 0.831470 },
296         { -0.481138, -0.277785, 0.831470 },
297         { -0.277785, -0.481138, 0.831470 },
298         { 0.000000, -0.555570, 0.831470 },
299         { 0.277785, -0.481138, 0.831470 },
300         { 0.481138, -0.277785, 0.831470 },
301         { 0.382683, 0.000000, 0.923880 },
302         { 0.270598, 0.270598, 0.923880 },
303         { -0.000000, 0.382683, 0.923880 },
304         { -0.270598, 0.270598, 0.923880 },
305         { -0.382683, -0.000000, 0.923880 },
306         { -0.270598, -0.270598, 0.923880 },
307         { 0.000000, -0.382683, 0.923880 },
308         { 0.270598, -0.270598, 0.923880 },
309         { 0.195090, 0.000000, 0.980785 },
310         { -0.000000, 0.195090, 0.980785 },
311         { -0.195090, -0.000000, 0.980785 },
312         { 0.000000, -0.195090, 0.980785 }
313 };
314
315 /* mdc model frame information */
316 typedef struct mdcFrame_s
317 {
318         float           bounds[ 2 ][ 3 ];
319         float           localOrigin[ 3 ];
320         float           radius;
321         char            creator[ 16 ];
322 }
323 mdcFrame_t;
324
325 /* mdc model tag information */
326 typedef struct mdcTag_s
327 {
328         short           xyz[3];
329         short           angles[3];
330 }
331 mdcTag_t;
332
333 /* mdc surface mdc (one object mesh) */
334 typedef struct mdcSurface_s
335 {
336         char            magic[ 4 ];
337         char            name[ 64 ];                     /* polyset name */
338         int                     flags;
339         int                     numCompFrames;          /* all surfaces in a model should have the same */
340         int                     numBaseFrames;          /* ditto */
341         int                     numShaders;                     /* all model surfaces should have the same */
342         int                     numVerts;
343         int                     numTriangles;
344         int                     ofsTriangles;
345         int                     ofsShaders;                     /* offset from start of mdcSurface_t */
346         int                     ofsSt;                          /* texture coords are common for all frames */
347         int                     ofsXyzNormals;          /* numVerts * numBaseFrames */
348         int                     ofsXyzCompressed;       /* numVerts * numCompFrames */
349
350         int                     ofsFrameBaseFrames;     /* numFrames */
351         int                     ofsFrameCompFrames;     /* numFrames */
352         int                     ofsEnd;                         /* next surface follows */
353 }
354 mdcSurface_t;
355
356 typedef struct mdcShader_s
357 {
358         char            name[ 64 ];
359         int                     shaderIndex;    /* for ingame use */
360 }
361 mdcShader_t;
362
363 typedef struct mdcTriangle_s
364 {
365         int                     indexes[ 3 ];
366 }
367 mdcTriangle_t;
368
369 typedef struct mdcTexCoord_s
370 {
371         float           st[ 2 ];
372 }
373 mdcTexCoord_t;
374
375 typedef struct mdcVertex_s
376 {
377         short           xyz[ 3 ];
378         short           normal;
379 }
380 mdcVertex_t;
381
382 typedef struct mdcXyzCompressed_s
383 {
384         unsigned int    ofsVec;         /* offset direction from the last base frame */
385 }
386 mdcXyzCompressed_t;
387
388
389 /* mdc model file mdc structure */
390 typedef struct mdc_s
391 {
392         char            magic[ 4 ];             /* MDC_MAGIC */
393         int                     version;
394         char            name[ 64 ];             /* model name */
395         int                     flags;
396         int                     numFrames;
397         int                     numTags;
398         int                     numSurfaces;
399         int                     numSkins;               /* number of skins for the mesh */
400         int                     ofsFrames;              /* offset for first frame */
401         int                     ofsTagNames;    /* numTags */
402         int                     ofsTags;                /* numFrames * numTags */
403         int                     ofsSurfaces;    /* first surface, others follow */
404         int                     ofsEnd;                 /* end of file */
405 }
406 mdc_t;
407
408
409
410
411 /*
412 _mdc_canload()
413 validates a Return to Castle Wolfenstein model file. btw, i use the
414 preceding underscore cause it's a static func referenced
415 by one structure only.
416 */
417
418 static int _mdc_canload( PM_PARAMS_CANLOAD )
419 {
420         const mdc_t     *mdc;
421         
422         
423         /* sanity check */
424         if( (size_t) bufSize < ( sizeof( *mdc ) * 2) )
425                 return PICO_PMV_ERROR_SIZE;
426         
427         /* set as mdc */
428         mdc     = (const mdc_t*) buffer;
429         
430         /* check mdc magic */
431         if( *((const int*) mdc->magic) != *((const int*) MDC_MAGIC) ) 
432                 return PICO_PMV_ERROR_IDENT;
433         
434         /* check mdc version */
435         if( _pico_little_long( mdc->version ) != MDC_VERSION )
436                 return PICO_PMV_ERROR_VERSION;
437         
438         /* file seems to be a valid mdc */
439         return PICO_PMV_OK;
440 }
441
442
443
444 /*
445 _mdc_load()
446 loads a Return to Castle Wolfenstein mdc model file.
447 */
448
449 static picoModel_t *_mdc_load( PM_PARAMS_LOAD )
450 {
451         int                                     i, j;
452         picoByte_t                      *bb, *bb0;
453         mdc_t                           *mdc;
454         mdcSurface_t            *surface;
455         mdcShader_t                     *shader;
456         mdcTexCoord_t           *texCoord;
457         mdcFrame_t                      *frame;
458         mdcTriangle_t           *triangle;
459         mdcVertex_t                     *vertex;
460         mdcXyzCompressed_t      *vertexComp = NULL;
461         short                           *mdcShort, *mdcCompVert = NULL;
462         double                          lat, lng;
463         
464         picoModel_t                     *picoModel;
465         picoSurface_t           *picoSurface;
466         picoShader_t            *picoShader;
467         picoVec3_t                      xyz, normal;
468         picoVec2_t                      st;
469         picoColor_t                     color;
470         
471         
472         /* -------------------------------------------------
473         mdc loading
474         ------------------------------------------------- */
475
476
477         /* set as mdc */
478         bb0 = bb = (picoByte_t*) _pico_alloc(bufSize);
479         memcpy(bb, buffer, bufSize);
480         mdc     = (mdc_t*) bb;
481         
482         /* check ident and version */
483         if( *((int*) mdc->magic) != *((int*) MDC_MAGIC) || _pico_little_long( mdc->version ) != MDC_VERSION )
484         {
485                 /* not an mdc file (todo: set error) */
486                 _pico_free(bb0);
487                 return NULL;
488         }
489         
490         /* swap mdc */
491         mdc->version = _pico_little_long( mdc->version );
492         mdc->numFrames = _pico_little_long( mdc->numFrames );
493         mdc->numTags = _pico_little_long( mdc->numTags );
494         mdc->numSurfaces = _pico_little_long( mdc->numSurfaces );
495         mdc->numSkins = _pico_little_long( mdc->numSkins );
496         mdc->ofsFrames = _pico_little_long( mdc->ofsFrames );
497         mdc->ofsTags = _pico_little_long( mdc->ofsTags );
498         mdc->ofsTagNames = _pico_little_long( mdc->ofsTagNames );
499         mdc->ofsSurfaces = _pico_little_long( mdc->ofsSurfaces );
500         mdc->ofsEnd = _pico_little_long( mdc->ofsEnd );
501         
502         /* do frame check */
503         if( mdc->numFrames < 1 )
504         {
505                 _pico_printf( PICO_ERROR, "MDC with 0 frames" );
506                 _pico_free(bb0);
507                 return NULL;
508         }
509         
510         if( frameNum < 0 || frameNum >= mdc->numFrames )
511         {
512                 _pico_printf( PICO_ERROR, "Invalid or out-of-range MDC frame specified" );
513                 _pico_free(bb0);
514                 return NULL;
515         }
516         
517         /* swap frames */
518         frame = (mdcFrame_t*) (bb + mdc->ofsFrames );
519         for( i = 0; i < mdc->numFrames; i++, frame++ )
520         {
521                 frame->radius = _pico_little_float( frame->radius );
522                 for( j = 0; j < 3; j++ )
523                 {
524                         frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
525                         frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
526                         frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
527                 }
528         }
529         
530         /* swap surfaces */
531         surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
532         for( i = 0; i < mdc->numSurfaces; i++ )
533         {
534                 /* swap surface mdc */
535                 surface->flags = _pico_little_long( surface->flags );
536                 surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
537                 surface->numCompFrames = _pico_little_long( surface->numCompFrames );
538                 surface->numShaders = _pico_little_long( surface->numShaders );
539                 surface->numTriangles = _pico_little_long( surface->numTriangles );
540                 surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
541                 surface->numVerts = _pico_little_long( surface->numVerts );
542                 surface->ofsShaders = _pico_little_long( surface->ofsShaders );
543                 surface->ofsSt = _pico_little_long( surface->ofsSt );
544                 surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
545                 surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
546                 surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
547                 surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
548                 surface->ofsEnd = _pico_little_long( surface->ofsEnd );
549                 
550                 /* swap triangles */
551                 triangle = (mdcTriangle_t*) ((picoByte_t*) surface + surface->ofsTriangles);
552                 for( j = 0; j < surface->numTriangles; j++, triangle++ )
553                 {
554                         /* sea: swaps fixed */
555                         triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
556                         triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
557                         triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
558                 }
559                 
560                 /* swap st coords */
561                 texCoord = (mdcTexCoord_t*) ((picoByte_t*) surface + surface->ofsSt);
562                 for( j = 0; j < surface->numVerts; j++, texCoord++ )
563                 {
564                         texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
565                         texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
566                 }
567                 
568                 /* swap xyz/normals */
569                 vertex = (mdcVertex_t*) ((picoByte_t*) surface + surface->ofsXyzNormals);
570                 for( j = 0; j < (surface->numVerts * surface->numBaseFrames); j++, vertex++)
571                 {
572                         vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
573                         vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
574                         vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
575                         vertex->normal   = _pico_little_short( vertex->normal );
576                 }
577
578                 /* swap xyz/compressed */
579                 vertexComp = (mdcXyzCompressed_t*) ((picoByte_t*) surface + surface->ofsXyzCompressed);
580                 for( j = 0; j < (surface->numVerts * surface->numCompFrames); j++, vertexComp++)
581                 {
582                         vertexComp->ofsVec      = _pico_little_long( vertexComp->ofsVec );
583                 }
584
585                 /* swap base frames */
586                 mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameBaseFrames);
587                 for( j = 0; j < mdc->numFrames; j++, mdcShort++)
588                 {
589                         *mdcShort       = _pico_little_short( *mdcShort );
590                 }
591
592                 /* swap compressed frames */
593                 mdcShort = (short *) ((picoByte_t*) surface + surface->ofsFrameCompFrames);
594                 for( j = 0; j < mdc->numFrames; j++, mdcShort++)
595                 {
596                         *mdcShort       = _pico_little_short( *mdcShort );
597                 }
598                 
599                 /* get next surface */
600                 surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
601         }
602         
603         /* -------------------------------------------------
604         pico model creation
605         ------------------------------------------------- */
606         
607         /* create new pico model */
608         picoModel = PicoNewModel();
609         if( picoModel == NULL )
610         {
611                 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
612                 _pico_free(bb0);
613                 return NULL;
614         }
615         
616         /* do model setup */
617         PicoSetModelFrameNum( picoModel, frameNum );
618         PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
619         PicoSetModelName( picoModel, fileName );
620         PicoSetModelFileName( picoModel, fileName );
621         
622         /* mdc surfaces become picomodel surfaces */
623         surface = (mdcSurface_t*) (bb + mdc->ofsSurfaces);
624         
625         /* run through mdc surfaces */
626         for( i = 0; i < mdc->numSurfaces; i++ )
627         {
628                 /* allocate new pico surface */
629                 picoSurface = PicoNewSurface( picoModel );
630                 if( picoSurface == NULL )
631                 {
632                         _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
633                         PicoFreeModel( picoModel ); /* sea */
634                         _pico_free(bb0);
635                         return NULL;
636                 }
637                 
638                 /* mdc model surfaces are all triangle meshes */
639                 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
640                 
641                 /* set surface name */
642                 PicoSetSurfaceName( picoSurface, surface->name );
643                 
644                 /* create new pico shader -sea */
645                 picoShader = PicoNewShader( picoModel );
646                 if( picoShader == NULL )
647                 {
648                         _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
649                         PicoFreeModel( picoModel );
650                         _pico_free(bb0);
651                         return NULL;
652                 }
653                 
654                 /* detox and set shader name */
655                 shader = (mdcShader_t*) ((picoByte_t*) surface + surface->ofsShaders);
656                 _pico_setfext( shader->name, "" );
657                 _pico_unixify( shader->name );
658                 PicoSetShaderName( picoShader, shader->name );
659                 
660                 /* associate current surface with newly created shader */
661                 PicoSetSurfaceShader( picoSurface, picoShader );
662                 
663                 /* copy indexes */
664                 triangle = (mdcTriangle_t *) ((picoByte_t*) surface + surface->ofsTriangles);
665                 
666                 for( j = 0; j < surface->numTriangles; j++, triangle++ )
667                 {
668                         PicoSetSurfaceIndex( picoSurface, (j * 3 + 0), (picoIndex_t) triangle->indexes[ 0 ] );
669                         PicoSetSurfaceIndex( picoSurface, (j * 3 + 1), (picoIndex_t) triangle->indexes[ 1 ] );
670                         PicoSetSurfaceIndex( picoSurface, (j * 3 + 2), (picoIndex_t) triangle->indexes[ 2 ] );
671                 }
672                 
673                 /* copy vertexes */
674                 texCoord = (mdcTexCoord_t*) ((picoByte_t *) surface + surface->ofsSt);
675     mdcShort = (short *) ((picoByte_t *) surface + surface->ofsXyzNormals) + ((int)*((short *) ((picoByte_t *) surface + surface->ofsFrameBaseFrames) + frameNum) * surface->numVerts * 4);
676                 if( surface->numCompFrames > 0 )
677                 {
678                         mdcCompVert = (short *) ((picoByte_t *) surface + surface->ofsFrameCompFrames) + frameNum;
679                         if( *mdcCompVert >= 0 )
680                                 vertexComp = (mdcXyzCompressed_t *) ((picoByte_t *) surface + surface->ofsXyzCompressed) + (*mdcCompVert * surface->numVerts);
681                 }
682                 _pico_set_color( color, 255, 255, 255, 255 );
683                 
684                 for( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort+=4 )
685                 {
686                         /* set vertex origin */
687                         xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
688                         xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
689                         xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
690
691                         /* add compressed ofsVec */
692                         if( surface->numCompFrames > 0 && *mdcCompVert >= 0 )
693                         {               
694                                 xyz[ 0 ] += ((float) ((vertexComp->ofsVec) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
695                                 xyz[ 1 ] += ((float) ((vertexComp->ofsVec >> 8) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
696                                 xyz[ 2 ] += ((float) ((vertexComp->ofsVec >> 16) & 255) - MDC_MAX_OFS) * MDC_DIST_SCALE;
697                                 PicoSetSurfaceXYZ( picoSurface, j, xyz );
698
699                                 normal[ 0 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 0 ];
700                                 normal[ 1 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 1 ];
701                                 normal[ 2 ] = (float) mdcNormals[ (vertexComp->ofsVec >> 24) ][ 2 ];
702                                 PicoSetSurfaceNormal( picoSurface, j, normal );
703
704                                 vertexComp++;
705                         }
706                         else
707                         {                       
708                                 PicoSetSurfaceXYZ( picoSurface, j, xyz );
709
710                                 /* decode lat/lng normal to 3 float normal */
711                                 lat = (float) ((*(mdcShort + 3) >> 8) & 0xff);
712                                 lng = (float) (*(mdcShort + 3) & 0xff);
713                                 lat *= PICO_PI / 128;
714                                 lng *= PICO_PI / 128;
715                                 normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
716                                 normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
717                                 normal[ 2 ] = (picoVec_t) cos( lng );
718                                 PicoSetSurfaceNormal( picoSurface, j, normal );
719                         }
720                         
721                         /* set st coords */
722                         st[ 0 ] = texCoord->st[ 0 ];
723                         st[ 1 ] = texCoord->st[ 1 ];
724                         PicoSetSurfaceST( picoSurface, 0, j, st );
725
726                         /* set color */
727                         PicoSetSurfaceColor( picoSurface, 0, j, color );
728                 }
729                 
730                 /* get next surface */
731                 surface = (mdcSurface_t*) ((picoByte_t*) surface + surface->ofsEnd);
732         }
733         
734         /* return the new pico model */
735         _pico_free(bb0);
736         return picoModel;
737 }
738
739
740
741 /* pico file format module definition */
742 const picoModule_t picoModuleMDC =
743 {
744         "1.3",                                                  /* module version string */
745         "RtCW MDC",                                             /* module display name */
746         "Arnout van Meer",                              /* author's name */
747         "2002 Arnout van Meer",                 /* module copyright */
748         {
749                 "mdc", NULL, NULL, NULL         /* default extensions to use */
750         },
751         _mdc_canload,                                   /* validation routine */
752         _mdc_load,                                              /* load routine */
753          NULL,                                                  /* save validation routine */
754          NULL                                                   /* save routine */
755 };