using System;
using System.Text;
using OpenTK;

namespace SharpQuake
{
	internal static class Mod
	{
		public static trivertx_t[][] PoseVerts
		{
			get
			{
				return Mod._PoseVerts;
			}
		}

		public static stvert_t[] STVerts
		{
			get
			{
				return Mod._STVerts;
			}
		}

		public static dtriangle_t[] Triangles
		{
			get
			{
				return Mod._Triangles;
			}
		}

		public static aliashdr_t Header
		{
			get
			{
				return Mod._Header;
			}
		}

		public static model_t Model
		{
			get
			{
				return Mod._LoadModel;
			}
		}

		public static float SubdivideSize
		{
			get
			{
				return Mod._glSubDivideSize.Value;
			}
		}

		public static void Init()
		{
			if (Mod._glSubDivideSize == null)
			{
				Mod._glSubDivideSize = new cvar("gl_subdivide_size", "128", true);
			}
			for (int i = 0; i < Mod._Known.Length; i++)
			{
				Mod._Known[i] = new model_t();
			}
			common.FillArray<byte>(Mod._Novis, byte.MaxValue);
		}

		public static void ClearAll()
		{
			for (int i = 0; i < Mod._NumKnown; i++)
			{
				model_t model_t = Mod._Known[i];
				if (model_t.type != modtype_t.mod_alias)
				{
					model_t.needload = true;
				}
			}
		}

		public static model_t ForName(string name, bool crash)
		{
			return Mod.LoadModel(Mod.FindName(name), crash);
		}

		public static aliashdr_t GetExtraData(model_t mod)
		{
			object obj = Cache.Check(mod.cache);
			if (obj != null)
			{
				return (aliashdr_t)obj;
			}
			Mod.LoadModel(mod, true);
			if (mod.cache.data == null)
			{
				sys.Error("Mod_Extradata: caching failed", Array.Empty<object>());
			}
			return (aliashdr_t)mod.cache.data;
		}

		public static void TouchModel(string name)
		{
			model_t model_t = Mod.FindName(name);
			if (!model_t.needload && model_t.type == modtype_t.mod_alias)
			{
				Cache.Check(model_t.cache);
			}
		}

		public static mleaf_t PointInLeaf(ref Vector3 p, model_t model)
		{
			if (model == null || model.nodes == null)
			{
				sys.Error("Mod_PointInLeaf: bad model", Array.Empty<object>());
			}
			mnodebase_t mnodebase_t = model.nodes[0];
			while (mnodebase_t.contents >= 0)
			{
				mnode_t mnode_t = (mnode_t)mnodebase_t;
				mplane_t plane = mnode_t.plane;
				if (Vector3.Dot(p, plane.normal) - plane.dist > 0f)
				{
					mnodebase_t = mnode_t.children[0];
				}
				else
				{
					mnodebase_t = mnode_t.children[1];
				}
			}
			return (mleaf_t)mnodebase_t;
		}

		public static byte[] LeafPVS(mleaf_t leaf, model_t model)
		{
			if (leaf == model.leafs[0])
			{
				return Mod._Novis;
			}
			return Mod.DecompressVis(leaf.compressed_vis, leaf.visofs, model);
		}

		public static void Print()
		{
			Con.Print("Cached models:\n", Array.Empty<object>());
			for (int i = 0; i < Mod._NumKnown; i++)
			{
				model_t model_t = Mod._Known[i];
				Con.Print("{0}\n", new object[]
				{
					model_t.name
				});
			}
		}

		public static model_t FindName(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				sys.Error("Mod_ForName: NULL name", Array.Empty<object>());
			}
			int num = 0;
			model_t model_t = Mod._Known[0];
			while (num < Mod._NumKnown && !(model_t.name == name))
			{
				num++;
				model_t = Mod._Known[num];
			}
			if (num == Mod._NumKnown)
			{
				if (Mod._NumKnown == 512)
				{
					sys.Error("mod_numknown == MAX_MOD_KNOWN", Array.Empty<object>());
				}
				model_t.name = name;
				model_t.needload = true;
				Mod._NumKnown++;
			}
			return model_t;
		}

		public static model_t LoadModel(model_t mod, bool crash)
		{
			if (!mod.needload)
			{
				if (mod.type != modtype_t.mod_alias)
				{
					return mod;
				}
				if (Cache.Check(mod.cache) != null)
				{
					return mod;
				}
			}
			byte[] array = common.LoadFile(mod.name);
			if (array == null)
			{
				if (crash)
				{
					sys.Error("Mod_NumForName: {0} not found", new object[]
					{
						mod.name
					});
				}
				return null;
			}
			Mod._LoadModel = mod;
			mod.needload = false;
			uint num = BitConverter.ToUInt32(array, 0);
			if (num != 1330660425u)
			{
				if (num != 1347634249u)
				{
					Mod.LoadBrushModel(mod, array);
				}
				else
				{
					Mod.LoadSpriteModel(mod, array);
				}
			}
			else
			{
				Mod.LoadAliasModel(mod, array);
			}
			return mod;
		}

