]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/picomodel/pm_mdc.c
Merge branch 'master' into divVerent/farplanedist-sky-fix
[xonotic/netradiant.git] / 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         const mdc_t *mdc;
420
421
422         /* sanity check */
423         if ( (size_t) bufSize < ( sizeof( *mdc ) * 2 ) ) {
424                 return PICO_PMV_ERROR_SIZE;
425         }
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
435         /* check mdc version */
436         if ( _pico_little_long( mdc->version ) != MDC_VERSION ) {
437                 return PICO_PMV_ERROR_VERSION;
438         }
439
440         /* file seems to be a valid mdc */
441         return PICO_PMV_OK;
442 }
443
444
445
446 /*
447    _mdc_load()
448    loads a Return to Castle Wolfenstein mdc model file.
449  */
450
451 static picoModel_t *_mdc_load( PM_PARAMS_LOAD ){
452         int i, j;
453         picoByte_t          *bb, *bb0;
454         mdc_t               *mdc;
455         mdcSurface_t        *surface;
456         mdcShader_t         *shader;
457         mdcTexCoord_t       *texCoord;
458         mdcFrame_t          *frame;
459         mdcTriangle_t       *triangle;
460         mdcVertex_t         *vertex;
461         mdcXyzCompressed_t  *vertexComp = NULL;
462         short               *mdcShort, *mdcCompVert = NULL;
463         double lat, lng;
464
465         picoModel_t         *picoModel;
466         picoSurface_t       *picoSurface;
467         picoShader_t        *picoShader;
468         picoVec3_t xyz, normal;
469         picoVec2_t st;
470         picoColor_t color;
471
472
473         /* -------------------------------------------------
474            mdc loading
475            ------------------------------------------------- */
476
477
478         /* set as mdc */
479         bb0 = bb = (picoByte_t*) _pico_alloc( bufSize );
480         memcpy( bb, buffer, bufSize );
481         mdc = (mdc_t*) bb;
482
483         /* check ident and version */
484         if ( *( (int*) mdc->magic ) != *( (int*) MDC_MAGIC ) || _pico_little_long( mdc->version ) != MDC_VERSION ) {
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                 _pico_printf( PICO_ERROR, "MDC with 0 frames" );
505                 _pico_free( bb0 );
506                 return NULL;
507         }
508
509         if ( frameNum < 0 || frameNum >= mdc->numFrames ) {
510                 _pico_printf( PICO_ERROR, "Invalid or out-of-range MDC frame specified" );
511                 _pico_free( bb0 );
512                 return NULL;
513         }
514
515         /* swap frames */
516         frame = (mdcFrame_t*) ( bb + mdc->ofsFrames );
517         for ( i = 0; i < mdc->numFrames; i++, frame++ )
518         {
519                 frame->radius = _pico_little_float( frame->radius );
520                 for ( j = 0; j < 3; j++ )
521                 {
522                         frame->bounds[ 0 ][ j ] = _pico_little_float( frame->bounds[ 0 ][ j ] );
523                         frame->bounds[ 1 ][ j ] = _pico_little_float( frame->bounds[ 1 ][ j ] );
524                         frame->localOrigin[ j ] = _pico_little_float( frame->localOrigin[ j ] );
525                 }
526         }
527
528         /* swap surfaces */
529         surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
530         for ( i = 0; i < mdc->numSurfaces; i++ )
531         {
532                 /* swap surface mdc */
533                 surface->flags = _pico_little_long( surface->flags );
534                 surface->numBaseFrames = _pico_little_long( surface->numBaseFrames );
535                 surface->numCompFrames = _pico_little_long( surface->numCompFrames );
536                 surface->numShaders = _pico_little_long( surface->numShaders );
537                 surface->numTriangles = _pico_little_long( surface->numTriangles );
538                 surface->ofsTriangles = _pico_little_long( surface->ofsTriangles );
539                 surface->numVerts = _pico_little_long( surface->numVerts );
540                 surface->ofsShaders = _pico_little_long( surface->ofsShaders );
541                 surface->ofsSt = _pico_little_long( surface->ofsSt );
542                 surface->ofsXyzNormals = _pico_little_long( surface->ofsXyzNormals );
543                 surface->ofsXyzCompressed = _pico_little_long( surface->ofsXyzCompressed );
544                 surface->ofsFrameBaseFrames = _pico_little_long( surface->ofsFrameBaseFrames );
545                 surface->ofsFrameCompFrames = _pico_little_long( surface->ofsFrameCompFrames );
546                 surface->ofsEnd = _pico_little_long( surface->ofsEnd );
547
548                 /* swap triangles */
549                 triangle = (mdcTriangle_t*) ( (picoByte_t*) surface + surface->ofsTriangles );
550                 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
551                 {
552                         /* sea: swaps fixed */
553                         triangle->indexes[ 0 ] = _pico_little_long( triangle->indexes[ 0 ] );
554                         triangle->indexes[ 1 ] = _pico_little_long( triangle->indexes[ 1 ] );
555                         triangle->indexes[ 2 ] = _pico_little_long( triangle->indexes[ 2 ] );
556                 }
557
558                 /* swap st coords */
559                 texCoord = (mdcTexCoord_t*) ( (picoByte_t*) surface + surface->ofsSt );
560                 for ( j = 0; j < surface->numVerts; j++, texCoord++ )
561                 {
562                         texCoord->st[ 0 ] = _pico_little_float( texCoord->st[ 0 ] );
563                         texCoord->st[ 1 ] = _pico_little_float( texCoord->st[ 1 ] );
564                 }
565
566                 /* swap xyz/normals */
567                 vertex = (mdcVertex_t*) ( (picoByte_t*) surface + surface->ofsXyzNormals );
568                 for ( j = 0; j < ( surface->numVerts * surface->numBaseFrames ); j++, vertex++ )
569                 {
570                         vertex->xyz[ 0 ] = _pico_little_short( vertex->xyz[ 0 ] );
571                         vertex->xyz[ 1 ] = _pico_little_short( vertex->xyz[ 1 ] );
572                         vertex->xyz[ 2 ] = _pico_little_short( vertex->xyz[ 2 ] );
573                         vertex->normal   = _pico_little_short( vertex->normal );
574                 }
575
576                 /* swap xyz/compressed */
577                 vertexComp = (mdcXyzCompressed_t*) ( (picoByte_t*) surface + surface->ofsXyzCompressed );
578                 for ( j = 0; j < ( surface->numVerts * surface->numCompFrames ); j++, vertexComp++ )
579                 {
580                         vertexComp->ofsVec  = _pico_little_long( vertexComp->ofsVec );
581                 }
582
583                 /* swap base frames */
584                 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameBaseFrames );
585                 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
586                 {
587                         *mdcShort   = _pico_little_short( *mdcShort );
588                 }
589
590                 /* swap compressed frames */
591                 mdcShort = (short *) ( (picoByte_t*) surface + surface->ofsFrameCompFrames );
592                 for ( j = 0; j < mdc->numFrames; j++, mdcShort++ )
593                 {
594                         *mdcShort   = _pico_little_short( *mdcShort );
595                 }
596
597                 /* get next surface */
598                 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
599         }
600
601         /* -------------------------------------------------
602            pico model creation
603            ------------------------------------------------- */
604
605         /* create new pico model */
606         picoModel = PicoNewModel();
607         if ( picoModel == NULL ) {
608                 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
609                 _pico_free( bb0 );
610                 return NULL;
611         }
612
613         /* do model setup */
614         PicoSetModelFrameNum( picoModel, frameNum );
615         PicoSetModelNumFrames( picoModel, mdc->numFrames ); /* sea */
616         PicoSetModelName( picoModel, fileName );
617         PicoSetModelFileName( picoModel, fileName );
618
619         /* mdc surfaces become picomodel surfaces */
620         surface = (mdcSurface_t*) ( bb + mdc->ofsSurfaces );
621
622         /* run through mdc surfaces */
623         for ( i = 0; i < mdc->numSurfaces; i++ )
624         {
625                 /* allocate new pico surface */
626                 picoSurface = PicoNewSurface( picoModel );
627                 if ( picoSurface == NULL ) {
628                         _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
629                         PicoFreeModel( picoModel ); /* sea */
630                         _pico_free( bb0 );
631                         return NULL;
632                 }
633
634                 /* mdc model surfaces are all triangle meshes */
635                 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
636
637                 /* set surface name */
638                 PicoSetSurfaceName( picoSurface, surface->name );
639
640                 /* create new pico shader -sea */
641                 picoShader = PicoNewShader( picoModel );
642                 if ( picoShader == NULL ) {
643                         _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
644                         PicoFreeModel( picoModel );
645                         _pico_free( bb0 );
646                         return NULL;
647                 }
648
649                 /* detox and set shader name */
650                 shader = (mdcShader_t*) ( (picoByte_t*) surface + surface->ofsShaders );
651                 _pico_setfext( shader->name, "" );
652                 _pico_unixify( shader->name );
653                 PicoSetShaderName( picoShader, shader->name );
654
655                 /* associate current surface with newly created shader */
656                 PicoSetSurfaceShader( picoSurface, picoShader );
657
658                 /* copy indexes */
659                 triangle = (mdcTriangle_t *) ( (picoByte_t*) surface + surface->ofsTriangles );
660
661                 for ( j = 0; j < surface->numTriangles; j++, triangle++ )
662                 {
663                         PicoSetSurfaceIndex( picoSurface, ( j * 3 + 0 ), (picoIndex_t) triangle->indexes[ 0 ] );
664                         PicoSetSurfaceIndex( picoSurface, ( j * 3 + 1 ), (picoIndex_t) triangle->indexes[ 1 ] );
665                         PicoSetSurfaceIndex( picoSurface, ( j * 3 + 2 ), (picoIndex_t) triangle->indexes[ 2 ] );
666                 }
667
668                 /* copy vertexes */
669                 texCoord = (mdcTexCoord_t*) ( (picoByte_t *) surface + surface->ofsSt );
670                 mdcShort = (short *) ( (picoByte_t *) surface + surface->ofsXyzNormals ) + ( (int)*( (short *) ( (picoByte_t *) surface + surface->ofsFrameBaseFrames ) + frameNum ) * surface->numVerts * 4 );
671                 if ( surface->numCompFrames > 0 ) {
672                         mdcCompVert = (short *) ( (picoByte_t *) surface + surface->ofsFrameCompFrames ) + frameNum;
673                         if ( *mdcCompVert >= 0 ) {
674                                 vertexComp = (mdcXyzCompressed_t *) ( (picoByte_t *) surface + surface->ofsXyzCompressed ) + ( *mdcCompVert * surface->numVerts );
675                         }
676                 }
677                 _pico_set_color( color, 255, 255, 255, 255 );
678
679                 for ( j = 0; j < surface->numVerts; j++, texCoord++, mdcShort += 4 )
680                 {
681                         /* set vertex origin */
682                         xyz[ 0 ] = MDC_SCALE * mdcShort[ 0 ];
683                         xyz[ 1 ] = MDC_SCALE * mdcShort[ 1 ];
684                         xyz[ 2 ] = MDC_SCALE * mdcShort[ 2 ];
685
686                         /* add compressed ofsVec */
687                         if ( surface->numCompFrames > 0 && *mdcCompVert >= 0 ) {
688                                 xyz[ 0 ] += ( (float) ( ( vertexComp->ofsVec ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
689                                 xyz[ 1 ] += ( (float) ( ( vertexComp->ofsVec >> 8 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
690                                 xyz[ 2 ] += ( (float) ( ( vertexComp->ofsVec >> 16 ) & 255 ) - MDC_MAX_OFS ) * MDC_DIST_SCALE;
691                                 PicoSetSurfaceXYZ( picoSurface, j, xyz );
692
693                                 normal[ 0 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 0 ];
694                                 normal[ 1 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 1 ];
695                                 normal[ 2 ] = (float) mdcNormals[ ( vertexComp->ofsVec >> 24 ) ][ 2 ];
696                                 PicoSetSurfaceNormal( picoSurface, j, normal );
697
698                                 vertexComp++;
699                         }
700                         else
701                         {
702                                 PicoSetSurfaceXYZ( picoSurface, j, xyz );
703
704                                 /* decode lat/lng normal to 3 float normal */
705                                 lat = (float) ( ( *( mdcShort + 3 ) >> 8 ) & 0xff );
706                                 lng = (float) ( *( mdcShort + 3 ) & 0xff );
707                                 lat *= PICO_PI / 128;
708                                 lng *= PICO_PI / 128;
709                                 normal[ 0 ] = (picoVec_t) cos( lat ) * (picoVec_t) sin( lng );
710                                 normal[ 1 ] = (picoVec_t) sin( lat ) * (picoVec_t) sin( lng );
711                                 normal[ 2 ] = (picoVec_t) cos( lng );
712                                 PicoSetSurfaceNormal( picoSurface, j, normal );
713                         }
714
715                         /* set st coords */
716                         st[ 0 ] = texCoord->st[ 0 ];
717                         st[ 1 ] = texCoord->st[ 1 ];
718                         PicoSetSurfaceST( picoSurface, 0, j, st );
719
720                         /* set color */
721                         PicoSetSurfaceColor( picoSurface, 0, j, color );
722                 }
723
724                 /* get next surface */
725                 surface = (mdcSurface_t*) ( (picoByte_t*) surface + surface->ofsEnd );
726         }
727
728         /* return the new pico model */
729         _pico_free( bb0 );
730         return picoModel;
731 }
732
733
734
735 /* pico file format module definition */
736 const picoModule_t picoModuleMDC =
737 {
738         "1.3",                          /* module version string */
739         "RtCW MDC",                     /* module display name */
740         "Arnout van Meer",              /* author's name */
741         "2002 Arnout van Meer",         /* module copyright */
742         {
743                 "mdc", NULL, NULL, NULL     /* default extensions to use */
744         },
745         _mdc_canload,                   /* validation routine */
746         _mdc_load,                      /* load routine */
747         NULL,                           /* save validation routine */
748         NULL                            /* save routine */
749 };