ref: b64d816a6b39760ca8df9434d7277bf8babe55b3
dir: /model_sprite.c/
#include "quakedef.h" static byte * Mod_LoadSpriteFrame(byte *in, byte *e, mspriteframe_t **ppframe) { int w, h, size, origin[2]; mspriteframe_t *pspriteframe; if(e-in < 4*4){ toosmall: werrstr("truncated?"); return nil; } origin[0] = le32(in); origin[1] = le32(in); w = le32(in); h = le32(in); if(w < 0 || h < 0){ werrstr("invalid dimensions: %dx%d", w, h); return nil; } if(e-in < (size = w*h)) goto toosmall; *ppframe = pspriteframe = Hunk_Alloc(sizeof(*pspriteframe) + size); pspriteframe->width = w; pspriteframe->height = h; pspriteframe->up = origin[1]; pspriteframe->down = origin[1] - h; pspriteframe->left = origin[0]; pspriteframe->right = w + origin[0]; memmove(pspriteframe->pixels, in, size); in += size; return in; } static byte * Mod_LoadSpriteGroup(byte *in, byte *e, mspritegroup_t **ppgroup) { mspritegroup_t *spgrp; float *poutintervals; int i, numframes; if(e-in < 4){ toosmall: werrstr("truncated?"); return nil; } if((numframes = le32(in)) < 0){ werrstr("invalid number of frames: %d", numframes); return nil; } *ppgroup = spgrp = Hunk_Alloc( sizeof(*spgrp) + numframes*(sizeof(*spgrp->frames) + sizeof(*spgrp->intervals)) ); spgrp->numframes = numframes; poutintervals = (void*)(spgrp->frames + numframes); for(i = 0; i < numframes; i++){ if(e-in < 4) goto toosmall; if((*poutintervals++ = f32(in)) <= 0.0){ werrstr("interval <= 0"); return nil; } } for(i = 0; i < numframes; i++){ in = Mod_LoadSpriteFrame(in, e, &spgrp->frames[i]); if(in == nil) break; } return in; } void Mod_LoadSpriteModel(model_t *mod, byte *in0, int total) { int version, numframes, i; msprite_t *psprite; byte *in, *e; if(total < 9*4){ toosmall: werrstr("file too small"); goto err; } in = in0 + 4; e = in0 + total; if((version = le32(in)) != SPRITE_VERSION){ werrstr("wrong version number (%d should be %d)", version, SPRITE_VERSION); goto err; } in = in0 + 24; if((numframes = le32(in)) < 1){ werrstr("invalid number of frames: %d", numframes); goto err; } psprite = Hunk_Alloc(sizeof(*psprite) + numframes*sizeof(*psprite->frames)); mod->cache.data = psprite; in = in0 + 8; psprite->type = le32(in); psprite->boundingradius = f32(in); psprite->maxwidth = le32(in); psprite->maxheight = le32(in); psprite->numframes = le32(in); psprite->beamlength = f32(in); mod->synctype = le32(in); mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2; mod->maxs[2] = psprite->maxheight/2; mod->mins[0] = mod->mins[1] = -mod->maxs[0]; mod->mins[2] = -mod->maxs[2]; mod->type = mod_sprite; mod->numframes = numframes; mod->flags = 0; for(i = 0; i < numframes; i++){ if(e-in < 4) goto toosmall; if((psprite->frames[i].type = le32(in)) == SPR_SINGLE) in = Mod_LoadSpriteFrame(in, e, &psprite->frames[i].frameptr); else in = Mod_LoadSpriteGroup(in, e, &psprite->frames[i].framegrp); if(in == nil){ werrstr("frame(group) %d: %s", i, lerr()); goto err; } } return; err: Host_Error("Mod_LoadSpriteModel: %s: %s", mod->name, lerr()); }