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