		public static void LoadAliasModel(model_t mod, byte[] buffer)
		{
			mdl_t mdl_t = sys.BytesToStructure<mdl_t>(buffer, 0);
			int num = common.LittleLong(mdl_t.version);
			if (num != 6)
			{
				sys.Error("{0} has wrong version number ({1} should be {2})", new object[]
				{
					mod.name,
					num,
					6
				});
			}
			Mod._Header = new aliashdr_t();
			mod.flags = common.LittleLong(mdl_t.flags);
			Mod._Header.boundingradius = common.LittleFloat(mdl_t.boundingradius);
			Mod._Header.numskins = common.LittleLong(mdl_t.numskins);
			Mod._Header.skinwidth = common.LittleLong(mdl_t.skinwidth);
			Mod._Header.skinheight = common.LittleLong(mdl_t.skinheight);
			if (Mod._Header.skinheight > 480)
			{
				sys.Error("model {0} has a skin taller than {1}", new object[]
				{
					mod.name,
					480
				});
			}
			Mod._Header.numverts = common.LittleLong(mdl_t.numverts);
			if (Mod._Header.numverts <= 0)
			{
				sys.Error("model {0} has no vertices", new object[]
				{
					mod.name
				});
			}
			if (Mod._Header.numverts > 1024)
			{
				sys.Error("model {0} has too many vertices", new object[]
				{
					mod.name
				});
			}
			Mod._Header.numtris = common.LittleLong(mdl_t.numtris);
			if (Mod._Header.numtris <= 0)
			{
				sys.Error("model {0} has no triangles", new object[]
				{
					mod.name
				});
			}
			Mod._Header.numframes = common.LittleLong(mdl_t.numframes);
			int numframes = Mod._Header.numframes;
			if (numframes < 1)
			{
				sys.Error("Mod_LoadAliasModel: Invalid # of frames: {0}\n", new object[]
				{
					numframes
				});
			}
			Mod._Header.size = common.LittleFloat(mdl_t.size) * Mod.ALIAS_BASE_SIZE_RATIO;
			mod.synctype = (synctype_t)common.LittleLong((int)mdl_t.synctype);
			mod.numframes = Mod._Header.numframes;
			Mod._Header.scale = common.LittleVector(common.ToVector(ref mdl_t.scale));
			Mod._Header.scale_origin = common.LittleVector(common.ToVector(ref mdl_t.scale_origin));
			Mod._Header.eyeposition = common.LittleVector(common.ToVector(ref mdl_t.eyeposition));
			int num2 = Mod.LoadAllSkins(Mod._Header.numskins, new ByteArraySegment(buffer, mdl_t.SizeInBytes));
			int num3 = num2;
			int i = 0;
			while (i < Mod._Header.numverts)
			{
				Mod._STVerts[i] = sys.BytesToStructure<stvert_t>(buffer, num2);
				Mod._STVerts[i].onseam = common.LittleLong(Mod._STVerts[i].onseam);
				Mod._STVerts[i].s = common.LittleLong(Mod._STVerts[i].s);
				Mod._STVerts[i].t = common.LittleLong(Mod._STVerts[i].t);
				i++;
				num2 += stvert_t.SizeInBytes;
			}
			int num4 = num3 + Mod._Header.numverts * stvert_t.SizeInBytes;
			num2 = num4;
			int j = 0;
			while (j < Mod._Header.numtris)
			{
				Mod._Triangles[j] = sys.BytesToStructure<dtriangle_t>(buffer, num2);
				Mod._Triangles[j].facesfront = common.LittleLong(Mod._Triangles[j].facesfront);
				for (int k = 0; k < 3; k++)
				{
					Mod._Triangles[j].vertindex[k] = common.LittleLong(Mod._Triangles[j].vertindex[k]);
				}
				j++;
				num2 += dtriangle_t.SizeInBytes;
			}
			Mod._PoseNum = 0;
			int num5 = num4 + Mod._Header.numtris * dtriangle_t.SizeInBytes;
			Mod._Header.frames = new maliasframedesc_t[Mod._Header.numframes];
			for (int l = 0; l < numframes; l++)
			{
				bool flag = BitConverter.ToInt32(buffer, num5) != 0;
				num5 += 4;
				if (!flag)
				{
					num5 = Mod.LoadAliasFrame(new ByteArraySegment(buffer, num5), ref Mod._Header.frames[l]);
				}
				else
				{
					num5 = Mod.LoadAliasGroup(new ByteArraySegment(buffer, num5), ref Mod._Header.frames[l]);
				}
			}
			Mod._Header.numposes = Mod._PoseNum;
			mod.type = modtype_t.mod_alias;
			mod.mins = -Vector3.One * 16f;
			mod.maxs = -mod.mins;
			mesh.MakeAliasModelDisplayLists(mod, Mod._Header);
			mod.cache = Cache.Alloc(aliashdr_t.SizeInBytes * Mod._Header.frames.Length * maliasframedesc_t.SizeInBytes, null);
			if (mod.cache == null)
			{
				return;
			}
			mod.cache.data = Mod._Header;
		}

		public static void LoadSpriteModel(model_t mod, byte[] buffer)
		{
			dsprite_t dsprite_t = sys.BytesToStructure<dsprite_t>(buffer, 0);
			int num = common.LittleLong(dsprite_t.version);
			if (num != 1)
			{
				sys.Error("{0} has wrong version number ({1} should be {2})", new object[]
				{
					mod.name,
					num,
					1
				});
			}
			int num2 = common.LittleLong(dsprite_t.numframes);
			msprite_t msprite_t = new msprite_t();
			mod.cache = new cache_user_t();
			mod.cache.data = msprite_t;
			msprite_t.type = common.LittleLong(dsprite_t.type);
			msprite_t.maxwidth = common.LittleLong(dsprite_t.width);
			msprite_t.maxheight = common.LittleLong(dsprite_t.height);
			msprite_t.beamlength = common.LittleFloat(dsprite_t.beamlength);
			mod.synctype = (synctype_t)common.LittleLong((int)dsprite_t.synctype);
			msprite_t.numframes = num2;
			mod.mins.X = (mod.mins.Y = (float)(-(float)msprite_t.maxwidth / 2));
			mod.maxs.X = (mod.maxs.Y = (float)(msprite_t.maxwidth / 2));
			mod.mins.Z = (float)(-(float)msprite_t.maxheight / 2);
			mod.maxs.Z = (float)(msprite_t.maxheight / 2);
			if (num2 < 1)
			{
				sys.Error("Mod_LoadSpriteModel: Invalid # of frames: {0}\n", new object[]
				{
					num2
				});
			}
			mod.numframes = num2;
			int num3 = dsprite_t.SizeInBytes;
			msprite_t.frames = new mspriteframedesc_t[num2];
			for (int i = 0; i < num2; i++)
			{
				spriteframetype_t spriteframetype_t = (spriteframetype_t)BitConverter.ToInt32(buffer, num3);
				num3 += 4;
				msprite_t.frames[i].type = spriteframetype_t;
				if (spriteframetype_t == spriteframetype_t.SPR_SINGLE)
				{
					num3 = Mod.LoadSpriteFrame(new ByteArraySegment(buffer, num3), out msprite_t.frames[i].frameptr, i);
				}
				else
				{
					num3 = Mod.LoadSpriteGroup(new ByteArraySegment(buffer, num3), out msprite_t.frames[i].frameptr, i);
				}
			}
			mod.type = modtype_t.mod_sprite;
		}

