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