shithub: qk1

Download patch

ref: 2772ba4f6025cd091184c15675e29211c355b3a7
parent: e84be7125ed52c674b2d46550751e56e18fe8356
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Dec 11 20:20:06 EST 2023

add support for external .vis files

--- a/model.c
+++ b/model.c
@@ -248,6 +248,7 @@
 	radix(mod->name, loadname);
 
 	// fill it in
+	mod->lmpfrom = fs_lmpfrom;
 
 	// call the apropriate loader
 	mod->needload = NL_PRESENT;
--- a/model.h
+++ b/model.h
@@ -313,6 +313,7 @@
 	int ver;
 	int numwads;
 	Wad **wads;
+	char *lmpfrom;
 
 	modtype_t	type;
 	int			numframes;
--- a/model_brush.c
+++ b/model_brush.c
@@ -50,7 +50,7 @@
 void
 Mod_LoadBrushModel(model_t *mod, byte *in0, int total)
 {
-	int i, j, ver, off, sz;
+	int i, j, off, sz;
 	model_t *submod;
 	byte *in;
 	submodel_t *bm;
@@ -91,15 +91,17 @@
 	};
 
 	in = in0;
-	ver = le32(in);
-	if(ver == BSPVERSION){
+	mod->type = mod_brush;
+	mod->ver = le32(in);
+	mod->leafs = nil;
+	if(mod->ver == BSPVERSION){
 		// all set
-	}else if(ver == BSP30VERSION){
+	}else if(mod->ver == BSP30VERSION){
 		loadf[LUMP_ENTITIES] = BSP30_LoadEntities,
 		loadf[LUMP_FACES] = BSP30_LoadFaces;
 		loadf[LUMP_LIGHTING] = BSP30_LoadLighting;
 		loadf[LUMP_TEXTURES] = BSP30_LoadTextures;
-	}else if(ver == BSP2VERSION){
+	}else if(mod->ver == BSP2VERSION){
 		loadf[LUMP_EDGES] = BSP2_LoadEdges;
 		loadf[LUMP_FACES] = BSP2_LoadFaces;
 		loadf[LUMP_MARKSURFACES] = BSP2_LoadMarksurfaces;
@@ -107,7 +109,7 @@
 		loadf[LUMP_NODES] = BSP2_LoadNodes;
 		loadf[LUMP_CLIPNODES] = BSP2_LoadClipnodes;
 	}else{
-		werrstr("unsupported version: %d", ver);
+		werrstr("unsupported version: %d", mod->ver);
 		goto err;
 	}
 
@@ -115,9 +117,6 @@
 		werrstr("truncated: total=%d", total);
 		goto err;
 	}
-
-	mod->type = mod_brush;
-	mod->ver = ver;
 
 	for(i = 0; i < nelem(loadf); i++){
 		in = in0+4+2*4*order[i];
--- a/model_bsp.c
+++ b/model_bsp.c
@@ -247,11 +247,90 @@
 }
 
 int
+BSP_LoadLeafs(model_t *mod, byte *in, int sz)
+{
+	mleaf_t *out;
+	int i, j, p;
+	static const int elsz = 4+4+3*2+3*2+2+2+Namb;
+
+	// skip if loaded external one
+	if(mod->leafs != nil)
+		return 0;
+
+	if(sz % elsz){
+		werrstr("BSP_LoadLeafs: funny lump size");
+		return -1;
+	}
+	mod->numleafs = sz / elsz;
+	mod->leafs = out = Hunk_Alloc(mod->numleafs * sizeof(*out));
+
+	for(i = 0; i < mod->numleafs; i++, out++){
+		out->contents = le32(in);
+		out->compressed_vis = (p = le32(in)) < 0 ? nil : mod->visdata + p;
+
+		for(j = 0; j < 3; j++)
+			out->minmaxs[0+j] = le16(in);
+		for(j = 0; j < 3; j++)
+			out->minmaxs[3+j] = le16(in);
+
+		out->firstmarksurface = mod->marksurfaces + le16u(in);
+		out->nummarksurfaces = le16u(in);
+
+		memmove(out->ambient_sound_level, in, Namb);
+		in += Namb;
+	}
+	return 0;
+}
+
+int
 BSP_LoadVisibility(model_t *mod, byte *in, int sz)
 {
+	char s[32+1], *t;
+	byte *vis, *leaf;
+	int filesz, combined, vissz, leafsz;
+
+	mod->visdata = nil;
 	if(sz == 0)
-		mod->visdata = nil;
-	else
+		return 0;
+
+	// external vis files
+	// FIXME(sigrid): add support for big combo ("id1.vis") files?
+	if(mod->ver == BSPVERSION){ // bsp2 should have proper vis built in already
+		strcpy(s, mod->name);
+		if((t = strrchr(s, '.')) != nil){
+			strcpy(t, ".vis");
+			if((t = strrchr(mod->name, '/')) != nil)
+				t++;
+			else
+				t = mod->name;
+			vis = loadhunklmp(s, &filesz);
+			if(vis != nil && strcmp(fs_lmpfrom, mod->lmpfrom) == 0 && filesz >= 32+4+4+4){
+				vis += 32;
+				combined = le32(vis);
+				filesz -= 32+4;
+				vis[-4] = 0;
+				if(combined > filesz || strcmp(t, (char*)&vis[-32-4]) != 0){
+bad:
+					Con_Printf("%s: invalid/unsupported VIS file\n", s);
+					mod->visdata = nil;
+					mod->leafs = nil;
+				}else{
+					vissz = le32(vis);
+					combined -= 4;
+					if(vissz+4 > combined)
+						goto bad;
+					mod->visdata = vis;
+					leaf = vis + vissz;
+					leafsz = le32(leaf);
+					combined -= 4;
+					if(leafsz > combined || BSP_LoadLeafs(mod, leaf, leafsz) != 0)
+						goto bad;
+				}
+			}
+		}
+	}
+
+	if(mod->visdata == nil)
 		memcpy(mod->visdata = Hunk_Alloc(sz), in, sz);
 	return 0;
 }
@@ -484,38 +563,6 @@
 	}
 
 	BSP_SetParent(mod->nodes, nil); // sets nodes and leafs
-	return 0;
-}
-
-int
-BSP_LoadLeafs(model_t *mod, byte *in, int sz)
-{
-	mleaf_t *out;
-	int i, j, p;
-	static const int elsz = 4+4+3*2+3*2+2+2+Namb;
-
-	if(sz % elsz){
-		werrstr("BSP_LoadLeafs: funny lump size");
-		return -1;
-	}
-	mod->numleafs = sz / elsz;
-	mod->leafs = out = Hunk_Alloc(mod->numleafs * sizeof(*out));
-
-	for(i = 0; i < mod->numleafs; i++, out++){
-		out->contents = le32(in);
-		out->compressed_vis = (p = le32(in)) < 0 ? nil : mod->visdata + p;
-
-		for(j = 0; j < 3; j++)
-			out->minmaxs[0+j] = le16(in);
-		for(j = 0; j < 3; j++)
-			out->minmaxs[3+j] = le16(in);
-
-		out->firstmarksurface = mod->marksurfaces + le16u(in);
-		out->nummarksurfaces = le16u(in);
-
-		memmove(out->ambient_sound_level, in, Namb);
-		in += Namb;
-	}
 	return 0;
 }