shithub: qk1

Download patch

ref: 40402e51183b677122198d5bb16ce31a87e40a9f
parent: e0318617afc836d3756390ffd3f9d6cb3d5f52ca
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sat Nov 25 15:12:38 EST 2023

rewrite sprite loading; move to its own file

--- a/Makefile
+++ b/Makefile
@@ -46,6 +46,7 @@
 	model_brush.o\
 	model_bsp.o\
 	model_bsp2.o\
+	model_sprite.o\
 	net_loop.o\
 	net_main.o\
 	pal.o\
--- a/mkfile
+++ b/mkfile
@@ -44,6 +44,7 @@
 	model_brush.$O\
 	model_bsp.$O\
 	model_bsp2.$O\
+	model_sprite.$O\
 	nanosec.$O\
 	net_dgrm.$O\
 	net_loop.$O\
--- a/model.c
+++ b/model.c
@@ -2,8 +2,8 @@
 
 static char loadname[32];	// for hunk tags
 
-void Mod_LoadSpriteModel (model_t *mod, void *buffer);
-void Mod_LoadBrushModel (model_t *mod, void *buffer, int total);
+void Mod_LoadSpriteModel (model_t *mod, byte *buffer, int total);
+void Mod_LoadBrushModel (model_t *mod, byte *buffer, int total);
 void Mod_LoadAliasModel (model_t *mod, void *buffer);
 model_t *Mod_LoadModel (model_t *mod, bool crash);
 
@@ -259,7 +259,7 @@
 		break;
 
 	case IDSPRITEHEADER:
-		Mod_LoadSpriteModel(mod, buf);
+		Mod_LoadSpriteModel(mod, buf, len);
 		break;
 
 	default:
@@ -663,168 +663,6 @@
 
 	Hunk_CacheFrom(&mod->cache, pheader);
 }
