1 /* -----------------------------------------------------------------------------
5 Copyright (c) 2002, Randy Reddig & seaw0lf
8 Redistribution and use in source and binary forms, with or without modification,
9 are permitted provided that the following conditions are met:
11 Redistributions of source code must retain the above copyright notice, this list
12 of conditions and the following disclaimer.
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.
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.
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.
33 ----------------------------------------------------------------------------- */
36 Nurail: Used pm_md3.c (Randy Reddig) as a template.
44 #include "picointernal.h"
47 /* md2 model format */
48 #define MD2_MAGIC "IDP2"
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
60 #define byte unsigned char
63 typedef struct index_LUT_s
67 struct index_LUT_s *next;
71 typedef struct index_DUP_LUT_s
92 byte v[3]; // scaled byte to fit in frame mins/maxs
93 byte lightnormalindex;
96 typedef struct md2Frame_s
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
106 /* md2 model file md2 structure */
132 float md2_normals[ MD2_NUMVERTEXNORMALS ][ 3 ] =
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 },
301 static int _md2_canload( PM_PARAMS_CANLOAD )
305 /* to keep the compiler happy */
306 *fileName = *fileName;
309 if( bufSize < ( sizeof( *md2 ) * 2) )
310 return PICO_PMV_ERROR_SIZE;
313 md2 = (md2_t*) buffer;
315 /* check md2 magic */
316 if( *((int*) md2->magic) != *((int*) MD2_MAGIC) )
317 return PICO_PMV_ERROR_IDENT;
319 /* check md2 version */
320 if( _pico_little_long( md2->version ) != MD2_VERSION )
321 return PICO_PMV_ERROR_VERSION;
323 /* file seems to be a valid md2 */
329 // _md2_load() loads a quake2 md2 model file.
332 static picoModel_t *_md2_load( PM_PARAMS_LOAD )
334 int i, j, dups, dup_index;
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;
340 char skinname[ MD2_MAX_SKINNAME ];
344 md2Triangle_t *triangle;
345 md2XyzNormal_t *vertex;
348 picoModel_t *picoModel;
349 picoSurface_t *picoSurface;
350 picoShader_t *picoShader;
351 picoVec3_t xyz, normal;
357 bb = (picoByte_t*) buffer;
358 md2 = (md2_t*) buffer;
360 /* check ident and version */
361 if( *((int*) md2->magic) != *((int*) MD2_MAGIC) || _pico_little_long( md2->version ) != MD2_VERSION )
363 /* not an md2 file (todo: set error) */
364 _pico_printf( PICO_ERROR, "%s is not an MD2 File!", fileName );
369 md2->version = _pico_little_long( md2->version );
371 md2->skinWidth = _pico_little_long( md2->skinWidth );
372 md2->skinHeight = _pico_little_long( md2->skinHeight );
373 md2->frameSize = _pico_little_long( md2->frameSize );
375 md2->numSkins = _pico_little_long( md2->numSkins );
376 md2->numXYZ = _pico_little_long( md2->numXYZ );
377 md2->numST = _pico_little_long( md2->numST );
378 md2->numTris = _pico_little_long( md2->numTris );
379 md2->numGLCmds = _pico_little_long( md2->numGLCmds );
380 md2->numFrames = _pico_little_long( md2->numFrames );
382 md2->ofsSkins = _pico_little_long( md2->ofsSkins );
383 md2->ofsST = _pico_little_long( md2->ofsST );
384 md2->ofsTris = _pico_little_long( md2->ofsTris );
385 md2->ofsFrames = _pico_little_long( md2->ofsFrames );
386 md2->ofsGLCmds = _pico_little_long( md2->ofsGLCmds );
387 md2->ofsEnd = _pico_little_long( md2->ofsEnd );
390 if( md2->numFrames < 1 )
392 _pico_printf( PICO_ERROR, "%s has 0 frames!", fileName );
396 if( frameNum < 0 || frameNum >= md2->numFrames )
398 _pico_printf( PICO_ERROR, "Invalid or out-of-range MD2 frame specified" );
403 frame = (md2Frame_t *) (bb + md2->ofsFrames + (sizeof(md2Frame_t) * frameNum));
405 // swap frame scale and translation
406 for( i = 0; i < 3; i++ )
408 frame->scale[ i ] = _pico_little_float( frame->scale[ i ] );
409 frame->translate[ i ] = _pico_little_float( frame->translate[ i ] );
413 triangle = (md2Triangle_t *) ((picoByte_t *) (bb + md2->ofsTris) );
414 for( i = 0; i < md2->numTris; i++, triangle++ )
416 for( j = 0; j < 3; j++ )
418 triangle->index_xyz[ j ] = _pico_little_short( triangle->index_xyz[ j ] );
419 triangle->index_st[ j ] = _pico_little_short( triangle->index_st[ j ] );
424 texCoord = (md2St_t*) ((picoByte_t *) (bb + md2->ofsST) );
425 for( i = 0; i < md2->numST; i++, texCoord++ )
427 texCoord->s = _pico_little_short( texCoord->s );
428 texCoord->t = _pico_little_short( texCoord->t );
432 strncpy(skinname, (bb + md2->ofsSkins), MD2_MAX_SKINNAME );
434 // Print out md2 values
435 _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 );
438 _pico_setfext( skinname, "" );
439 _pico_unixify( skinname );
441 /* create new pico model */
442 picoModel = PicoNewModel();
443 if( picoModel == NULL )
445 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
450 PicoSetModelFrameNum( picoModel, frameNum );
451 PicoSetModelNumFrames( picoModel, md2->numFrames ); /* sea */
452 PicoSetModelName( picoModel, fileName );
453 PicoSetModelFileName( picoModel, fileName );
455 // allocate new pico surface
456 picoSurface = PicoNewSurface( picoModel );
457 if( picoSurface == NULL )
459 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
460 PicoFreeModel( picoModel );
465 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
466 PicoSetSurfaceName( picoSurface, frame->name );
467 picoShader = PicoNewShader( picoModel );
468 if( picoShader == NULL )
470 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
471 PicoFreeModel( picoModel );
475 PicoSetShaderName( picoShader, skinname );
477 // associate current surface with newly created shader
478 PicoSetSurfaceShader( picoSurface, picoShader );
480 // Init LUT for Verts
481 p_index_LUT = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t) * md2->numXYZ);
482 for(i=0; i<md2->numXYZ; i++)
484 p_index_LUT[i].Vert = -1;
485 p_index_LUT[i].ST = -1;
486 p_index_LUT[i].next = NULL;
489 // Fill in Look Up Table, and allocate/fill Linked List from vert array as needed for dup STs per Vert.
490 tot_numVerts = md2->numXYZ;
492 for(i=0; i<md2->numTris; i++)
494 p_md2Triangle = (md2Triangle_t *) ( bb + md2->ofsTris + (sizeof(md2Triangle_t)*i));
497 if (p_index_LUT[p_md2Triangle->index_xyz[j]].ST == -1) // No Main Entry
498 p_index_LUT[p_md2Triangle->index_xyz[j]].ST = p_md2Triangle->index_st[j];
500 else if (p_md2Triangle->index_st[j] == p_index_LUT[p_md2Triangle->index_xyz[j]].ST ) // Equal to Main Entry
503 else if ( (p_index_LUT[p_md2Triangle->index_xyz[j]].next == NULL) ) // Not equal to Main entry, and no LL entry
504 { // Add first entry of LL from Main
505 p_index_LUT2 = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t));
506 if (p_index_LUT2 == NULL)
507 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
508 p_index_LUT[p_md2Triangle->index_xyz[j]].next = (index_LUT_t *)p_index_LUT2;
509 p_index_LUT2->Vert = dups;
510 p_index_LUT2->ST = p_md2Triangle->index_st[j];
511 p_index_LUT2->next = NULL;
512 p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
515 else // Try to find in LL from Main Entry
517 p_index_LUT3 = p_index_LUT2 = p_index_LUT[p_md2Triangle->index_xyz[j]].next;
518 while ( (p_index_LUT2 != NULL) && (p_md2Triangle->index_xyz[j] != p_index_LUT2->Vert) ) // Walk down LL
520 p_index_LUT3 = p_index_LUT2;
521 p_index_LUT2 = p_index_LUT2->next;
523 p_index_LUT2 = p_index_LUT3;
525 if ( p_md2Triangle->index_st[j] == p_index_LUT2->ST ) // Found it
527 p_md2Triangle->index_xyz[j] = p_index_LUT2->Vert + md2->numXYZ; // Make change in Tri hunk
531 if ( p_index_LUT2->next == NULL) // Didn't find it. Add entry to LL.
534 p_index_LUT3 = (index_LUT_t *)_pico_alloc(sizeof(index_LUT_t));
535 if (p_index_LUT3 == NULL)
536 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
537 p_index_LUT2->next = (index_LUT_t *)p_index_LUT3;
538 p_index_LUT3->Vert = p_md2Triangle->index_xyz[j];
539 p_index_LUT3->ST = p_md2Triangle->index_st[j];
540 p_index_LUT3->next = NULL;
541 p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
548 // malloc and build array for Dup STs
549 p_index_LUT_DUPS = (index_DUP_LUT_t *)_pico_alloc(sizeof(index_DUP_LUT_t) * dups);
550 if (p_index_LUT_DUPS == NULL)
551 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n");
554 for(i=0; i<md2->numXYZ; i++)
556 p_index_LUT2 = p_index_LUT[i].next;
557 while (p_index_LUT2 != NULL)
559 p_index_LUT_DUPS[p_index_LUT2->Vert].OldVert = i;
560 p_index_LUT_DUPS[p_index_LUT2->Vert].ST = p_index_LUT2->ST;
562 p_index_LUT2 = p_index_LUT2->next;
567 triangle = (md2Triangle_t *) ((picoByte_t *) (bb + md2->ofsTris) );
568 texCoord = (md2St_t*) ((picoByte_t *) (bb + md2->ofsST) );
569 vertex = (md2XyzNormal_t*) ((picoByte_t*) (frame->verts) );
570 for( j = 0; j < md2->numTris; j++, triangle++ )
572 PicoSetSurfaceIndex( picoSurface, j*3 , triangle->index_xyz[0] );
573 PicoSetSurfaceIndex( picoSurface, j*3+1 , triangle->index_xyz[1] );
574 PicoSetSurfaceIndex( picoSurface, j*3+2 , triangle->index_xyz[2] );
577 for(i=0; i< md2->numXYZ; i++, vertex++)
579 /* set vertex origin */
580 xyz[ 0 ] = vertex->v[0] * frame->scale[0] + frame->translate[0];
581 xyz[ 1 ] = vertex->v[1] * frame->scale[1] + frame->translate[1];
582 xyz[ 2 ] = vertex->v[2] * frame->scale[2] + frame->translate[2];
583 PicoSetSurfaceXYZ( picoSurface, i , xyz );
586 normal[ 0 ] = md2_normals[vertex->lightnormalindex][0];
587 normal[ 1 ] = md2_normals[vertex->lightnormalindex][1];
588 normal[ 2 ] = md2_normals[vertex->lightnormalindex][2];
589 PicoSetSurfaceNormal( picoSurface, i , normal );
592 st[ 0 ] = ((texCoord[p_index_LUT[i].ST].s) / ((float)md2->skinWidth));
593 st[ 1 ] = (texCoord[p_index_LUT[i].ST].t / ((float)md2->skinHeight));
594 PicoSetSurfaceST( picoSurface, 0, i , st );
599 for(i=0; i<dups; i++)
601 j = p_index_LUT_DUPS[i].OldVert;
602 /* set vertex origin */
603 xyz[ 0 ] = frame->verts[j].v[0] * frame->scale[0] + frame->translate[0];
604 xyz[ 1 ] = frame->verts[j].v[1] * frame->scale[1] + frame->translate[1];
605 xyz[ 2 ] = frame->verts[j].v[2] * frame->scale[2] + frame->translate[2];
606 PicoSetSurfaceXYZ( picoSurface, i + md2->numXYZ , xyz );
609 normal[ 0 ] = md2_normals[frame->verts[j].lightnormalindex][0];
610 normal[ 1 ] = md2_normals[frame->verts[j].lightnormalindex][1];
611 normal[ 2 ] = md2_normals[frame->verts[j].lightnormalindex][2];
612 PicoSetSurfaceNormal( picoSurface, i + md2->numXYZ , normal );
615 st[ 0 ] = ((texCoord[p_index_LUT_DUPS[i].ST].s) / ((float)md2->skinWidth));
616 st[ 1 ] = (texCoord[p_index_LUT_DUPS[i].ST].t / ((float)md2->skinHeight));
617 PicoSetSurfaceST( picoSurface, 0, i + md2->numXYZ , st );
622 PicoSetSurfaceColor( picoSurface, 0, 0, color );
624 // Free up malloc'ed LL entries
625 for(i=0; i<md2->numXYZ; i++)
627 if(p_index_LUT[i].next != NULL)
629 p_index_LUT2 = p_index_LUT[i].next;
631 p_index_LUT3 = p_index_LUT2->next;
632 _pico_free(p_index_LUT2);
633 p_index_LUT2 = p_index_LUT3;
635 } while (p_index_LUT2 != NULL);
640 _pico_printf(PICO_WARNING, " Not all LL mallocs freed\n");
642 // Free malloc'ed LUTs
643 _pico_free(p_index_LUT);
644 _pico_free(p_index_LUT_DUPS);
646 /* return the new pico model */
653 /* pico file format module definition */
654 const picoModule_t picoModuleMD2 =
656 "0.875", /* module version string */
657 "Quake 2 MD2", /* module display name */
658 "Nurail", /* author's name */
659 "2003 Nurail", /* module copyright */
661 "md2", NULL, NULL, NULL /* default extensions to use */
663 _md2_canload, /* validation routine */
664 _md2_load, /* load routine */
665 NULL, /* save validation routine */
666 NULL /* save routine */