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 if ( (size_t) bufSize < ( sizeof( *md2 ) * 2 ) ) {
306 return PICO_PMV_ERROR_SIZE;
310 md2 = (const md2_t*) buffer;
312 /* check md2 magic */
313 if ( *( (const int*) md2->magic ) != *( (const int*) MD2_MAGIC ) ) {
314 return PICO_PMV_ERROR_IDENT;
317 /* check md2 version */
318 if ( _pico_little_long( md2->version ) != MD2_VERSION ) {
319 return PICO_PMV_ERROR_VERSION;
322 /* file seems to be a valid md2 */
328 // _md2_load() loads a quake2 md2 model file.
331 static picoModel_t *_md2_load( PM_PARAMS_LOAD ){
332 int i, j, dups, dup_index;
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;
337 char skinname[ MD2_MAX_SKINNAME ];
341 md2Triangle_t *triangle;
342 md2XyzNormal_t *vertex;
344 picoByte_t *bb, *bb0;
345 picoModel_t *picoModel;
346 picoSurface_t *picoSurface;
347 picoShader_t *picoShader;
348 picoVec3_t xyz, normal;
354 bb0 = bb = (picoByte_t*) _pico_alloc( bufSize );
355 memcpy( bb, buffer, bufSize );
358 /* check ident and version */
359 if ( *( (const int*) md2->magic ) != *( (const int*) MD2_MAGIC ) || _pico_little_long( md2->version ) != MD2_VERSION ) {
360 /* not an md2 file (todo: set error) */
361 _pico_printf( PICO_ERROR, "%s is not an MD2 File!", fileName );
367 md2->version = _pico_little_long( md2->version );
369 md2->skinWidth = _pico_little_long( md2->skinWidth );
370 md2->skinHeight = _pico_little_long( md2->skinHeight );
371 md2->frameSize = _pico_little_long( md2->frameSize );
373 md2->numSkins = _pico_little_long( md2->numSkins );
374 md2->numXYZ = _pico_little_long( md2->numXYZ );
375 md2->numST = _pico_little_long( md2->numST );
376 md2->numTris = _pico_little_long( md2->numTris );
377 md2->numGLCmds = _pico_little_long( md2->numGLCmds );
378 md2->numFrames = _pico_little_long( md2->numFrames );
380 md2->ofsSkins = _pico_little_long( md2->ofsSkins );
381 md2->ofsST = _pico_little_long( md2->ofsST );
382 md2->ofsTris = _pico_little_long( md2->ofsTris );
383 md2->ofsFrames = _pico_little_long( md2->ofsFrames );
384 md2->ofsGLCmds = _pico_little_long( md2->ofsGLCmds );
385 md2->ofsEnd = _pico_little_long( md2->ofsEnd );
388 if ( md2->numFrames < 1 ) {
389 _pico_printf( PICO_ERROR, "%s has 0 frames!", fileName );
394 if ( frameNum < 0 || frameNum >= md2->numFrames ) {
395 _pico_printf( PICO_ERROR, "Invalid or out-of-range MD2 frame specified" );
401 frame = (md2Frame_t *) ( bb + md2->ofsFrames + ( sizeof( md2Frame_t ) * frameNum ) );
403 // swap frame scale and translation
404 for ( i = 0; i < 3; i++ )
406 frame->scale[ i ] = _pico_little_float( frame->scale[ i ] );
407 frame->translate[ i ] = _pico_little_float( frame->translate[ i ] );
411 triangle = (md2Triangle_t *) ( (picoByte_t *) ( bb + md2->ofsTris ) );
412 for ( i = 0; i < md2->numTris; i++, triangle++ )
414 for ( j = 0; j < 3; j++ )
416 triangle->index_xyz[ j ] = _pico_little_short( triangle->index_xyz[ j ] );
417 triangle->index_st[ j ] = _pico_little_short( triangle->index_st[ j ] );
422 texCoord = (md2St_t*) ( (picoByte_t *) ( bb + md2->ofsST ) );
423 for ( i = 0; i < md2->numST; i++, texCoord++ )
425 texCoord->s = _pico_little_short( texCoord->s );
426 texCoord->t = _pico_little_short( texCoord->t );
430 strncpy( skinname, (const char *) ( bb + md2->ofsSkins ), MD2_MAX_SKINNAME );
432 // Print out md2 values
433 _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 );
436 _pico_setfext( skinname, "" );
437 _pico_unixify( skinname );
439 /* create new pico model */
440 picoModel = PicoNewModel();
441 if ( picoModel == NULL ) {
442 _pico_printf( PICO_ERROR, "Unable to allocate a new model" );
448 PicoSetModelFrameNum( picoModel, frameNum );
449 PicoSetModelNumFrames( picoModel, md2->numFrames ); /* sea */
450 PicoSetModelName( picoModel, fileName );
451 PicoSetModelFileName( picoModel, fileName );
453 // allocate new pico surface
454 picoSurface = PicoNewSurface( picoModel );
455 if ( picoSurface == NULL ) {
456 _pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
457 PicoFreeModel( picoModel );
463 PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
464 PicoSetSurfaceName( picoSurface, frame->name );
465 picoShader = PicoNewShader( picoModel );
466 if ( picoShader == NULL ) {
467 _pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
468 PicoFreeModel( picoModel );
473 PicoSetShaderName( picoShader, skinname );
475 // associate current surface with newly created shader
476 PicoSetSurfaceShader( picoSurface, picoShader );
478 // Init LUT for Verts
479 p_index_LUT = (index_LUT_t *)_pico_alloc( sizeof( index_LUT_t ) * md2->numXYZ );
480 for ( i = 0; i < md2->numXYZ; i++ )
482 p_index_LUT[i].Vert = -1;
483 p_index_LUT[i].ST = -1;
484 p_index_LUT[i].next = NULL;
487 // Fill in Look Up Table, and allocate/fill Linked List from vert array as needed for dup STs per Vert.
489 for ( i = 0; i < md2->numTris; i++ )
491 p_md2Triangle = (md2Triangle_t *) ( bb + md2->ofsTris + ( sizeof( md2Triangle_t ) * i ) );
492 for ( j = 0; j < 3; j++ )
494 if ( p_index_LUT[p_md2Triangle->index_xyz[j]].ST == -1 ) { // No Main Entry
495 p_index_LUT[p_md2Triangle->index_xyz[j]].ST = p_md2Triangle->index_st[j];
498 else if ( p_md2Triangle->index_st[j] == p_index_LUT[p_md2Triangle->index_xyz[j]].ST ) { // Equal to Main Entry
502 else if ( ( p_index_LUT[p_md2Triangle->index_xyz[j]].next == NULL ) ) { // Not equal to Main entry, and no LL entry
503 // Add first entry of LL from Main
504 p_index_LUT2 = (index_LUT_t *)_pico_alloc( sizeof( index_LUT_t ) );
505 if ( p_index_LUT2 == NULL ) {
506 _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
526 p_md2Triangle->index_xyz[j] = p_index_LUT2->Vert + md2->numXYZ; // Make change in Tri hunk
530 if ( p_index_LUT2->next == NULL ) { // Didn't find it. Add entry to LL.
532 p_index_LUT3 = (index_LUT_t *)_pico_alloc( sizeof( index_LUT_t ) );
533 if ( p_index_LUT3 == NULL ) {
534 _pico_printf( PICO_ERROR," Couldn't allocate memory!\n" );
536 p_index_LUT2->next = (index_LUT_t *)p_index_LUT3;
537 p_index_LUT3->Vert = p_md2Triangle->index_xyz[j];
538 p_index_LUT3->ST = p_md2Triangle->index_st[j];
539 p_index_LUT3->next = NULL;
540 p_md2Triangle->index_xyz[j] = dups + md2->numXYZ; // Make change in Tri hunk
547 // malloc and build array for Dup STs
548 p_index_LUT_DUPS = (index_DUP_LUT_t *)_pico_alloc( sizeof( index_DUP_LUT_t ) * dups );
549 if ( p_index_LUT_DUPS == NULL ) {
550 _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 );
598 for ( i = 0; i < dups; i++ )
600 j = p_index_LUT_DUPS[i].OldVert;
601 /* set vertex origin */
602 xyz[ 0 ] = frame->verts[j].v[0] * frame->scale[0] + frame->translate[0];
603 xyz[ 1 ] = frame->verts[j].v[1] * frame->scale[1] + frame->translate[1];
604 xyz[ 2 ] = frame->verts[j].v[2] * frame->scale[2] + frame->translate[2];
605 PicoSetSurfaceXYZ( picoSurface, i + md2->numXYZ, xyz );
608 normal[ 0 ] = md2_normals[frame->verts[j].lightnormalindex][0];
609 normal[ 1 ] = md2_normals[frame->verts[j].lightnormalindex][1];
610 normal[ 2 ] = md2_normals[frame->verts[j].lightnormalindex][2];
611 PicoSetSurfaceNormal( picoSurface, i + md2->numXYZ, normal );
614 st[ 0 ] = ( ( texCoord[p_index_LUT_DUPS[i].ST].s ) / ( (float)md2->skinWidth ) );
615 st[ 1 ] = ( texCoord[p_index_LUT_DUPS[i].ST].t / ( (float)md2->skinHeight ) );
616 PicoSetSurfaceST( picoSurface, 0, i + md2->numXYZ, st );
621 PicoSetSurfaceColor( picoSurface, 0, 0, color );
623 // Free up malloc'ed LL entries
624 for ( i = 0; i < md2->numXYZ; i++ )
626 if ( p_index_LUT[i].next != NULL ) {
627 p_index_LUT2 = p_index_LUT[i].next;
629 p_index_LUT3 = p_index_LUT2->next;
630 _pico_free( p_index_LUT2 );
631 p_index_LUT2 = p_index_LUT3;
633 } while ( p_index_LUT2 != NULL );
638 _pico_printf( PICO_WARNING, " Not all LL mallocs freed\n" );
641 // Free malloc'ed LUTs
642 _pico_free( p_index_LUT );
643 _pico_free( p_index_LUT_DUPS );
645 /* 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 */