-
-void *
-Mod_LoadSpriteFrame(void * pin, mspriteframe_t **ppframe)
-{
-	int width, height, size, origin[2];
-	dspriteframe_t *pinframe;
-	mspriteframe_t *pspriteframe;
-
-	pinframe = (dspriteframe_t *)pin;
-
-	width = LittleLong(pinframe->width);
-	height = LittleLong(pinframe->height);
-	size = width * height;
-
-	pspriteframe = Hunk_Alloc(size + sizeof *pspriteframe);
-
-	memset(pspriteframe, 0, size + sizeof *pspriteframe);
-	*ppframe = pspriteframe;
-
-	pspriteframe->width = width;
-	pspriteframe->height = height;
-	origin[0] = LittleLong (pinframe->origin[0]);
-	origin[1] = LittleLong (pinframe->origin[1]);
-
-	pspriteframe->up = origin[1];
-	pspriteframe->down = origin[1] - height;
-	pspriteframe->left = origin[0];
-	pspriteframe->right = width + origin[0];
-
-	memcpy(&pspriteframe->pixels[0], (uchar *)(pinframe + 1), size);
-	return (void *)((byte *)pinframe + size + sizeof *pinframe);
-}
-
-
-/*
-=================
-Mod_LoadSpriteGroup
-=================
-*/
-void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe)
-{
-	dspritegroup_t		*pingroup;
-	mspritegroup_t		*pspritegroup;
-	int					i, numframes;
-	dspriteinterval_t	*pin_intervals;
-	float				*poutintervals;
-	void				*ptemp;
-
-	pingroup = (dspritegroup_t *)pin;
-
-	numframes = LittleLong (pingroup->numframes);
-
-	pspritegroup = Hunk_Alloc(sizeof(*pspritegroup) +
-		(numframes - 1) * sizeof pspritegroup->frames[0]);
-
-	pspritegroup->numframes = numframes;
-
-	*ppframe = (mspriteframe_t *)pspritegroup;
-
-	pin_intervals = (dspriteinterval_t *)(pingroup + 1);
-
-	poutintervals = Hunk_Alloc(numframes * sizeof *poutintervals);
-
-	pspritegroup->intervals = poutintervals;
-
-	for (i=0 ; i<numframes ; i++)
-	{
-		*poutintervals = LittleFloat (pin_intervals->interval);
-		if (*poutintervals <= 0.0)
-			Host_Error("Mod_LoadSpriteGroup: interval<=0");
-
-		poutintervals++;
-		pin_intervals++;
-	}
-
-	ptemp = (void *)pin_intervals;
-
-	for (i=0 ; i<numframes ; i++)
-	{
-		ptemp = Mod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i]);
-	}
-
-	return ptemp;
-}
-
-
-/*
-=================
-Mod_LoadSpriteModel
-=================
-*/
-void Mod_LoadSpriteModel (model_t *mod, void *buffer)
-{
-	int					i;
-	int					version;
-	dsprite_t			*pin;
-	msprite_t			*psprite;
-	int					numframes;
-	int					size;
-	dspriteframetype_t	*pframetype;
-
-	pin = (dsprite_t *)buffer;
-
-	version = LittleLong (pin->version);
-	if (version != SPRITE_VERSION)
-		Host_Error("%s has wrong version number "
-				 "(%d should be %d)", mod->name, version, SPRITE_VERSION);
-
-	numframes = LittleLong (pin->numframes);
-
-	size = sizeof (msprite_t) +	(numframes - 1) * sizeof (psprite->frames);
-
-	psprite = Hunk_Alloc(size);
-
-	mod->cache.data = psprite;
-
-	psprite->type = LittleLong (pin->type);
-	psprite->maxwidth = LittleLong (pin->width);
-	psprite->maxheight = LittleLong (pin->height);
-	psprite->beamlength = LittleFloat (pin->beamlength);
-	mod->synctype = LittleLong (pin->synctype);
-	psprite->numframes = numframes;
-
-	mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2;
-	mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2;
-	mod->mins[2] = -psprite->maxheight/2;
-	mod->maxs[2] = psprite->maxheight/2;
-
-	// load the frames
-	if (numframes < 1)
-		Host_Error("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes);
-
-	mod->numframes = numframes;
-	mod->flags = 0;
-
-	pframetype = (dspriteframetype_t *)(pin + 1);
-
-	for (i=0 ; i<numframes ; i++)
-	{
-		spriteframetype_t	frametype;
-
-		frametype = LittleLong (pframetype->type);
-		psprite->frames[i].type = frametype;
-
-		if (frametype == SPR_SINGLE)
-		{
-			pframetype = (dspriteframetype_t *)
-					Mod_LoadSpriteFrame (pframetype + 1,
-										 &psprite->frames[i].frameptr);
-		}
-		else
-		{
-			pframetype = (dspriteframetype_t *)
-					Mod_LoadSpriteGroup (pframetype + 1,
-										 &psprite->frames[i].frameptr);
-		}
-	}
-
-	mod->type = mod_sprite;
-}
-
-//=============================================================================
 
 /*
 ================
--- a/model.h
+++ b/model.h
@@ -186,24 +186,28 @@
 {
 	int				numframes;
 	float			*intervals;
-	mspriteframe_t	*frames[1];
+	mspriteframe_t	*frames[0];
 } mspritegroup_t;
 
 typedef struct
 {
 	spriteframetype_t	type;
-	mspriteframe_t		*frameptr;
+	union {
+		mspriteframe_t *frameptr;
+		mspritegroup_t *framegrp;
+	};
 } mspriteframedesc_t;
 
 typedef struct
 {
 	int					type;
+	float				boundingradius;
 	int					maxwidth;
 	int					maxheight;
 	int					numframes;
 	float				beamlength;		// remove?
 	void				*cachespot;		// remove?
-	mspriteframedesc_t	frames[1];
+	mspriteframedesc_t	frames[0];
 } msprite_t;
 
 
--- a/model_brush.c
+++ b/model_brush.c
@@ -43,11 +43,11 @@
 }
 
 void
-Mod_LoadBrushModel(model_t *mod, void *buffer, int total)
+Mod_LoadBrushModel(model_t *mod, byte *in0, int total)
 {
 	int i, j, ver, off, sz;
 	model_t *submod;
-	byte *in, *in0;
+	byte *in;
 	submodel_t *bm;
 	char name[16];
 	int (*loadf[HEADER_LUMPS])(model_t *, byte *, int) = {
@@ -85,7 +85,7 @@
 		LUMP_MODELS,
 	};
 
-	in0 = in = buffer;
+	in = in0;
 	ver = le32(in);
 	if(ver == BSPVERSION){
 		loadf[LUMP_EDGES] = BSP_LoadEdges;
--- /dev/null
+++ b/model_sprite.c
@@ -1,0 +1,143 @@
+#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());
+}