		public static void LoadBrushModel(model_t mod, byte[] buffer)
		{
			mod.type = modtype_t.mod_brush;
			dheader_t dheader_t = sys.BytesToStructure<dheader_t>(buffer, 0);
			int i = common.LittleLong(dheader_t.version);
			if (i != 29)
			{
				sys.Error("Mod_LoadBrushModel: {0} has wrong version number ({1} should be {2})", new object[]
				{
					mod.name,
					i,
					29
				});
			}
			dheader_t.version = i;
			Mod._ModBase = buffer;
			for (i = 0; i < dheader_t.lumps.Length; i++)
			{
				dheader_t.lumps[i].filelen = common.LittleLong(dheader_t.lumps[i].filelen);
				dheader_t.lumps[i].fileofs = common.LittleLong(dheader_t.lumps[i].fileofs);
			}
			Mod.LoadVertexes(ref dheader_t.lumps[3]);
			Mod.LoadEdges(ref dheader_t.lumps[12]);
			Mod.LoadSurfEdges(ref dheader_t.lumps[13]);
			Mod.LoadTextures(ref dheader_t.lumps[2]);
			Mod.LoadLighting(ref dheader_t.lumps[8]);
			Mod.LoadPlanes(ref dheader_t.lumps[1]);
			Mod.LoadTexInfo(ref dheader_t.lumps[6]);
			Mod.LoadFaces(ref dheader_t.lumps[7]);
			Mod.LoadMarkSurfaces(ref dheader_t.lumps[11]);
			Mod.LoadVisibility(ref dheader_t.lumps[4]);
			Mod.LoadLeafs(ref dheader_t.lumps[10]);
			Mod.LoadNodes(ref dheader_t.lumps[5]);
			Mod.LoadClipNodes(ref dheader_t.lumps[9]);
			Mod.LoadEntities(ref dheader_t.lumps[0]);
			Mod.LoadSubModels(ref dheader_t.lumps[14]);
			Mod.MakeHull0();
			mod.numframes = 2;
			for (i = 0; i < mod.numsubmodels; i++)
			{
				Mod.SetupSubModel(mod, ref mod.submodels[i]);
				if (i < mod.numsubmodels - 1)
				{
					string name = "*" + (i + 1).ToString();
					Mod._LoadModel = Mod.FindName(name);
					Mod._LoadModel.CopyFrom(mod);
					Mod._LoadModel.name = name;
					mod = Mod._LoadModel;
				}
			}
		}

		private static byte[] DecompressVis(byte[] p, int startIndex, model_t model)
		{
			int num = model.numleafs + 7 >> 3;
			int num2 = 0;
			if (p == null)
			{
				while (num != 0)
				{
					Mod._Decompressed[num2++] = byte.MaxValue;
					num--;
				}
				return Mod._Decompressed;
			}
			int num3 = startIndex;
			do
			{
				if (p[num3] != 0)
				{
					Mod._Decompressed[num2++] = p[num3++];
				}
				else
				{
					int num4 = (int)p[num3 + 1];
					num3 += 2;
					while (num4 != 0)
					{
						Mod._Decompressed[num2++] = 0;
						num4--;
					}
				}
			}
			while (num2 < num);
			return Mod._Decompressed;
		}

		private static void SetupSubModel(model_t mod, ref dmodel_t submodel)
		{
			mod.hulls[0].firstclipnode = submodel.headnode[0];
			for (int i = 1; i < 4; i++)
			{
				mod.hulls[i].firstclipnode = submodel.headnode[i];
				mod.hulls[i].lastclipnode = mod.numclipnodes - 1;
			}
			mod.firstmodelsurface = submodel.firstface;
			mod.nummodelsurfaces = submodel.numfaces;
			common.Copy(submodel.maxs, out mod.maxs);
			common.Copy(submodel.mins, out mod.mins);
			mod.radius = Mod.RadiusFromBounds(ref mod.mins, ref mod.maxs);
			mod.numleafs = submodel.visleafs;
		}

		private static int LoadAllSkins(int numskins, ByteArraySegment data)
		{
			if (numskins < 1 || numskins > 32)
			{
				sys.Error("Mod_LoadAliasModel: Invalid # of skins: {0}\n", new object[]
				{
					numskins
				});
			}
			int num = data.StartIndex;
			int startIndex = data.StartIndex + daliasskintype_t.SizeInBytes;
			int num2 = Mod._Header.skinwidth * Mod._Header.skinheight;
			daliasskintype_t daliasskintype_t = sys.BytesToStructure<daliasskintype_t>(data.Data, num);
			for (int i = 0; i < numskins; i++)
			{
				if (daliasskintype_t.type == aliasskintype_t.ALIAS_SKIN_SINGLE)
				{
					Mod.FloodFillSkin(new ByteArraySegment(data.Data, startIndex), Mod._Header.skinwidth, Mod._Header.skinheight);
					byte[] array = new byte[num2];
					Mod._Header.texels[i] = array;
					Buffer.BlockCopy(data.Data, num + daliasskintype_t.SizeInBytes, array, 0, num2);
					num += daliasskintype_t.SizeInBytes;
					string identifier = Mod._LoadModel.name + "_" + i.ToString();
					Mod._Header.gl_texturenum[i, 0] = (Mod._Header.gl_texturenum[i, 1] = (Mod._Header.gl_texturenum[i, 2] = (Mod._Header.gl_texturenum[i, 3] = Drawer.LoadTexture(identifier, Mod._Header.skinwidth, Mod._Header.skinheight, new ByteArraySegment(data.Data, num), true, false, ""))));
					num += num2;
					daliasskintype_t = sys.BytesToStructure<daliasskintype_t>(data.Data, num);
				}
				else
				{
					num += daliasskintype_t.SizeInBytes;
					int num3 = common.LittleLong(sys.BytesToStructure<daliasskingroup_t>(data.Data, num).numskins);
					num += daliasskingroup_t.SizeInBytes;
					sys.BytesToStructure<daliasskininterval_t>(data.Data, num);
					num += daliasskininterval_t.SizeInBytes * num3;
					daliasskintype_t = sys.BytesToStructure<daliasskintype_t>(data.Data, num);
					int j;
					for (j = 0; j < num3; j++)
					{
						Mod.FloodFillSkin(new ByteArraySegment(data.Data, startIndex), Mod._Header.skinwidth, Mod._Header.skinheight);
						if (j == 0)
						{
							byte[] array2 = new byte[num2];
							Mod._Header.texels[i] = array2;
							Buffer.BlockCopy(data.Data, num, array2, 0, num2);
						}
						string identifier2 = string.Format("{0}_{1}_{2}", Mod._LoadModel.name, i, j);
						Mod._Header.gl_texturenum[i, j & 3] = Drawer.LoadTexture(identifier2, Mod._Header.skinwidth, Mod._Header.skinheight, new ByteArraySegment(data.Data, num), true, false, "");
						num += num2;
						daliasskintype_t = sys.BytesToStructure<daliasskintype_t>(data.Data, num);
					}
					int num4 = j;
					while (j < 4)
					{
						Mod._Header.gl_texturenum[i, j & 3] = Mod._Header.gl_texturenum[i, j - num4];
						j++;
					}
				}
			}
			return num;
		}

