int lwGetPoints( picoMemStream_t *fp, int cksize, lwPointList *point ) { float *f; int np, i, j; if ( cksize == 1 ) return 1; /* extend the point array to hold the new points */ np = cksize / 12; point->offset = point->count; point->count += np; if ( !_pico_realloc( (void *) &point->pt, (point->count - np) * sizeof( lwPoint ), point->count * sizeof( lwPoint )) ) return 0; memset( &point->pt[ point->offset ], 0, np * sizeof( lwPoint )); /* read the whole chunk */ f = ( float * ) getbytes( fp, cksize ); if ( !f ) return 0; revbytes( f, 4, np * 3 ); /* assign position values */ for ( i = 0, j = 0; i < np; i++, j += 3 ) { point->pt[ i ].pos[ 0 ] = f[ j ]; point->pt[ i ].pos[ 1 ] = f[ j + 1 ]; point->pt[ i ].pos[ 2 ] = f[ j + 2 ]; } _pico_free( f ); return 1; }
/** * @brief adjusts a models's memory allocations to handle the requested sizes. * will always grow, never shrink */ int PicoAdjustModel (picoModel_t *model, int numShaders, int numSurfaces) { /* dummy check */ if (model == NULL) return 0; /* bare minimums */ /* sea: null surface/shader fix (1s=>0s) */ if (numShaders < 0) numShaders = 0; if (numSurfaces < 0) numSurfaces = 0; /* additional shaders? */ while (numShaders > model->maxShaders) { model->maxShaders += PICO_GROW_SHADERS; if (!_pico_realloc((void *) &model->shader, model->numShaders * sizeof(*model->shader), model->maxShaders * sizeof(*model->shader))) return 0; } /* set shader count to higher */ if (numShaders > model->numShaders) model->numShaders = numShaders; /* additional surfaces? */ while (numSurfaces > model->maxSurfaces) { model->maxSurfaces += PICO_GROW_SURFACES; if (!_pico_realloc((void *) &model->surface, model->numSurfaces * sizeof(*model->surface), model->maxSurfaces * sizeof(*model->surface))) return 0; } /* set shader count to higher */ if (numSurfaces > model->numSurfaces) model->numSurfaces = numSurfaces; /* return ok */ return 1; }
int lwGetTags( picoMemStream_t *fp, int cksize, lwTagList *tlist ){ char *buf, *bp; int i, len, ntags; if ( cksize == 0 ) { return 1; } /* read the whole chunk */ set_flen( 0 ); buf = getbytes( fp, cksize ); if ( !buf ) { return 0; } /* count the strings */ ntags = 0; bp = buf; while ( bp < buf + cksize ) { len = strlen( bp ) + 1; len += len & 1; bp += len; ++ntags; } /* expand the string array to hold the new tags */ tlist->offset = tlist->count; tlist->count += ntags; if ( !_pico_realloc( (void *) &tlist->tag, ( tlist->count - ntags ) * sizeof( char * ), tlist->count * sizeof( char * ) ) ) { goto Fail; } memset( &tlist->tag[ tlist->offset ], 0, ntags * sizeof( char * ) ); /* copy the new tags to the tag array */ bp = buf; for ( i = 0; i < ntags; i++ ) tlist->tag[ i + tlist->offset ] = sgetS0( &bp ); _pico_free( buf ); return 1; Fail: if ( buf ) { _pico_free( buf ); } return 0; }
int lwAllocPolygons( lwPolygonList *plist, int npols, int nverts ) { int i; plist->offset = plist->count; plist->count += npols; if ( !_pico_realloc( (void *) &plist->pol, (plist->count - npols) * sizeof( lwPolygon ), plist->count * sizeof( lwPolygon )) ) return 0; memset( plist->pol + plist->offset, 0, npols * sizeof( lwPolygon )); plist->voffset = plist->vcount; plist->vcount += nverts; if ( !_pico_realloc( (void *) &plist->pol[ 0 ].v, (plist->vcount - nverts) * sizeof( lwPolVert ), plist->vcount * sizeof( lwPolVert )) ) return 0; memset( plist->pol[ 0 ].v + plist->voffset, 0, nverts * sizeof( lwPolVert )); /* fix up the old vertex pointers */ for ( i = 1; i < plist->offset; i++ ) plist->pol[ i ].v = plist->pol[ i - 1 ].v + plist->pol[ i - 1 ].nverts; return 1; }
/** * @brief This pretty piece of 'alloc ahead' code dynamically * allocates - and reallocates as soon as required - * my vertex data array in even steps. */ static TObjVertexData *SizeObjVertexData (TObjVertexData *vertexData, int reqEntries, int *entries, int *allocated) { int newAllocated; /* sanity checks */ if (reqEntries < 1) return NULL; if (entries == NULL || allocated == NULL) return NULL; /* must have */ /* no need to grow yet */ if (vertexData && (reqEntries < *allocated)) { *entries = reqEntries; return vertexData; } /* given vertex data ptr not allocated yet */ if (vertexData == NULL) { /* how many entries to allocate */ newAllocated = (reqEntries > SIZE_OBJ_STEP) ? reqEntries : SIZE_OBJ_STEP; /* throw out an extended debug message */ #ifdef DEBUG_PM_OBJ_EX printf("SizeObjVertexData: allocate (%d entries)\n", newAllocated); #endif /* first time allocation */ vertexData = (TObjVertexData *) _pico_alloc(sizeof(TObjVertexData) * newAllocated); /* allocation failed */ if (vertexData == NULL) return NULL; /* allocation succeeded */ *allocated = newAllocated; *entries = reqEntries; return vertexData; } /* given vertex data ptr needs to be resized */ if (reqEntries == *allocated) { newAllocated = (*allocated + SIZE_OBJ_STEP); /* throw out an extended debug message */ #ifdef DEBUG_PM_OBJ_EX printf("SizeObjVertexData: reallocate (%d entries)\n", newAllocated); #endif /* try to reallocate */ vertexData = (TObjVertexData *) _pico_realloc((void *) &vertexData, sizeof(TObjVertexData) * (*allocated), sizeof(TObjVertexData) * (newAllocated)); /* reallocation failed */ if (vertexData == NULL) return NULL; /* reallocation succeeded */ *allocated = newAllocated; *entries = reqEntries; return vertexData; } /* we're b0rked when we reach this */ return NULL; }
/** * @brief adjusts a surface's memory allocations to handle the requested sizes. * will always grow, never shrink */ int PicoAdjustSurface (picoSurface_t *surface, int numVertexes, int numSTArrays, int numColorArrays, int numIndexes, int numFaceNormals) { int i; /* dummy check */ if (surface == NULL) return 0; /* bare minimums */ if (numVertexes < 1) numVertexes = 1; if (numSTArrays < 1) numSTArrays = 1; if (numColorArrays < 1) numColorArrays = 1; if (numIndexes < 1) numIndexes = 1; /* additional vertexes? */ while (numVertexes > surface->maxVertexes) { /* fix */ surface->maxVertexes += PICO_GROW_VERTEXES; if (!_pico_realloc((void *) &surface->xyz, surface->numVertexes * sizeof(*surface->xyz), surface->maxVertexes * sizeof(*surface->xyz))) return 0; if (!_pico_realloc((void *) &surface->normal, surface->numVertexes * sizeof(*surface->normal), surface->maxVertexes * sizeof(*surface->normal))) return 0; if (!_pico_realloc((void *) &surface->smoothingGroup, surface->numVertexes * sizeof(*surface->smoothingGroup), surface->maxVertexes * sizeof(*surface->smoothingGroup))) return 0; for (i = 0; i < surface->numSTArrays; i++) if (!_pico_realloc((void*) &surface->st[i], surface->numVertexes * sizeof(*surface->st[i]), surface->maxVertexes * sizeof(*surface->st[i]))) return 0; for (i = 0; i < surface->numColorArrays; i++) if (!_pico_realloc((void*) &surface->color[i], surface->numVertexes * sizeof(*surface->color[i]), surface->maxVertexes * sizeof(*surface->color[i]))) return 0; } /* set vertex count to higher */ if (numVertexes > surface->numVertexes) surface->numVertexes = numVertexes; /* additional st arrays? */ while (numSTArrays > surface->maxSTArrays) { /* fix */ surface->maxSTArrays += PICO_GROW_ARRAYS; if (!_pico_realloc((void*) &surface->st, surface->numSTArrays * sizeof(*surface->st), surface->maxSTArrays * sizeof(*surface->st))) return 0; while (surface->numSTArrays < numSTArrays) { surface->st[surface->numSTArrays] = _pico_alloc(surface->maxVertexes * sizeof(*surface->st[0])); memset(surface->st[surface->numSTArrays], 0, surface->maxVertexes * sizeof(*surface->st[0])); surface->numSTArrays++; } } /* additional color arrays? */ while (numColorArrays > surface->maxColorArrays) { /* fix */ surface->maxColorArrays += PICO_GROW_ARRAYS; if (!_pico_realloc((void*) &surface->color, surface->numColorArrays * sizeof(*surface->color), surface->maxColorArrays * sizeof(*surface->color))) return 0; while (surface->numColorArrays < numColorArrays) { surface->color[surface->numColorArrays] = _pico_alloc(surface->maxVertexes * sizeof(*surface->color[0])); memset(surface->color[surface->numColorArrays], 0, surface->maxVertexes * sizeof(*surface->color[0])); surface->numColorArrays++; } } /* additional indexes? */ while (numIndexes > surface->maxIndexes) { /* fix */ surface->maxIndexes += PICO_GROW_INDEXES; if (!_pico_realloc((void*) &surface->index, surface->numIndexes * sizeof(*surface->index), surface->maxIndexes * sizeof(*surface->index))) return 0; } /* set index count to higher */ if (numIndexes > surface->numIndexes) surface->numIndexes = numIndexes; /* additional face normals? */ while (numFaceNormals > surface->maxFaceNormals) { /* fix */ surface->maxFaceNormals += PICO_GROW_FACES; if (!_pico_realloc((void *) &surface->faceNormal, surface->numFaceNormals * sizeof(*surface->faceNormal), surface->maxFaceNormals * sizeof(*surface->faceNormal))) return 0; } /* set face normal count to higher */ if (numFaceNormals > surface->numFaceNormals) surface->numFaceNormals = numFaceNormals; /* return ok */ return 1; }