]> icculus.org git repositories - divverent/netradiant.git/blob - libs/picomodel/pm_md2.c
automatically run the decompiler when specifying a BSP file in Import...
[divverent/netradiant.git] / libs / picomodel / pm_md2.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 Nurail: Used pm_md3.c (Randy Reddig) as a template.
37 */
38
39
40 /* marker */
41 #define PM_MD2_C
42
43 /* dependencies */
44 #include "picointernal.h"
45
46
47 /* md2 model format */
48 #define MD2_MAGIC                               "IDP2"
49 #define MD2_VERSION                             8
50
51 #define MD2_NUMVERTEXNORMALS    162
52 #define MD2_MAX_SKINNAME                64
53 #define MD2_MAX_TRIANGLES               4096
54 #define MD2_MAX_VERTS                   2048
55 #define MD2_MAX_FRAMES                  512
56 #define MD2_MAX_MD2SKINS                32
57 #define MD2_MAX_SKINNAME                64
58
59 #ifndef byte
60         #define byte unsigned char
61 #endif
62
63 typedef struct index_LUT_s
64 {
65         short   Vert;
66         short   ST;
67         struct  index_LUT_s     *next;
68
69 } index_LUT_t;
70
71 typedef struct index_DUP_LUT_s
72 {
73         short                   ST;
74         short                   OldVert;
75
76 } index_DUP_LUT_t;
77
78 typedef struct
79 {
80         short   s;
81         short   t;
82 } md2St_t;
83
84 typedef struct
85 {
86         short   index_xyz[3];
87         short   index_st[3];
88 } md2Triangle_t;
89
90 typedef struct
91 {
92         byte    v[3];                   // scaled byte to fit in frame mins/maxs
93         byte    lightnormalindex;
94 } md2XyzNormal_t;
95
96 typedef struct md2Frame_s
97 {
98         float           scale[3];       // multiply byte verts by this
99         float           translate[3];   // then add this
100         char            name[16];       // frame name from grabbing
101         md2XyzNormal_t  verts[1];       // variable sized
102 }
103 md2Frame_t;
104
105
106 /* md2 model file md2 structure */
107 typedef struct md2_s
108 {
109         char    magic[ 4 ];
110         int     version;
111
112         int     skinWidth;
113         int     skinHeight;
114         int     frameSize;
115
116         int     numSkins;
117         int     numXYZ;
118         int     numST;
119         int     numTris;
120         int     numGLCmds;
121         int     numFrames;
122
123         int     ofsSkins;
124         int     ofsST;
125         int     ofsTris;
126         int     ofsFrames;
127         int     ofsGLCmds;
128         int     ofsEnd;
129 }
130 md2_t;
131
132 float   md2_normals[ MD2_NUMVERTEXNORMALS ][ 3 ] =
133 {
134         { -0.525731f, 0.000000f, 0.850651f },
135         { -0.442863f, 0.238856f, 0.864188f }, 
136         { -0.295242f, 0.000000f, 0.955423f }, 
137         { -0.309017f, 0.500000f, 0.809017f }, 
138         { -0.162460f, 0.262866f, 0.951056f }, 
139         { 0.000000f, 0.000000f, 1.000000f },
140         { 0.000000f, 0.850651f, 0.525731f },
141         { -0.147621f, 0.716567f, 0.681718f },
142         { 0.147621f, 0.716567f, 0.681718f }, 
143         { 0.000000f, 0.525731f, 0.850651f }, 
144         { 0.309017f, 0.500000f, 0.809017f }, 
145         { 0.525731f, 0.000000f, 0.850651f }, 
146         { 0.295242f, 0.000000f, 0.955423f }, 
147         { 0.442863f, 0.238856f, 0.864188f }, 
148         { 0.162460f, 0.262866f, 0.951056f }, 
149         { -0.681718f, 0.147621f, 0.716567f }, 
150         { -0.809017f, 0.309017f, 0.500000f }, 
151         { -0.587785f, 0.425325f, 0.688191f }, 
152         { -0.850651f, 0.525731f, 0.000000f }, 
153         { -0.864188f, 0.442863f, 0.238856f }, 
154         { -0.716567f, 0.681718f, 0.147621f }, 
155         { -0.688191f, 0.587785f, 0.425325f }, 
156         { -0.500000f, 0.809017f, 0.309017f }, 
157         { -0.238856f, 0.864188f, 0.442863f }, 
158         { -0.425325f, 0.688191f, 0.587785f }, 
159         { -0.716567f, 0.681718f, -0.147621f }, 
160         { -0.500000f, 0.809017f, -0.309017f }, 
161         { -0.525731f, 0.850651f, 0.000000f }, 
162         { 0.000000f, 0.850651f, -0.525731f }, 
163         { -0.238856f, 0.864188f, -0.442863f }, 
164         { 0.000000f, 0.955423f, -0.295242f }, 
165         { -0.262866f, 0.951056f, -0.162460f }, 
166         { 0.000000f, 1.000000f, 0.000000f }, 
167         { 0.000000f, 0.955423f, 0.295242f }, 
168         { -0.262866f, 0.951056f, 0.162460f }, 
169         { 0.238856f, 0.864188f, 0.442863f }, 
170         { 0.262866f, 0.951056f, 0.162460f }, 
171         { 0.500000f, 0.809017f, 0.309017f }, 
172         { 0.238856f, 0.864188f, -0.442863f }, 
173         { 0.262866f, 0.951056f, -0.162460f }, 
174         { 0.500000f, 0.809017f, -0.309017f }, 
175         { 0.850651f, 0.525731f, 0.000000f }, 
176         { 0.716567f, 0.681718f, 0.147621f }, 
177         { 0.716567f, 0.681718f, -0.147621f }, 
178         { 0.525731f, 0.850651f, 0.000000f }, 
179         { 0.425325f, 0.688191f, 0.587785f }, 
180         { 0.864188f, 0.442863f, 0.238856f }, 
181         { 0.688191f, 0.587785f, 0.425325f }, 
182         { 0.809017f, 0.309017f, 0.500000f }, 
183         { 0.681718f, 0.147621f, 0.716567f }, 
184         { 0.587785f, 0.425325f, 0.688191f }, 
185         { 0.955423f, 0.295242f, 0.000000f }, 
186         { 1.000000f, 0.000000f, 0.000000f }, 
187         { 0.951056f, 0.162460f, 0.262866f }, 
188         { 0.850651f, -0.525731f, 0.000000f }, 
189         { 0.955423f, -0.295242f, 0.000000f }, 
190         { 0.864188f, -0.442863f, 0.238856f }, 
191         { 0.951056f, -0.162460f, 0.262866f }, 
192         { 0.809017f, -0.309017f, 0.500000f }, 
193         { 0.681718f, -0.147621f, 0.716567f }, 
194         { 0.850651f, 0.000000f, 0.525731f }, 
195         { 0.864188f, 0.442863f, -0.238856f }, 
196         { 0.809017f, 0.309017f, -0.500000f }, 
197         { 0.951056f, 0.162460f, -0.262866f }, 
198         { 0.525731f, 0.000000f, -0.850651f }, 
199         { 0.681718f, 0.147621f, -0.716567f }, 
200         { 0.681718f, -0.147621f, -0.716567f }, 
201         { 0.850651f, 0.000000f, -0.525731f }, 
202         { 0.809017f, -0.309017f, -0.500000f }, 
203         { 0.864188f, -0.442863f, -0.238856f }, 
204         { 0.951056f, -0.162460f, -0.262866f }, 
205         { 0.147621f, 0.716567f, -0.681718f }, 
206         { 0.309017f, 0.500000f, -0.809017f }, 
207         { 0.425325f, 0.688191f, -0.587785f }, 
208         { 0.442863f, 0.238856f, -0.864188f }, 
209         { 0.587785f, 0.425325f, -0.688191f }, 
210         { 0.688191f, 0.587785f, -0.425325f }, 
211         { -0.147621f, 0.716567f, -0.681718f }, 
212         { -0.309017f, 0.500000f, -0.809017f }, 
213         { 0.000000f, 0.525731f, -0.850651f }, 
214         { -0.525731f, 0.000000f, -0.850651f }, 
215         { -0.442863f, 0.238856f, -0.864188f }, 
216         { -0.295242f, 0.000000f, -0.955423f }, 
217         { -0.162460f, 0.262866f, -0.951056f }, 
218         { 0.000000f, 0.000000f, -1.000000f }, 
219         { 0.295242f, 0.000000f, -0.955423f }, 
220         { 0.162460f, 0.262866f, -0.951056f }, 
221         { -0.442863f, -0.238856f, -0.864188f }, 
222         { -0.309017f, -0.500000f, -0.809017f }, 
223         { -0.162460f, -0.262866f, -0.951056f }, 
224         { 0.000000f, -0.850651f, -0.525731f }, 
225         { -0.147621f, -0.716567f, -0.681718f }, 
226         { 0.147621f, -0.716567f, -0.681718f }, 
227         { 0.000000f, -0.525731f, -0.850651f }, 
228         { 0.309017f, -0.500000f, -0.809017f }, 
229         { 0.442863f, -0.238856f, -0.864188f }, 
230         { 0.162460f, -0.262866f, -0.951056f }, 
231         { 0.238856f, -0.864188f, -0.442863f }, 
232         { 0.500000f, -0.809017f, -0.309017f }, 
233         { 0.425325f, -0.688191f, -0.587785f }, 
234         { 0.716567f, -0.681718f, -0.147621f }, 
235         { 0.688191f, -0.587785f, -0.425325f }, 
236         { 0.587785f, -0.425325f, -0.688191f }, 
237         { 0.000000f, -0.955423f, -0.295242f }, 
238         { 0.000000f, -1.000000f, 0.000000f }, 
239         { 0.262866f, -0.951056f, -0.162460f }, 
240         { 0.000000f, -0.850651f, 0.525731f }, 
241         { 0.000000f, -0.955423f, 0.295242f }, 
242         { 0.238856f, -0.864188f, 0.442863f }, 
243         { 0.262866f, -0.951056f, 0.162460f }, 
244         { 0.500000f, -0.809017f, 0.309017f }, 
245         { 0.716567f, -0.681718f, 0.147621f }, 
246         { 0.525731f, -0.850651f, 0.000000f }, 
247         { -0.238856f, -0.864188f, -0.442863f }, 
248         { -0.500000f, -0.809017f, -0.309017f }, 
249         { -0.262866f, -0.951056f, -0.162460f }, 
250         { -0.850651f, -0.525731f, 0.000000f }, 
251         { -0.716567f, -0.681718f, -0.147621f }, 
252         { -0.716567f, -0.681718f, 0.147621f }, 
253         { -0.525731f, -0.850651f, 0.000000f }, 
254         { -0.500000f, -0.809017f, 0.309017f }, 
255         { -0.238856f, -0.864188f, 0.442863f }, 
256         { -0.262866f, -0.951056f, 0.162460f }, 
257         { -0.864188f, -0.442863f, 0.238856f }, 
258         { -0.809017f, -0.309017f, 0.500000f }, 
259         { -0.688191f, -0.587785f, 0.425325f }, 
260         { -0.681718f, -0.147621f, 0.716567f }, 
261         { -0.442863f, -0.238856f, 0.864188f }, 
262         { -0.587785f, -0.425325f, 0.688191f }, 
263         { -0.309017f, -0.500000f, 0.809017f }, 
264         { -0.147621f, -0.716567f, 0.681718f }, 
265         { -0.425325f, -0.688191f, 0.587785f }, 
266         { -0.162460f, -0.262866f, 0.951056f }, 
267         { 0.442863f, -0.238856f, 0.864188f }, 
268         { 0.162460f, -0.262866f, 0.951056f }, 
269         { 0.309017f, -0.500000f, 0.809017f }, 
270         { 0.147621f, -0.716567f, 0.681718f }, 
271         { 0.000000f, -0.525731f, 0.850651f }, 
272         { 0.425325f, -0.688191f, 0.587785f }, 
273         { 0.587785f, -0.425325f, 0.688191f }, 
274         { 0.688191f, -0.587785f, 0.425325f }, 
275         { -0.955423f, 0.295242f, 0.000000f }, 
276         { -0.951056f, 0.162460f, 0.262866f }, 
277         { -1.000000f, 0.000000f, 0.000000f }, 
278         { -0.850651f, 0.000000f, 0.525731f }, 
279         { -0.955423f, -0.295242f, 0.000000f }, 
280         { -0.951056f, -0.162460f, 0.262866f }, 
281         { -0.864188f, 0.442863f, -0.238856f }, 
282         { -0.951056f, 0.162460f, -0.262866f }, 
283         { -0.809017f, 0.309017f, -0.500000f }, 
284         { -0.864188f, -0.442863f, -0.238856f },
285         { -0.951056f, -0.162460f, -0.262866f }, 
286         { -0.809017f, -0.309017f, -0.500000f }, 
287         { -0.681718f, 0.147621f, -0.716567f }, 
288         { -0.681718f, -0.147621f, -0.716567f }, 
289         { -0.850651f, 0.000000f, -0.525731f }, 
290         { -0.688191f, 0.587785f, -0.425325f }, 
291         { -0.587785f, 0.425325f, -0.688191f }, 
292         { -0.425325f, 0.688191f, -0.587785f }, 
293         { -0.425325f, -0.688191f, -0.587785f }, 
294         { -0.587785f, -0.425325f, -0.688191f }, 
295         { -0.688191f, -0.587785f, -0.425325f }, 
296 };
297
298
299 // _md2_canload()
300
301 static int _md2_canload( PM_PARAMS_CANLOAD )
302 {
303         const md2_t     *md2;
304
305         /* sanity check */
306         if( (size_t) bufSize < ( sizeof( *md2 ) * 2) )
307                 return PICO_PMV_ERROR_SIZE;
308         
309         /* set as md2 */
310         md2 = (const md2_t*) buffer;
311         
312         /* check md2 magic */
313         if( *((const int*) md2->magic) != *((const int*) MD2_MAGIC) ) 
314                 return PICO_PMV_ERROR_IDENT;
315         
316         /* check md2 version */
317         if( _pico_little_long( md2->version ) != MD2_VERSION )
318                 return PICO_PMV_ERROR_VERSION;
319
320         /* file seems to be a valid md2 */
321         return PICO_PMV_OK;
322 }
323
324
325
326 // _md2_load() loads a quake2 md2 model file.
327
328
329 static picoModel_t *_md2_load( PM_PARAMS_LOAD )
330 {
331         int                             i, j, dups, dup_index;
332         short                   tot_numVerts;
333         index_LUT_t             *p_index_LUT, *p_index_LUT2, *p_index_LUT3;
334         index_DUP_LUT_t *p_index_LUT_DUPS;
335         md2Triangle_t   *p_md2Triangle;
336
337         char                    skinname[ MD2_MAX_SKINNAME ];
338         md2_t                   *md2;
339         md2St_t                 *texCoord;
340         md2Frame_t              *frame;
341         md2Triangle_t   *triangle;
342         md2XyzNormal_t  *vertex;
343
344         picoByte_t      *bb, *bb0;
345         picoModel_t             *picoModel;
346         picoSurface_t   *picoSurface;
347         picoShader_t    *picoShader;
348         picoVec3_t              xyz, normal;
349         picoVec2_t              st;
350         picoColor_t             color;
351         
352
353         /* set as md2 */
354         bb0 = bb = (picoByte_t*) _pico_alloc(bufSize);
355         memcpy(bb, buffer, bufSize);
356         md2     = (md2_t*) bb;
357
358         /* check ident and version */
359         if( *((const int*) md2->magic) != *((const int*) MD2_MAGIC) || _pico_little_long( md2->version ) != MD2_VERSION )
360         {
361                 /* not an md2 file (todo: set error) */
362                 _pico_printf( PICO_ERROR, "%s is not an MD2 File!", fileName );
363                 _pico_free(bb0);
364                 return NULL;
365         }
366         
367         // swap md2
368         md2->version = _pico_little_long( md2->version );
369
370         md2->skinWidth = _pico_little_long( md2->skinWidth );
371         md2->skinHeight = _pico_little_long( md2->skinHeight );
372         md2->frameSize = _pico_little_long( md2->frameSize );
373
374         md2->numSkins = _pico_little_long( md2->numSkins );
375         md2->numXYZ = _pico_little_long( md2->numXYZ );
376         md2->numST = _pico_little_long( md2->numST );
377         md2->numTris = _pico_little_long( md2->numTris );
378         md2->numGLCmds = _pico_little_long( md2->numGLCmds );
379         md2->numFrames = _pico_little_long( md2->numFrames );
380
381         md2->ofsSkins = _pico_little_long( md2->ofsSkins );
382         md2->ofsST = _pico_little_long( md2->ofsST );
383         md2->ofsTris = _pico_little_long( md2->ofsTris );
384         md2->ofsFrames = _pico_little_long( md2->ofsFrames );
385         md2->ofsGLCmds = _pico_little_long( md2->ofsGLCmds );
386         md2->ofsEnd = _pico_little_long( md2->ofsEnd );
387
388         // do frame check
389         if( md2->numFrames < 1 )
390         {
391                 _pico_printf( PICO_ERROR, "%s has 0 frames!", fileName );
392                 _pico_free(bb0);
393                 return NULL;
394         }
395         
396         if( frameNum < 0 || frameNum >= md2->numFrames )
397         {
398                 _pico_printf( PICO_ERROR, "Invalid or out-of-range MD2 frame specified" );
399                 _pico_free(bb0);
400                 return NULL;
401         }
402
403         // Setup Frame
404         frame = (md2Frame_t *) (bb + md2->ofsFrames + (sizeof(md2Frame_t) * frameNum));
405
406         // swap frame scale and translation
407         for( i = 0; i < 3; i++ )
408         {
409                 frame->scale[ i ] = _pico_little_float( frame->scale[ i ] );
410                 frame->translate[ i ] = _pico_little_float( frame->translate[ i ] );
411         }
412
413         // swap triangles
414         triangle = (md2Triangle_t *) ((picoByte_t *) (bb + md2->ofsTris) );
415         for( i = 0; i < md2->numTris; i++, triangle++ )
416         {
417                 for( j = 0; j < 3; j++ )
418                 {
419                         triangle->index_xyz[ j ] = _pico_little_short( triangle->index_xyz[ j ] );
420                         triangle->index_st[ j ] = _pico_little_short( triangle->index_st[ j ] );
421                 }
422         }
423
424         // swap st coords
425         texCoord = (md2St_t*) ((picoByte_t *) (bb + md2->ofsST) );
426         for( i = 0; i < md2->numST; i++, texCoord++ )
427         {
428                 texCoord->s = _pico_little_short( texCoord->s );
429                 texCoord->t = _pico_little_short( texCoord->t );
430         }
431
432         // set Skin Name
433         strncpy(skinname, (const char *) (bb + md2->ofsSkins), MD2_MAX_SKINNAME );
434
435         // Print out md2 values
436         _pico_printf(PICO_VERBOSE,"Skins: %d  Verts: %d  STs: %d  Triangles: %d  Frames: %d\nSkin Name \"%s\"\n", md2->numSkins, md2->numXYZ, md2->numST, md2->numTris, md2->numFrames, &skinname );
437
438         // detox Skin name
439         _pico_setfext( skinname, "" );
440         _pico_unixify( skinname );
441
442         /* create new pico model */
443         picoModel = PicoNewModel();
444         if( picoModel == NULL )
445         {
446                 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
447                 _pico_free(bb0);
448                 return NULL;
449         }
450
451         /* do model setup */
452         PicoSetModelFrameNum( picoModel, frameNum );
453         PicoSetModelNumFrames( picoModel, md2->numFrames ); /* sea */
454         PicoSetModelName( picoModel, fileName );
455         PicoSetModelFileName( picoModel, fileName );
456
457         // allocate new pico surface
458         picoSurface = PicoNewSurface( picoModel );
459         if( picoSurface == NULL )
460         {
461                 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
462                 PicoFreeModel( picoModel );
463                 _pico_free(bb0);
464                 return NULL;
465         }
466
467
468         PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
469         PicoSetSurfaceName( picoSurface, frame->name );
470         picoShader = PicoNewShader( picoModel );
471         if( picoShader == NULL )
472         {
473                 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
474                 PicoFreeModel( picoModel );
475                 _pico_free(bb0);
476                 return NULL;
477         }
478
479         PicoSetShaderName( picoShader, skinname );
480
481         // associate current surface with newly created shader
482         PicoSetSurfaceShader( picoSurface, picoShader );
483
484         // Init LUT for Verts
485         p_index_LUT = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t) * md2->numXYZ);
486         for(i=0; i<md2->numXYZ; i++)
487         {
488                 p_index_LUT[i].Vert = -1;
489                 p_index_LUT[i].ST = -1;
490                 p_index_LUT[i].next = NULL;
491         }
492
493         // Fill in Look Up Table, and allocate/fill Linked List from vert array as needed for dup STs per Vert.
494         tot_numVerts = md2->numXYZ;
495         dups = 0;
496         for(i=0; i<md2->numTris; i++)
497         {
498                 p_md2Triangle = (md2Triangle_t *) ( bb + md2->ofsTris + (sizeof(md2Triangle_t)*i));
499                 for(j=0; j<3; j++)
500                 {
501                         if (p_index_LUT[p_md2Triangle->index_xyz[j]].ST == -1) // No Main Entry
502                                 p_index_LUT[p_md2Triangle->index_xyz[j]].ST = p_md2Triangle->index_st[j];
503
504                         else if (p_md2Triangle->index_st[j] == p_index_LUT[p_md2Triangle->index_xyz[j]].ST ) // Equal to Main Entry
505                                 continue;
506
507                         else if ( (p_index_LUT[p_md2Triangle->index_xyz[j]].next == NULL) )  // Not equal to Main entry, and no LL entry
508                         {       // Add first entry of LL from Main
509                                 p_index_LUT2 = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t));
510                                 if (p_index_LUT2 == NULL)
511                                         _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
512                                 p_index_LUT[p_md2Triangle->index_xyz[j]].next = (index_LUT_t *)p_index_LUT2;
513                                 p_index_LUT2->Vert = dups;
514                                 p_index_LUT2->ST = p_md2Triangle->index_st[j];
515                                 p_index_LUT2->next = NULL;
516                                 p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
517                                 dups++;
518                         }
519                         else // Try to find in LL from Main Entry
520                         {
521                                 p_index_LUT3 = p_index_LUT2 = p_index_LUT[p_md2Triangle->index_xyz[j]].next;
522                                 while ( (p_index_LUT2 != NULL) && (p_md2Triangle->index_xyz[j] != p_index_LUT2->Vert) ) // Walk down LL
523                                 {
524                                         p_index_LUT3 = p_index_LUT2;
525                                         p_index_LUT2 = p_index_LUT2->next;
526                                 }
527                                 p_index_LUT2 = p_index_LUT3;
528
529                                 if ( p_md2Triangle->index_st[j] == p_index_LUT2->ST ) // Found it
530                                 {
531                                         p_md2Triangle->index_xyz[j] = p_index_LUT2->Vert + md2->numXYZ; // Make change in Tri hunk
532                                         continue;
533                                 }
534
535                                 if ( p_index_LUT2->next == NULL)  // Didn't find it. Add entry to LL.
536                                 {
537                                         // Add the Entry
538                                         p_index_LUT3 = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t));
539                                         if (p_index_LUT3 == NULL)
540                                                 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
541                                         p_index_LUT2->next = (index_LUT_t *)p_index_LUT3;
542                                         p_index_LUT3->Vert = p_md2Triangle->index_xyz[j];
543                                         p_index_LUT3->ST = p_md2Triangle->index_st[j];
544                                         p_index_LUT3->next = NULL;
545                                         p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
546                                         dups++;
547                                 }
548                         }
549                 }
550         }
551
552         // malloc and build array for Dup STs
553         p_index_LUT_DUPS = (index_DUP_LUT_t *)_pico_alloc(sizeof(index_DUP_LUT_t) * dups);
554         if (p_index_LUT_DUPS == NULL)
555                 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
556
557         dup_index = 0;
558         for(i=0; i<md2->numXYZ; i++)
559         {
560                 p_index_LUT2 = p_index_LUT[i].next;
561                 while (p_index_LUT2 != NULL)
562                 {
563                         p_index_LUT_DUPS[p_index_LUT2->Vert].OldVert = i;
564                         p_index_LUT_DUPS[p_index_LUT2->Vert].ST = p_index_LUT2->ST;
565                         dup_index++;
566                         p_index_LUT2 = p_index_LUT2->next;
567                 }
568         }
569
570         // Build Picomodel
571         triangle = (md2Triangle_t *) ((picoByte_t *) (bb + md2->ofsTris) );
572         texCoord = (md2St_t*) ((picoByte_t *) (bb + md2->ofsST) );
573         vertex = (md2XyzNormal_t*) ((picoByte_t*) (frame->verts) );
574         for( j = 0; j < md2->numTris; j++, triangle++ )
575         {
576                 PicoSetSurfaceIndex( picoSurface, j*3   , triangle->index_xyz[0] );
577                 PicoSetSurfaceIndex( picoSurface, j*3+1 , triangle->index_xyz[1] );
578                 PicoSetSurfaceIndex( picoSurface, j*3+2 , triangle->index_xyz[2] );
579         }
580
581         for(i=0; i< md2->numXYZ; i++, vertex++)
582         {
583                 /* set vertex origin */
584                 xyz[ 0 ] = vertex->v[0] * frame->scale[0] + frame->translate[0];
585                 xyz[ 1 ] = vertex->v[1] * frame->scale[1] + frame->translate[1];
586                 xyz[ 2 ] = vertex->v[2] * frame->scale[2] + frame->translate[2];
587                 PicoSetSurfaceXYZ( picoSurface, i , xyz );
588
589                 /* set normal */
590                 normal[ 0 ] = md2_normals[vertex->lightnormalindex][0];
591                 normal[ 1 ] = md2_normals[vertex->lightnormalindex][1];
592                 normal[ 2 ] = md2_normals[vertex->lightnormalindex][2];
593                 PicoSetSurfaceNormal( picoSurface, i , normal );
594
595                 /* set st coords */
596                 st[ 0 ] =  ((texCoord[p_index_LUT[i].ST].s) / ((float)md2->skinWidth));
597                 st[ 1 ] =  (texCoord[p_index_LUT[i].ST].t / ((float)md2->skinHeight));
598                 PicoSetSurfaceST( picoSurface, 0, i , st );
599         }
600
601         if (dups)
602         {
603                 for(i=0; i<dups; i++)
604                 {
605                         j = p_index_LUT_DUPS[i].OldVert;
606                         /* set vertex origin */
607                         xyz[ 0 ] = frame->verts[j].v[0] * frame->scale[0] + frame->translate[0];
608                         xyz[ 1 ] = frame->verts[j].v[1] * frame->scale[1] + frame->translate[1];
609                         xyz[ 2 ] = frame->verts[j].v[2] * frame->scale[2] + frame->translate[2];
610                         PicoSetSurfaceXYZ( picoSurface, i + md2->numXYZ , xyz );
611
612                         /* set normal */
613                         normal[ 0 ] = md2_normals[frame->verts[j].lightnormalindex][0];
614                         normal[ 1 ] = md2_normals[frame->verts[j].lightnormalindex][1];
615                         normal[ 2 ] = md2_normals[frame->verts[j].lightnormalindex][2];
616                         PicoSetSurfaceNormal( picoSurface, i + md2->numXYZ , normal );
617
618                         /* set st coords */
619                         st[ 0 ] =  ((texCoord[p_index_LUT_DUPS[i].ST].s) / ((float)md2->skinWidth));
620                         st[ 1 ] =  (texCoord[p_index_LUT_DUPS[i].ST].t / ((float)md2->skinHeight));
621                         PicoSetSurfaceST( picoSurface, 0, i + md2->numXYZ , st );
622                 }
623         }
624
625         /* set color */
626         PicoSetSurfaceColor( picoSurface, 0, 0, color );
627
628         // Free up malloc'ed LL entries
629         for(i=0; i<md2->numXYZ; i++)
630         {
631                 if(p_index_LUT[i].next != NULL)
632                 {
633                         p_index_LUT2 = p_index_LUT[i].next;
634                         do {
635                                 p_index_LUT3 = p_index_LUT2->next;
636                                 _pico_free(p_index_LUT2);
637                                 p_index_LUT2 = p_index_LUT3;
638                                 dups--;
639                         } while (p_index_LUT2 != NULL);
640                 }
641         }
642
643         if (dups)
644                 _pico_printf(PICO_WARNING, " Not all LL mallocs freed\n");
645
646         // Free malloc'ed LUTs
647         _pico_free(p_index_LUT);
648         _pico_free(p_index_LUT_DUPS);
649
650         /* return the new pico model */
651         _pico_free(bb0);
652         return picoModel;
653
654 }
655
656
657
658 /* pico file format module definition */
659 const picoModule_t picoModuleMD2 =
660 {
661         "0.875",                                                /* module version string */
662         "Quake 2 MD2",                                  /* module display name */
663         "Nurail",                                               /* author's name */
664         "2003 Nurail",                                  /* module copyright */
665         {
666                 "md2", NULL, NULL, NULL         /* default extensions to use */
667         },
668         _md2_canload,                                   /* validation routine */
669         _md2_load,                                              /* load routine */
670          NULL,                                                  /* save validation routine */
671          NULL                                                   /* save routine */
672 };