		private static int LoadAliasFrame(ByteArraySegment pin, ref maliasframedesc_t frame)
		{
			daliasframe_t daliasframe_t = sys.BytesToStructure<daliasframe_t>(pin.Data, pin.StartIndex);
			frame.name = common.GetString(daliasframe_t.name);
			frame.firstpose = Mod._PoseNum;
			frame.numposes = 1;
			frame.bboxmin.Init();
			frame.bboxmax.Init();
			for (int i = 0; i < 3; i++)
			{
				frame.bboxmin.v[i] = daliasframe_t.bboxmin.v[i];
				frame.bboxmax.v[i] = daliasframe_t.bboxmax.v[i];
			}
			trivertx_t[] array = new trivertx_t[Mod._Header.numverts];
			int num = pin.StartIndex + daliasframe_t.SizeInBytes;
			int j = 0;
			while (j < array.Length)
			{
				array[j] = sys.BytesToStructure<trivertx_t>(pin.Data, num);
				j++;
				num += trivertx_t.SizeInBytes;
			}
			Mod._PoseVerts[Mod._PoseNum] = array;
			Mod._PoseNum++;
			return num;
		}

		private static int LoadAliasGroup(ByteArraySegment pin, ref maliasframedesc_t frame)
		{
			int num = pin.StartIndex;
			daliasgroup_t daliasgroup_t = sys.BytesToStructure<daliasgroup_t>(pin.Data, num);
			int num2 = common.LittleLong(daliasgroup_t.numframes);
			frame.Init();
			frame.firstpose = Mod._PoseNum;
			frame.numposes = num2;
			for (int i = 0; i < 3; i++)
			{
				frame.bboxmin.v[i] = daliasgroup_t.bboxmin.v[i];
				frame.bboxmin.v[i] = daliasgroup_t.bboxmax.v[i];
			}
			num += daliasgroup_t.SizeInBytes;
			daliasinterval_t daliasinterval_t = sys.BytesToStructure<daliasinterval_t>(pin.Data, num);
			frame.interval = common.LittleFloat(daliasinterval_t.interval);
			num += num2 * daliasinterval_t.SizeInBytes;
			for (int j = 0; j < num2; j++)
			{
				trivertx_t[] array = new trivertx_t[Mod._Header.numverts];
				int num3 = num + daliasframe_t.SizeInBytes;
				int k = 0;
				while (k < Mod._Header.numverts)
				{
					array[k] = sys.BytesToStructure<trivertx_t>(pin.Data, num3);
					k++;
					num3 += trivertx_t.SizeInBytes;
				}
				Mod._PoseVerts[Mod._PoseNum] = array;
				Mod._PoseNum++;
				num += daliasframe_t.SizeInBytes + Mod._Header.numverts * trivertx_t.SizeInBytes;
			}
			return num;
		}

		private static int LoadSpriteFrame(ByteArraySegment pin, out object ppframe, int framenum)
		{
			dspriteframe_t dspriteframe_t = sys.BytesToStructure<dspriteframe_t>(pin.Data, pin.StartIndex);
			int num = common.LittleLong(dspriteframe_t.width);
			int num2 = common.LittleLong(dspriteframe_t.height);
			int num3 = num * num2;
			mspriteframe_t mspriteframe_t = new mspriteframe_t();
			ppframe = mspriteframe_t;
			mspriteframe_t.width = num;
			mspriteframe_t.height = num2;
			int num4 = common.LittleLong(dspriteframe_t.origin[0]);
			int num5 = common.LittleLong(dspriteframe_t.origin[1]);
			mspriteframe_t.up = (float)num5;
			mspriteframe_t.down = (float)(num5 - num2);
			mspriteframe_t.left = (float)num4;
			mspriteframe_t.right = (float)(num + num4);
			string identifier = Mod._LoadModel.name + "_" + framenum.ToString();
			mspriteframe_t.gl_texturenum = Drawer.LoadTexture(identifier, num, num2, new ByteArraySegment(pin.Data, pin.StartIndex + dspriteframe_t.SizeInBytes), true, true, "");
			return pin.StartIndex + dspriteframe_t.SizeInBytes + num3;
		}

		private static int LoadSpriteGroup(ByteArraySegment pin, out object ppframe, int framenum)
		{
			int num = common.LittleLong(sys.BytesToStructure<dspritegroup_t>(pin.Data, pin.StartIndex).numframes);
			mspritegroup_t mspritegroup_t = new mspritegroup_t();
			mspritegroup_t.numframes = num;
			mspritegroup_t.frames = new mspriteframe_t[num];
			ppframe = mspritegroup_t;
			float[] array = new float[num];
			mspritegroup_t.intervals = array;
			int num2 = pin.StartIndex + dspritegroup_t.SizeInBytes;
			int i = 0;
			while (i < num)
			{
				dspriteinterval_t dspriteinterval_t = sys.BytesToStructure<dspriteinterval_t>(pin.Data, num2);
				array[i] = common.LittleFloat(dspriteinterval_t.interval);
				if (array[i] <= 0f)
				{
					sys.Error("Mod_LoadSpriteGroup: interval<=0", Array.Empty<object>());
				}
				i++;
				num2 += dspriteinterval_t.SizeInBytes;
			}
			for (int j = 0; j < num; j++)
			{
				object obj;
				num2 = Mod.LoadSpriteFrame(new ByteArraySegment(pin.Data, num2), out obj, framenum * 100 + j);
				mspritegroup_t.frames[j] = (mspriteframe_t)obj;
			}
			return num2;
		}

