]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/picomodel/pm_md2.c
eol style
[xonotic/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         md2_t   *md2;
304
305         /* to keep the compiler happy */
306         *fileName = *fileName;
307
308         /* sanity check */
309         if( bufSize < ( sizeof( *md2 ) * 2) )
310                 return PICO_PMV_ERROR_SIZE;
311         
312         /* set as md2 */
313         md2 = (md2_t*) buffer;
314         
315         /* check md2 magic */
316         if( *((int*) md2->magic) != *((int*) MD2_MAGIC) ) 
317                 return PICO_PMV_ERROR_IDENT;
318         
319         /* check md2 version */
320         if( _pico_little_long( md2->version ) != MD2_VERSION )
321                 return PICO_PMV_ERROR_VERSION;
322
323         /* file seems to be a valid md2 */
324         return PICO_PMV_OK;
325 }
326
327
328
329 // _md2_load() loads a quake2 md2 model file.
330
331
332 static picoModel_t *_md2_load( PM_PARAMS_LOAD )
333 {
334         int                             i, j, dups, dup_index;
335         short                   tot_numVerts;
336         index_LUT_t             *p_index_LUT, *p_index_LUT2, *p_index_LUT3;
337         index_DUP_LUT_t *p_index_LUT_DUPS;
338         md2Triangle_t   *p_md2Triangle;
339
340         char                    skinname[ MD2_MAX_SKINNAME ];
341         md2_t                   *md2;
342         md2St_t                 *texCoord;
343         md2Frame_t              *frame;
344         md2Triangle_t   *triangle;
345         md2XyzNormal_t  *vertex;
346
347         picoByte_t      *bb;
348         picoModel_t             *picoModel;
349         picoSurface_t   *picoSurface;
350         picoShader_t    *picoShader;
351         picoVec3_t              xyz, normal;
352         picoVec2_t              st;
353         picoColor_t             color;
354         
355
356         // md2 loading
357         _pico_printf( PICO_NORMAL, "Loading \"%s\"", fileName );
358
359         /* set as md2 */
360         bb = (picoByte_t*) buffer;
361         md2     = (md2_t*) buffer;
362
363         /* check ident and version */
364         if( *((int*) md2->magic) != *((int*) MD2_MAGIC) || _pico_little_long( md2->version ) != MD2_VERSION )
365         {
366                 /* not an md2 file (todo: set error) */
367                 _pico_printf( PICO_ERROR, "%s is not an MD2 File!", fileName );
368                 return NULL;
369         }
370         
371         // swap md2
372         md2->version = _pico_little_long( md2->version );
373
374         md2->skinWidth = _pico_little_long( md2->skinWidth );
375         md2->skinHeight = _pico_little_long( md2->skinHeight );
376         md2->frameSize = _pico_little_long( md2->frameSize );
377
378         md2->numSkins = _pico_little_long( md2->numSkins );
379         md2->numXYZ = _pico_little_long( md2->numXYZ );
380         md2->numST = _pico_little_long( md2->numST );
381         md2->numTris = _pico_little_long( md2->numTris );
382         md2->numGLCmds = _pico_little_long( md2->numGLCmds );
383         md2->numFrames = _pico_little_long( md2->numFrames );
384
385         md2->ofsSkins = _pico_little_long( md2->ofsSkins );
386         md2->ofsST = _pico_little_long( md2->ofsST );
387         md2->ofsTris = _pico_little_long( md2->ofsTris );
388         md2->ofsFrames = _pico_little_long( md2->ofsFrames );
389         md2->ofsGLCmds = _pico_little_long( md2->ofsGLCmds );
390         md2->ofsEnd = _pico_little_long( md2->ofsEnd );
391
392         // do frame check
393         if( md2->numFrames < 1 )
394         {
395                 _pico_printf( PICO_ERROR, "%s has 0 frames!", fileName );
396                 return NULL;
397         }
398         
399         if( frameNum < 0 || frameNum >= md2->numFrames )
400         {
401                 _pico_printf( PICO_ERROR, "Invalid or out-of-range MD2 frame specified" );
402                 return NULL;
403         }
404
405         // Setup Frame
406         frame = (md2Frame_t *) (bb + md2->ofsFrames + (sizeof(md2Frame_t) * frameNum));
407
408         // swap frame scale and translation
409         for( i = 0; i < 3; i++ )
410         {
411                 frame->scale[ i ] = _pico_little_float( frame->scale[ i ] );
412                 frame->translate[ i ] = _pico_little_float( frame->translate[ i ] );
413         }
414
415         // swap triangles
416         triangle = (md2Triangle_t *) ((picoByte_t *) (bb + md2->ofsTris) );
417         for( i = 0; i < md2->numTris; i++, triangle++ )
418         {
419                 for( j = 0; j < 3; j++ )
420                 {
421                         triangle->index_xyz[ j ] = _pico_little_short( triangle->index_xyz[ j ] );
422                         triangle->index_st[ j ] = _pico_little_short( triangle->index_st[ j ] );
423                 }
424         }
425
426         // swap st coords
427         texCoord = (md2St_t*) ((picoByte_t *) (bb + md2->ofsST) );
428         for( i = 0; i < md2->numST; i++, texCoord++ )
429         {
430                 texCoord->s = _pico_little_short( texCoord->s );
431                 texCoord->t = _pico_little_short( texCoord->t );
432         }
433
434         // set Skin Name
435         strncpy(skinname, (bb + md2->ofsSkins), MD2_MAX_SKINNAME );
436
437         // Print out md2 values
438         _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 );
439
440         // detox Skin name
441         _pico_setfext( skinname, "" );
442         _pico_unixify( skinname );
443
444         /* create new pico model */
445         picoModel = PicoNewModel();
446         if( picoModel == NULL )
447         {
448                 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
449                 return NULL;
450         }
451
452         /* do model setup */
453         PicoSetModelFrameNum( picoModel, frameNum );
454         PicoSetModelNumFrames( picoModel, md2->numFrames ); /* sea */
455         PicoSetModelName( picoModel, fileName );
456         PicoSetModelFileName( picoModel, fileName );
457
458         // allocate new pico surface
459         picoSurface = PicoNewSurface( picoModel );
460         if( picoSurface == NULL )
461         {
462                 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
463                 PicoFreeModel( picoModel );
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                 return NULL;
476         }
477
478         PicoSetShaderName( picoShader, skinname );
479
480         // associate current surface with newly created shader
481         PicoSetSurfaceShader( picoSurface, picoShader );
482
483         // Init LUT for Verts
484         p_index_LUT = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t) * md2->numXYZ);
485         for(i=0; i<md2->numXYZ; i++)
486         {
487                 p_index_LUT[i].Vert = -1;
488                 p_index_LUT[i].ST = -1;
489                 p_index_LUT[i].next = NULL;
490         }
491
492         // Fill in Look Up Table, and allocate/fill Linked List from vert array as needed for dup STs per Vert.
493         tot_numVerts = md2->numXYZ;
494         dups = 0;
495         for(i=0; i<md2->numTris; i++)
496         {
497                 p_md2Triangle = (md2Triangle_t *) ( bb + md2->ofsTris + (sizeof(md2Triangle_t)*i));
498                 for(j=0; j<3; j++)
499                 {
500                         if (p_index_LUT[p_md2Triangle->index_xyz[j]].ST == -1) // No Main Entry
501                                 p_index_LUT[p_md2Triangle->index_xyz[j]].ST = p_md2Triangle->index_st[j];
502
503                         else if (p_md2Triangle->index_st[j] == p_index_LUT[p_md2Triangle->index_xyz[j]].ST ) // Equal to Main Entry
504                                 continue;
505
506                         else if ( (p_index_LUT[p_md2Triangle->index_xyz[j]].next == NULL) )  // Not equal to Main entry, and no LL entry
507                         {       // Add first entry of LL from Main
508                                 p_index_LUT2 = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t));
509                                 if (p_index_LUT2 == NULL)
510                                         _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
511                                 p_index_LUT[p_md2Triangle->index_xyz[j]].next = (index_LUT_t *)p_index_LUT2;
512                                 p_index_LUT2->Vert = dups;
513                                 p_index_LUT2->ST = p_md2Triangle->index_st[j];
514                                 p_index_LUT2->next = NULL;
515                                 p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
516                                 dups++;
517                         }
518                         else // Try to find in LL from Main Entry
519                         {
520                                 p_index_LUT3 = p_index_LUT2 = p_index_LUT[p_md2Triangle->index_xyz[j]].next;
521                                 while ( (p_index_LUT2 != NULL) && (p_md2Triangle->index_xyz[j] != p_index_LUT2->Vert) ) // Walk down LL
522                                 {
523                                         p_index_LUT3 = p_index_LUT2;
524                                         p_index_LUT2 = p_index_LUT2->next;
525                                 }
526                                 p_index_LUT2 = p_index_LUT3;
527
528                                 if ( p_md2Triangle->index_st[j] == p_index_LUT2->ST ) // Found it
529                                 {
530                                         p_md2Triangle->index_xyz[j] = p_index_LUT2->Vert + md2->numXYZ; // Make change in Tri hunk
531                                         continue;
532                                 }
533
534                                 if ( p_index_LUT2->next == NULL)  // Didn't find it. Add entry to LL.
535                                 {
536                                         // Add the Entry
537                                         p_index_LUT3 = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t));
538                                         if (p_index_LUT3 == NULL)
539                                                 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
540                                         p_index_LUT2->next = (index_LUT_t *)p_index_LUT3;
541                                         p_index_LUT3->Vert = p_md2Triangle->index_xyz[j];
542                                         p_index_LUT3->ST = p_md2Triangle->index_st[j];
543                                         p_index_LUT3->next = NULL;
544                                         p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
545                                         dups++;
546                                 }
547                         }
548                 }
549         }
550
551         // malloc and build array for Dup STs
552         p_index_LUT_DUPS = (index_DUP_LUT_t *)_pico_alloc(sizeof(index_DUP_LUT_t) * dups);
553         if (p_index_LUT_DUPS == NULL)
554                 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
555
556         dup_index = 0;
557         for(i=0; i<md2->numXYZ; i++)
558         {
559                 p_index_LUT2 = p_index_LUT[i].next;
560                 while (p_index_LUT2 != NULL)
561                 {
562                         p_index_LUT_DUPS[p_index_LUT2->Vert].OldVert = i;
563                         p_index_LUT_DUPS[p_index_LUT2->Vert].ST = p_index_LUT2->ST;
564                         dup_index++;
565                         p_index_LUT2 = p_index_LUT2->next;
566                 }
567         }
568
569         // Build Picomodel
570         triangle = (md2Triangle_t *) ((picoByte_t *) (bb + md2->ofsTris) );
571         texCoord = (md2St_t*) ((picoByte_t *) (bb + md2->ofsST) );
572         vertex = (md2XyzNormal_t*) ((picoByte_t*) (frame->verts) );
573         for( j = 0; j < md2->numTris; j++, triangle++ )
574         {
575                 PicoSetSurfaceIndex( picoSurface, j*3   , triangle->index_xyz[0] );
576                 PicoSetSurfaceIndex( picoSurface, j*3+1 , triangle->index_xyz[1] );
577                 PicoSetSurfaceIndex( picoSurface, j*3+2 , triangle->index_xyz[2] );
578         }
579
580         for(i=0; i< md2->numXYZ; i++, vertex++)
581         {
582                 /* set vertex origin */
583                 xyz[ 0 ] = vertex->v[0] * frame->scale[0] + frame->translate[0];
584                 xyz[ 1 ] = vertex->v[1] * frame->scale[1] + frame->translate[1];
585                 xyz[ 2 ] = vertex->v[2] * frame->scale[2] + frame->translate[2];
586                 PicoSetSurfaceXYZ( picoSurface, i , xyz );
587
588                 /* set normal */
589                 normal[ 0 ] = md2_normals[vertex->lightnormalindex][0];
590                 normal[ 1 ] = md2_normals[vertex->lightnormalindex][1];
591                 normal[ 2 ] = md2_normals[vertex->lightnormalindex][2];
592                 PicoSetSurfaceNormal( picoSurface, i , normal );
593
594                 /* set st coords */
595                 st[ 0 ] =  ((texCoord[p_index_LUT[i].ST].s) / ((float)md2->skinWidth));
596                 st[ 1 ] =  (texCoord[p_index_LUT[i].ST].t / ((float)md2->skinHeight));
597                 PicoSetSurfaceST( picoSurface, 0, i , st );
598         }
599
600         if (dups)
601         {
602                 for(i=0; i<dups; i++)
603                 {
604                         j = p_index_LUT_DUPS[i].OldVert;
605                         /* set vertex origin */
606                         xyz[ 0 ] = frame->verts[j].v[0] * frame->scale[0] + frame->translate[0];
607                         xyz[ 1 ] = frame->verts[j].v[1] * frame->scale[1] + frame->translate[1];
608                         xyz[ 2 ] = frame->verts[j].v[2] * frame->scale[2] + frame->translate[2];
609                         PicoSetSurfaceXYZ( picoSurface, i + md2->numXYZ , xyz );
610
611                         /* set normal */
612                         normal[ 0 ] = md2_normals[frame->verts[j].lightnormalindex][0];
613                         normal[ 1 ] = md2_normals[frame->verts[j].lightnormalindex][1];
614                         normal[ 2 ] = md2_normals[frame->verts[j].lightnormalindex][2];
615                         PicoSetSurfaceNormal( picoSurface, i + md2->numXYZ , normal );
616
617                         /* set st coords */
618                         st[ 0 ] =  ((texCoord[p_index_LUT_DUPS[i].ST].s) / ((float)md2->skinWidth));
619                         st[ 1 ] =  (texCoord[p_index_LUT_DUPS[i].ST].t / ((float)md2->skinHeight));
620                         PicoSetSurfaceST( picoSurface, 0, i + md2->numXYZ , st );
621                 }
622         }
623
624         /* set color */
625         PicoSetSurfaceColor( picoSurface, 0, 0, color );
626
627         // Free up malloc'ed LL entries
628         for(i=0; i<md2->numXYZ; i++)
629         {
630                 if(p_index_LUT[i].next != NULL)
631                 {
632                         p_index_LUT2 = p_index_LUT[i].next;
633                         do {
634                                 p_index_LUT3 = p_index_LUT2->next;
635                                 _pico_free(p_index_LUT2);
636                                 p_index_LUT2 = p_index_LUT3;
637                                 dups--;
638                         } while (p_index_LUT2 != NULL);
639                 }
640         }
641
642         if (dups)
643                 _pico_printf(PICO_WARNING, " Not all LL mallocs freed\n");
644
645         // Free malloc'ed LUTs
646         _pico_free(p_index_LUT);
647         _pico_free(p_index_LUT_DUPS);
648
649         /* return the new pico model */
650         return picoModel;
651
652 }
653
654
655
656 /* pico file format module definition */
657 const picoModule_t picoModuleMD2 =
658 {
659         "0.875",                                                /* module version string */
660         "Quake 2 MD2",                                  /* module display name */
661         "Nurail",                                               /* author's name */
662         "2003 Nurail",                                  /* module copyright */
663         {
664                 "md2", NULL, NULL, NULL         /* default extensions to use */
665         },
666         _md2_canload,                                   /* validation routine */
667         _md2_load,                                              /* load routine */
668          NULL,                                                  /* save validation routine */
669          NULL                                                   /* save routine */
670 };