		private static void LoadVertexes(ref lump_t l)
		{
			if (l.filelen % dvertex_t.SizeInBytes != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / dvertex_t.SizeInBytes;
			mvertex_t[] array = new mvertex_t[num];
			Mod._LoadModel.vertexes = array;
			Mod._LoadModel.numvertexes = num;
			int i = 0;
			int num2 = l.fileofs;
			while (i < num)
			{
				dvertex_t dvertex_t = sys.BytesToStructure<dvertex_t>(Mod._ModBase, num2);
				array[i].position = common.LittleVector3(dvertex_t.point);
				i++;
				num2 += dvertex_t.SizeInBytes;
			}
		}

		private static void LoadEdges(ref lump_t l)
		{
			if (l.filelen % dedge_t.SizeInBytes != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / dedge_t.SizeInBytes;
			medge_t[] array = new medge_t[num];
			Mod._LoadModel.edges = array;
			Mod._LoadModel.numedges = num;
			int i = 0;
			int num2 = l.fileofs;
			while (i < num)
			{
				dedge_t dedge_t = sys.BytesToStructure<dedge_t>(Mod._ModBase, num2);
				array[i].v = new ushort[]
				{
					(ushort)common.LittleShort((short)dedge_t.v[0]),
					(ushort)common.LittleShort((short)dedge_t.v[1])
				};
				i++;
				num2 += dedge_t.SizeInBytes;
			}
		}

		private static void LoadSurfEdges(ref lump_t l)
		{
			if (l.filelen % 4 != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / 4;
			int[] array = new int[num];
			Mod._LoadModel.surfedges = array;
			Mod._LoadModel.numsurfedges = num;
			int i = 0;
			int num2 = l.fileofs;
			while (i < num)
			{
				int num3 = BitConverter.ToInt32(Mod._ModBase, num2);
				array[i] = num3;
				i++;
				num2 += 4;
			}
		}

		private static void LoadTextures(ref lump_t l)
		{
			if (l.filelen == 0)
			{
				Mod._LoadModel.textures = null;
				return;
			}
			dmiptexlump_t dmiptexlump_t = sys.BytesToStructure<dmiptexlump_t>(Mod._ModBase, l.fileofs);
			dmiptexlump_t.nummiptex = common.LittleLong(dmiptexlump_t.nummiptex);
			int[] array = new int[dmiptexlump_t.nummiptex];
			Buffer.BlockCopy(Mod._ModBase, l.fileofs + dmiptexlump_t.SizeInBytes, array, 0, array.Length * 4);
			Mod._LoadModel.numtextures = dmiptexlump_t.nummiptex;
			Mod._LoadModel.textures = new texture_t[dmiptexlump_t.nummiptex];
			for (int i = 0; i < dmiptexlump_t.nummiptex; i++)
			{
				array[i] = common.LittleLong(array[i]);
				if (array[i] != -1)
				{
					int num = l.fileofs + array[i];
					miptex_t miptex_t = sys.BytesToStructure<miptex_t>(Mod._ModBase, num);
					miptex_t.width = (uint)common.LittleLong((int)miptex_t.width);
					miptex_t.height = (uint)common.LittleLong((int)miptex_t.height);
					for (int j = 0; j < 4; j++)
					{
						miptex_t.offsets[j] = (uint)common.LittleLong((int)miptex_t.offsets[j]);
					}
					if ((miptex_t.width & 15u) != 0u || (miptex_t.height & 15u) != 0u)
					{
						sys.Error("Texture {0} is not 16 aligned", new object[]
						{
							miptex_t.name
						});
					}
					int num2 = (int)(miptex_t.width * miptex_t.height / 64u * 85u);
					texture_t texture_t = new texture_t();
					Mod._LoadModel.textures[i] = texture_t;
					texture_t.name = common.GetString(miptex_t.name);
					texture_t.width = miptex_t.width;
					texture_t.height = miptex_t.height;
					for (int k = 0; k < 4; k++)
					{
						texture_t.offsets[k] = (int)(miptex_t.offsets[k] - (uint)miptex_t.SizeInBytes);
					}
					texture_t.pixels = new byte[num2];
					if (num + miptex_t.SizeInBytes + num2 <= Mod._ModBase.Length)
					{
						Buffer.BlockCopy(Mod._ModBase, num + miptex_t.SizeInBytes, texture_t.pixels, 0, num2);
					}
					else
					{
						Buffer.BlockCopy(Mod._ModBase, num, texture_t.pixels, 0, num2);
						Con.Print("Texture info of {0} truncated to fit in bounds of _ModBase\n", new object[]
						{
							Mod._LoadModel.name
						});
					}
					if (texture_t.name != null && texture_t.name.StartsWith("sky"))
					{
						render.InitSky(texture_t);
					}
					else
					{
						texture_t.gl_texturenum = Drawer.LoadTexture(texture_t.name, (int)texture_t.width, (int)texture_t.height, new ByteArraySegment(texture_t.pixels), true, false, Mod._LoadModel.name);
					}
				}
			}
			texture_t[] array2 = new texture_t[10];
			texture_t[] array3 = new texture_t[10];
			for (int m = 0; m < dmiptexlump_t.nummiptex; m++)
			{
				texture_t texture_t2 = Mod._LoadModel.textures[m];
				if (texture_t2 != null && texture_t2.name.StartsWith("+") && texture_t2.anim_next == null)
				{
					Array.Clear(array2, 0, array2.Length);
					Array.Clear(array3, 0, array3.Length);
					int num3 = (int)texture_t2.name[1];
					int num4 = 0;
					if (num3 >= 97 && num3 <= 122)
					{
						num3 -= 32;
					}
					if (num3 >= 48 && num3 <= 57)
					{
						num3 -= 48;
						num4 = 0;
						array2[num3] = texture_t2;
						num3++;
					}
					else if (num3 >= 65 && num3 <= 74)
					{
						num4 = num3 - 65;
						num3 = 0;
						array3[num4] = texture_t2;
						num4++;
					}
					else
					{
						sys.Error("Bad animating texture {0}", new object[]
						{
							texture_t2.name
						});
					}
					for (int n = m + 1; n < dmiptexlump_t.nummiptex; n++)
					{
						texture_t texture_t3 = Mod._LoadModel.textures[n];
						if (texture_t3 != null && texture_t3.name.StartsWith("+") && string.Compare(texture_t3.name, 2, texture_t2.name, 2, Math.Min(texture_t2.name.Length, texture_t3.name.Length)) == 0)
						{
							int num5 = (int)texture_t3.name[1];
							if (num5 >= 97 && num5 <= 122)
							{
								num5 -= 32;
							}
							if (num5 >= 48 && num5 <= 57)
							{
								num5 -= 48;
								array2[num5] = texture_t3;
								if (num5 + 1 > num3)
								{
									num3 = num5 + 1;
								}
							}
							else if (num5 >= 65 && num5 <= 74)
							{
								num5 -= 65;
								array3[num5] = texture_t3;
								if (num5 + 1 > num4)
								{
									num4 = num5 + 1;
								}
							}
							else
							{
								sys.Error("Bad animating texture {0}", new object[]
								{
									texture_t3.name
								});
							}
						}
					}
					for (int num6 = 0; num6 < num3; num6++)
					{
						texture_t texture_t4 = array2[num6];
						if (texture_t4 == null)
						{
							sys.Error("Missing frame {0} of {1}", new object[]
							{
								num6,
								texture_t2.name
							});
						}
						texture_t4.anim_total = num3 * 2;
						texture_t4.anim_min = num6 * 2;
						texture_t4.anim_max = (num6 + 1) * 2;
						texture_t4.anim_next = array2[(num6 + 1) % num3];
						if (num4 != 0)
						{
							texture_t4.alternate_anims = array3[0];
						}
					}
					for (int num7 = 0; num7 < num4; num7++)
					{
						texture_t texture_t5 = array3[num7];
						if (texture_t5 == null)
						{
							sys.Error("Missing frame {0} of {1}", new object[]
							{
								num7,
								texture_t5.name
							});
						}
						texture_t5.anim_total = num4 * 2;
						texture_t5.anim_min = num7 * 2;
						texture_t5.anim_max = (num7 + 1) * 2;
						texture_t5.anim_next = array3[(num7 + 1) % num4];
						if (num3 != 0)
						{
							texture_t5.alternate_anims = array2[0];
						}
					}
				}
			}
		}

		private static void LoadLighting(ref lump_t l)
		{
			if (l.filelen == 0)
			{
				Mod._LoadModel.lightdata = null;
				return;
			}
			Mod._LoadModel.lightdata = new byte[l.filelen];
			Buffer.BlockCopy(Mod._ModBase, l.fileofs, Mod._LoadModel.lightdata, 0, l.filelen);
		}

		private static void LoadPlanes(ref lump_t l)
		{
			if (l.filelen % dplane_t.SizeInBytes != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / dplane_t.SizeInBytes;
			mplane_t[] array = new mplane_t[num];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new mplane_t();
			}
			Mod._LoadModel.planes = array;
			Mod._LoadModel.numplanes = num;
			for (int j = 0; j < num; j++)
			{
				dplane_t dplane_t = sys.BytesToStructure<dplane_t>(Mod._ModBase, l.fileofs + j * dplane_t.SizeInBytes);
				int num2 = 0;
				array[j].normal = common.LittleVector3(dplane_t.normal);
				if (array[j].normal.X < 0f)
				{
					num2 |= 1;
				}
				if (array[j].normal.Y < 0f)
				{
					num2 |= 2;
				}
				if (array[j].normal.Z < 0f)
				{
					num2 |= 4;
				}
				array[j].dist = common.LittleFloat(dplane_t.dist);
				array[j].type = (byte)common.LittleLong(dplane_t.type);
				array[j].signbits = (byte)num2;
			}
		}

		private static void LoadTexInfo(ref lump_t l)
		{
			if (l.filelen % texinfo_t.SizeInBytes != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / texinfo_t.SizeInBytes;
			mtexinfo_t[] array = new mtexinfo_t[num];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new mtexinfo_t();
			}
			Mod._LoadModel.texinfo = array;
			Mod._LoadModel.numtexinfo = num;
			for (int j = 0; j < num; j++)
			{
				texinfo_t texinfo_t = sys.BytesToStructure<texinfo_t>(Mod._ModBase, l.fileofs + j * texinfo_t.SizeInBytes);
				for (int k = 0; k < 2; k++)
				{
					array[j].vecs[k] = common.LittleVector4(texinfo_t.vecs, k * 4);
				}
				float num2 = array[j].vecs[0].Length;
				float length = array[j].vecs[1].Length;
				num2 = (num2 + length) / 2f;
				if ((double)num2 < 0.32)
				{
					array[j].mipadjust = 4f;
				}
				else if ((double)num2 < 0.49)
				{
					array[j].mipadjust = 3f;
				}
				else if ((double)num2 < 0.99)
				{
					array[j].mipadjust = 2f;
				}
				else
				{
					array[j].mipadjust = 1f;
				}
				int num3 = common.LittleLong(texinfo_t.miptex);
				array[j].flags = common.LittleLong(texinfo_t.flags);
				if (Mod._LoadModel.textures == null)
				{
					array[j].texture = render.NoTextureMip;
					array[j].flags = 0;
				}
				else
				{
					if (num3 >= Mod._LoadModel.numtextures)
					{
						sys.Error("miptex >= loadmodel->numtextures", Array.Empty<object>());
					}
					array[j].texture = Mod._LoadModel.textures[num3];
					if (array[j].texture == null)
					{
						array[j].texture = render.NoTextureMip;
						array[j].flags = 0;
					}
				}
			}
		}

		private static void LoadFaces(ref lump_t l)
		{
			if (l.filelen % dface_t.SizeInBytes != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / dface_t.SizeInBytes;
			msurface_t[] array = new msurface_t[num];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new msurface_t();
			}
			Mod._LoadModel.surfaces = array;
			Mod._LoadModel.numsurfaces = num;
			int num2 = l.fileofs;
			int j = 0;
			while (j < num)
			{
				dface_t dface_t = sys.BytesToStructure<dface_t>(Mod._ModBase, num2);
				array[j].firstedge = common.LittleLong(dface_t.firstedge);
				array[j].numedges = (int)common.LittleShort(dface_t.numedges);
				array[j].flags = 0;
				int num3 = (int)common.LittleShort(dface_t.planenum);
				if (common.LittleShort(dface_t.side) != 0)
				{
					array[j].flags |= 2;
				}
				array[j].plane = Mod._LoadModel.planes[num3];
				array[j].texinfo = Mod._LoadModel.texinfo[(int)common.LittleShort(dface_t.texinfo)];
				Mod.CalcSurfaceExtents(array[j]);
				for (int k = 0; k < 4; k++)
				{
					array[j].styles[k] = dface_t.styles[k];
				}
				int num4 = common.LittleLong(dface_t.lightofs);
				if (num4 == -1)
				{
					array[j].sample_base = null;
				}
				else
				{
					array[j].sample_base = Mod._LoadModel.lightdata;
					array[j].sampleofs = num4;
				}
				if (array[j].texinfo.texture.name != null)
				{
					if (array[j].texinfo.texture.name.StartsWith("sky"))
					{
						array[j].flags |= 36;
						render.SubdivideSurface(array[j]);
					}
					else if (array[j].texinfo.texture.name.StartsWith("*"))
					{
						array[j].flags |= 48;
						for (int m = 0; m < 2; m++)
						{
							array[j].extents[m] = 16384;
							array[j].texturemins[m] = -8192;
						}
						render.SubdivideSurface(array[j]);
					}
				}
				j++;
				num2 += dface_t.SizeInBytes;
			}
		}

		private static void LoadMarkSurfaces(ref lump_t l)
		{
			if (l.filelen % 2 != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / 2;
			msurface_t[] array = new msurface_t[num];
			Mod._LoadModel.marksurfaces = array;
			Mod._LoadModel.nummarksurfaces = num;
			for (int i = 0; i < num; i++)
			{
				int num2 = (int)BitConverter.ToInt16(Mod._ModBase, l.fileofs + i * 2);
				if (num2 >= Mod._LoadModel.numsurfaces)
				{
					sys.Error("Mod_ParseMarksurfaces: bad surface number", Array.Empty<object>());
				}
				array[i] = Mod._LoadModel.surfaces[num2];
			}
		}

		private static void LoadVisibility(ref lump_t l)
		{
			if (l.filelen == 0)
			{
				Mod._LoadModel.visdata = null;
				return;
			}
			Mod._LoadModel.visdata = new byte[l.filelen];
			Buffer.BlockCopy(Mod._ModBase, l.fileofs, Mod._LoadModel.visdata, 0, l.filelen);
		}

		private static void LoadLeafs(ref lump_t l)
		{
			if (l.filelen % dleaf_t.SizeInBytes != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / dleaf_t.SizeInBytes;
			mleaf_t[] array = new mleaf_t[num];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new mleaf_t();
			}
			Mod._LoadModel.leafs = array;
			Mod._LoadModel.numleafs = num;
			int j = 0;
			int num2 = l.fileofs;
			while (j < num)
			{
				dleaf_t dleaf_t = sys.BytesToStructure<dleaf_t>(Mod._ModBase, num2);
				array[j].mins.X = (float)common.LittleShort(dleaf_t.mins[0]);
				array[j].mins.Y = (float)common.LittleShort(dleaf_t.mins[1]);
				array[j].mins.Z = (float)common.LittleShort(dleaf_t.mins[2]);
				array[j].maxs.X = (float)common.LittleShort(dleaf_t.maxs[0]);
				array[j].maxs.Y = (float)common.LittleShort(dleaf_t.maxs[1]);
				array[j].maxs.Z = (float)common.LittleShort(dleaf_t.maxs[2]);
				int num3 = common.LittleLong(dleaf_t.contents);
				array[j].contents = num3;
				array[j].marksurfaces = Mod._LoadModel.marksurfaces;
				array[j].firstmarksurface = (int)common.LittleShort((short)dleaf_t.firstmarksurface);
				array[j].nummarksurfaces = (int)common.LittleShort((short)dleaf_t.nummarksurfaces);
				num3 = common.LittleLong(dleaf_t.visofs);
				if (num3 == -1)
				{
					array[j].compressed_vis = null;
				}
				else
				{
					array[j].compressed_vis = Mod._LoadModel.visdata;
					array[j].visofs = num3;
				}
				array[j].efrags = null;
				for (int k = 0; k < 4; k++)
				{
					array[j].ambient_sound_level[k] = dleaf_t.ambient_level[k];
				}
				j++;
				num2 += dleaf_t.SizeInBytes;
			}
		}

		private static void LoadNodes(ref lump_t l)
		{
			if (l.filelen % dnode_t.SizeInBytes != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / dnode_t.SizeInBytes;
			mnode_t[] array = new mnode_t[num];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new mnode_t();
			}
			Mod._LoadModel.nodes = array;
			Mod._LoadModel.numnodes = num;
			int j = 0;
			int num2 = l.fileofs;
			while (j < num)
			{
				dnode_t dnode_t = sys.BytesToStructure<dnode_t>(Mod._ModBase, num2);
				array[j].mins.X = (float)common.LittleShort(dnode_t.mins[0]);
				array[j].mins.Y = (float)common.LittleShort(dnode_t.mins[1]);
				array[j].mins.Z = (float)common.LittleShort(dnode_t.mins[2]);
				array[j].maxs.X = (float)common.LittleShort(dnode_t.maxs[0]);
				array[j].maxs.Y = (float)common.LittleShort(dnode_t.maxs[1]);
				array[j].maxs.Z = (float)common.LittleShort(dnode_t.maxs[2]);
				int num3 = common.LittleLong(dnode_t.planenum);
				array[j].plane = Mod._LoadModel.planes[num3];
				array[j].firstsurface = (ushort)common.LittleShort((short)dnode_t.firstface);
				array[j].numsurfaces = (ushort)common.LittleShort((short)dnode_t.numfaces);
				for (int k = 0; k < 2; k++)
				{
					num3 = (int)common.LittleShort(dnode_t.children[k]);
					if (num3 >= 0)
					{
						array[j].children[k] = Mod._LoadModel.nodes[num3];
					}
					else
					{
						array[j].children[k] = Mod._LoadModel.leafs[-1 - num3];
					}
				}
				j++;
				num2 += dnode_t.SizeInBytes;
			}
			Mod.SetParent(Mod._LoadModel.nodes[0], null);
		}

		private static void LoadClipNodes(ref lump_t l)
		{
			if (l.filelen % dclipnode_t.SizeInBytes != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / dclipnode_t.SizeInBytes;
			dclipnode_t[] array = new dclipnode_t[num];
			Mod._LoadModel.clipnodes = array;
			Mod._LoadModel.numclipnodes = num;
			hull_t hull_t = Mod._LoadModel.hulls[1];
			hull_t.clipnodes = array;
			hull_t.firstclipnode = 0;
			hull_t.lastclipnode = num - 1;
			hull_t.planes = Mod._LoadModel.planes;
			hull_t.clip_mins.X = -16f;
			hull_t.clip_mins.Y = -16f;
			hull_t.clip_mins.Z = -24f;
			hull_t.clip_maxs.X = 16f;
			hull_t.clip_maxs.Y = 16f;
			hull_t.clip_maxs.Z = 32f;
			hull_t hull_t2 = Mod._LoadModel.hulls[2];
			hull_t2.clipnodes = array;
			hull_t2.firstclipnode = 0;
			hull_t2.lastclipnode = num - 1;
			hull_t2.planes = Mod._LoadModel.planes;
			hull_t2.clip_mins.X = -32f;
			hull_t2.clip_mins.Y = -32f;
			hull_t2.clip_mins.Z = -24f;
			hull_t2.clip_maxs.X = 32f;
			hull_t2.clip_maxs.Y = 32f;
			hull_t2.clip_maxs.Z = 64f;
			int i = 0;
			int num2 = l.fileofs;
			while (i < num)
			{
				dclipnode_t dclipnode_t = sys.BytesToStructure<dclipnode_t>(Mod._ModBase, num2);
				array[i].planenum = common.LittleLong(dclipnode_t.planenum);
				array[i].children = new short[2];
				array[i].children[0] = common.LittleShort(dclipnode_t.children[0]);
				array[i].children[1] = common.LittleShort(dclipnode_t.children[1]);
				i++;
				num2 += dclipnode_t.SizeInBytes;
			}
		}

		private static void LoadEntities(ref lump_t l)
		{
			if (l.filelen == 0)
			{
				Mod._LoadModel.entities = null;
				return;
			}
			Mod._LoadModel.entities = Encoding.ASCII.GetString(Mod._ModBase, l.fileofs, l.filelen);
		}

		private static void LoadSubModels(ref lump_t l)
		{
			if (l.filelen % dmodel_t.SizeInBytes != 0)
			{
				sys.Error("MOD_LoadBmodel: funny lump size in {0}", new object[]
				{
					Mod._LoadModel.name
				});
			}
			int num = l.filelen / dmodel_t.SizeInBytes;
			dmodel_t[] array = new dmodel_t[num];
			Mod._LoadModel.submodels = array;
			Mod._LoadModel.numsubmodels = num;
			int i = 0;
			int num2 = l.fileofs;
			while (i < num)
			{
				dmodel_t dmodel_t = sys.BytesToStructure<dmodel_t>(Mod._ModBase, num2);
				array[i].mins = new float[3];
				array[i].maxs = new float[3];
				array[i].origin = new float[3];
				for (int j = 0; j < 3; j++)
				{
					array[i].mins[j] = common.LittleFloat(dmodel_t.mins[j]) - 1f;
					array[i].maxs[j] = common.LittleFloat(dmodel_t.maxs[j]) + 1f;
					array[i].origin[j] = common.LittleFloat(dmodel_t.origin[j]);
				}
				array[i].headnode = new int[4];
				for (int k = 0; k < 4; k++)
				{
					array[i].headnode[k] = common.LittleLong(dmodel_t.headnode[k]);
				}
				array[i].visleafs = common.LittleLong(dmodel_t.visleafs);
				array[i].firstface = common.LittleLong(dmodel_t.firstface);
				array[i].numfaces = common.LittleLong(dmodel_t.numfaces);
				i++;
				num2 += dmodel_t.SizeInBytes;
			}
		}

		private static void MakeHull0()
		{
			hull_t hull_t = Mod._LoadModel.hulls[0];
			mnode_t[] nodes = Mod._LoadModel.nodes;
			int numnodes = Mod._LoadModel.numnodes;
			dclipnode_t[] array = new dclipnode_t[numnodes];
			hull_t.clipnodes = array;
			hull_t.firstclipnode = 0;
			hull_t.lastclipnode = numnodes - 1;
			hull_t.planes = Mod._LoadModel.planes;
			for (int i = 0; i < numnodes; i++)
			{
				array[i].planenum = Array.IndexOf<mplane_t>(Mod._LoadModel.planes, nodes[i].plane);
				array[i].children = new short[2];
				for (int j = 0; j < 2; j++)
				{
					mnodebase_t mnodebase_t = nodes[i].children[j];
					if (mnodebase_t.contents < 0)
					{
						array[i].children[j] = (short)mnodebase_t.contents;
					}
					else
					{
						array[i].children[j] = (short)Array.IndexOf<mnode_t>(Mod._LoadModel.nodes, (mnode_t)mnodebase_t);
					}
				}
			}
		}

		private static float RadiusFromBounds(ref Vector3 mins, ref Vector3 maxs)
		{
			Vector3 vector;
			vector.X = Math.Max(Math.Abs(mins.X), Math.Abs(maxs.X));
			vector.Y = Math.Max(Math.Abs(mins.Y), Math.Abs(maxs.Y));
			vector.Z = Math.Max(Math.Abs(mins.Z), Math.Abs(maxs.Z));
			return vector.Length;
		}

		private static void CalcSurfaceExtents(msurface_t s)
		{
			float[] array = new float[]
			{
				999999f,
				999999f
			};
			float[] array2 = new float[]
			{
				-99999f,
				-99999f
			};
			mtexinfo_t texinfo = s.texinfo;
			mvertex_t[] vertexes = Mod._LoadModel.vertexes;
			for (int i = 0; i < s.numedges; i++)
			{
				int num = Mod._LoadModel.surfedges[s.firstedge + i];
				int num2;
				if (num >= 0)
				{
					num2 = (int)Mod._LoadModel.edges[num].v[0];
				}
				else
				{
					num2 = (int)Mod._LoadModel.edges[-num].v[1];
				}
				for (int j = 0; j < 2; j++)
				{
					float num3 = vertexes[num2].position.X * texinfo.vecs[j].X + vertexes[num2].position.Y * texinfo.vecs[j].Y + vertexes[num2].position.Z * texinfo.vecs[j].Z + texinfo.vecs[j].W;
					if (num3 < array[j])
					{
						array[j] = num3;
					}
					if (num3 > array2[j])
					{
						array2[j] = num3;
					}
				}
			}
			int[] array3 = new int[2];
			int[] array4 = new int[2];
			for (int k = 0; k < 2; k++)
			{
				array3[k] = (int)Math.Floor((double)(array[k] / 16f));
				array4[k] = (int)Math.Ceiling((double)(array2[k] / 16f));
				s.texturemins[k] = (short)(array3[k] * 16);
				s.extents[k] = (short)((array4[k] - array3[k]) * 16);
				if ((texinfo.flags & 1) == 0 && s.extents[k] > 512)
				{
					sys.Error("Bad surface extents", Array.Empty<object>());
				}
			}
		}

		private static void SetParent(mnodebase_t node, mnode_t parent)
		{
			node.parent = parent;
			if (node.contents < 0)
			{
				return;
			}
			mnode_t mnode_t = (mnode_t)node;
			Mod.SetParent(mnode_t.children[0], mnode_t);
			Mod.SetParent(mnode_t.children[1], mnode_t);
		}

		private static void FloodFillSkin(ByteArraySegment skin, int skinwidth, int skinheight)
		{
			new FloodFiller(skin, skinwidth, skinheight).Perform();
		}

		public const int ALIAS_VERSION = 6;

		public const int IDPOLYHEADER = 1330660425;

		public const int SPRITE_VERSION = 1;

		public const int IDSPRITEHEADER = 1347634249;

		public const int VERTEXSIZE = 7;

		public const int MAX_SKINS = 32;

		public const int MAXALIASVERTS = 1024;

		public const int MAXALIASFRAMES = 256;

		public const int MAXALIASTRIS = 2048;

		public const int MAX_MOD_KNOWN = 512;

		public const int MAX_LBM_HEIGHT = 480;

		private const int ANIM_CYCLE = 2;

		private static float ALIAS_BASE_SIZE_RATIO = 0.09090909f;

		private static cvar _glSubDivideSize;

		private static byte[] _Novis = new byte[1024];

		private static model_t[] _Known = new model_t[512];

		private static int _NumKnown;

		private static model_t _LoadModel;

		private static aliashdr_t _Header;

		private static stvert_t[] _STVerts = new stvert_t[1024];

		private static dtriangle_t[] _Triangles = new dtriangle_t[2048];

		private static int _PoseNum;

		private static byte[] _ModBase;

		private static trivertx_t[][] _PoseVerts = new trivertx_t[256][];

		private static byte[] _Decompressed = new byte[1024];
	}
}
