using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using OpenTK;

namespace SharpQuake
{
	internal static class progs
	{
		public static int EdictSize
		{
			get
			{
				return progs._EdictSize;
			}
		}

		public static long GlobalStructAddr
		{
			get
			{
				return progs._GlobalStructAddr;
			}
		}

		public static int Crc
		{
			get
			{
				return (int)progs._Crc;
			}
		}

		public static void Init()
		{
			cmd.Add("edict", new xcommand_t(progs.PrintEdict_f));
			cmd.Add("edicts", new xcommand_t(progs.PrintEdicts));
			cmd.Add("edictcount", new xcommand_t(progs.EdictCount));
			cmd.Add("profile", new xcommand_t(progs.Profile_f));
			cmd.Add("test5", new xcommand_t(progs.Test5_f));
			if (progs._NoMonsters == null)
			{
				progs._NoMonsters = new cvar("nomonsters", "0");
				progs._GameCfg = new cvar("gamecfg", "0");
				progs._Scratch1 = new cvar("scratch1", "0");
				progs._Scratch2 = new cvar("scratch2", "0");
				progs._Scratch3 = new cvar("scratch3", "0");
				progs._Scratch4 = new cvar("scratch4", "0");
				progs._SavedGameCfg = new cvar("savedgamecfg", "0", true);
				progs._Saved1 = new cvar("saved1", "0", true);
				progs._Saved2 = new cvar("saved2", "0", true);
				progs._Saved3 = new cvar("saved3", "0", true);
				progs._Saved4 = new cvar("saved4", "0", true);
			}
		}

		public static void LoadProgs()
		{
			progs.FreeHandles();
			QBuiltins.ClearState();
			progs._DynamicStrings.Clear();
			for (int i = 0; i < 2; i++)
			{
				progs._gefvCache[i].field = null;
			}
			crc.Init(out progs._Crc);
			byte[] array = common.LoadFile("progs.dat");
			progs._Progs = sys.BytesToStructure<dprograms_t>(array, 0);
			if (progs._Progs == null)
			{
				sys.Error("PR_LoadProgs: couldn't load progs.dat", Array.Empty<object>());
			}
			Con.DPrint("Programs occupy {0}K.\n", new object[]
			{
				array.Length / 1024
			});
			for (int j = 0; j < array.Length; j++)
			{
				crc.ProcessByte(ref progs._Crc, array[j]);
			}
			progs._Progs.SwapBytes();
			if (progs._Progs.version != 6)
			{
				sys.Error("progs.dat has wrong version number ({0} should be {1})", new object[]
				{
					progs._Progs.version,
					6
				});
			}
			if (progs._Progs.crc != 5927)
			{
				sys.Error("progs.dat system vars have been modified, progdefs.h is out of date", Array.Empty<object>());
			}
			progs._Functions = new dfunction_t[progs._Progs.numfunctions];
			int num = progs._Progs.ofs_functions;
			int k = 0;
			while (k < progs._Functions.Length)
			{
				progs._Functions[k] = sys.BytesToStructure<dfunction_t>(array, num);
				progs._Functions[k].SwapBytes();
				k++;
				num += dfunction_t.SizeInBytes;
			}
			num = progs._Progs.ofs_strings;
			int num2 = num;
			int l = 0;
			while (l < progs._Progs.numstrings)
			{
				while (array[num] != 0)
				{
					num++;
				}
				l++;
				num++;
			}
			int count = num - num2;
			progs._Strings = Encoding.ASCII.GetString(array, num2, count);
			progs._GlobalDefs = new ddef_t[progs._Progs.numglobaldefs];
			num = progs._Progs.ofs_globaldefs;
			int m = 0;
			while (m < progs._GlobalDefs.Length)
			{
				progs._GlobalDefs[m] = sys.BytesToStructure<ddef_t>(array, num);
				progs._GlobalDefs[m].SwapBytes();
				m++;
				num += ddef_t.SizeInBytes;
			}
			progs._FieldDefs = new ddef_t[progs._Progs.numfielddefs];
			num = progs._Progs.ofs_fielddefs;
			int n = 0;
			while (n < progs._FieldDefs.Length)
			{
				progs._FieldDefs[n] = sys.BytesToStructure<ddef_t>(array, num);
				progs._FieldDefs[n].SwapBytes();
				if ((progs._FieldDefs[n].type & 32768) != 0)
				{
					sys.Error("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL", Array.Empty<object>());
				}
				n++;
				num += ddef_t.SizeInBytes;
			}
			progs._Statements = new dstatement_t[progs._Progs.numstatements];
			num = progs._Progs.ofs_statements;
			int num3 = 0;
			while (num3 < progs._Statements.Length)
			{
				progs._Statements[num3] = sys.BytesToStructure<dstatement_t>(array, num);
				progs._Statements[num3].SwapBytes();
				num3++;
				num += dstatement_t.SizeInBytes;
			}
			if (!BitConverter.IsLittleEndian)
			{
				num = progs._Progs.ofs_globals;
				int num4 = 0;
				while (num4 < progs._Progs.numglobals)
				{
					SwapHelper.Swap4b(array, num);
					num4++;
					num += 4;
				}
			}
			progs.GlobalStruct = sys.BytesToStructure<globalvars_t>(array, progs._Progs.ofs_globals);
			progs._Globals = new float[progs._Progs.numglobals - globalvars_t.SizeInBytes / 4];
			Buffer.BlockCopy(array, progs._Progs.ofs_globals + globalvars_t.SizeInBytes, progs._Globals, 0, progs._Globals.Length * 4);
			progs._EdictSize = progs._Progs.entityfields * 4 + dedict_t.SizeInBytes - entvars_t.SizeInBytes;
			progs._HGlobals = GCHandle.Alloc(progs._Globals, GCHandleType.Pinned);
			progs._GlobalsAddr = progs._HGlobals.AddrOfPinnedObject().ToInt64();
			progs._HGlobalStruct = GCHandle.Alloc(progs.GlobalStruct, GCHandleType.Pinned);
			progs._GlobalStructAddr = progs._HGlobalStruct.AddrOfPinnedObject().ToInt64();
		}

		public static void PrintEdicts()
		{
			Con.Print("{0} entities\n", new object[]
			{
				server.sv.num_edicts
			});
			for (int i = 0; i < server.sv.num_edicts; i++)
			{
				progs.PrintNum(i);
			}
		}

		public static int StringOffset(string value)
		{
			string value2 = "\0" + value + "\0";
			int num = progs._Strings.IndexOf(value2, StringComparison.Ordinal);
			if (num != -1)
			{
				return progs.MakeStingId(num + 1, true);
			}
			for (int i = 0; i < progs._DynamicStrings.Count; i++)
			{
				if (progs._DynamicStrings[i] == value)
				{
					return progs.MakeStingId(i, false);
				}
			}
			return -1;
		}

		public static void LoadFromFile(string data)
		{
			edict_t edict_t = null;
			int num = 0;
			progs.GlobalStruct.time = (float)server.sv.time;
			for (;;)
			{
				data = common.Parse(data);
				if (data == null)
				{
					break;
				}
				if (common.Token != "{")
				{
					sys.Error("ED_LoadFromFile: found {0} when expecting {", new object[]
					{
						common.Token
					});
				}
				if (edict_t == null)
				{
					edict_t = server.EdictNum(0);
				}
				else
				{
					edict_t = server.AllocEdict();
				}
				data = progs.ParseEdict(data, edict_t);
				if (host.Deathmatch != 0f)
				{
					if (((int)edict_t.v.spawnflags & 2048) != 0)
					{
						server.FreeEdict(edict_t);
						num++;
						continue;
					}
				}
				else if ((host.CurrentSkill == 0 && ((int)edict_t.v.spawnflags & 256) != 0) || (host.CurrentSkill == 1 && ((int)edict_t.v.spawnflags & 512) != 0) || (host.CurrentSkill >= 2 && ((int)edict_t.v.spawnflags & 1024) != 0))
				{
					server.FreeEdict(edict_t);
					num++;
					continue;
				}
				if (edict_t.v.classname == 0)
				{
					Con.Print("No classname for:\n", Array.Empty<object>());
					progs.Print(edict_t);
					server.FreeEdict(edict_t);
				}
				else
				{
					int num2 = progs.IndexOfFunction(progs.GetString(edict_t.v.classname));
					if (num2 == -1)
					{
						Con.Print("No spawn function for:\n", Array.Empty<object>());
						progs.Print(edict_t);
						server.FreeEdict(edict_t);
					}
					else
					{
						progs.GlobalStruct.self = server.EdictToProg(edict_t);
						progs.Execute(num2);
					}
				}
			}
			Con.DPrint("{0} entities inhibited\n", new object[]
			{
				num
			});
		}

		public static string ParseEdict(string data, edict_t ent)
		{
			bool flag = false;
			if (ent != server.sv.edicts[0])
			{
				ent.Clear();
			}
			for (;;)
			{
				data = common.Parse(data);
				if (common.Token.StartsWith("}"))
				{
					break;
				}
				if (data == null)
				{
					sys.Error("ED_ParseEntity: EOF without closing brace", Array.Empty<object>());
				}
				string text = common.Token;
				bool flag2;
				if (text == "angle")
				{
					text = "angles";
					flag2 = true;
				}
				else
				{
					flag2 = false;
				}
				if (text == "light")
				{
					text = "light_lev";
				}
				string text2 = text.TrimEnd(Array.Empty<char>());
				data = common.Parse(data);
				if (data == null)
				{
					sys.Error("ED_ParseEntity: EOF without closing brace", Array.Empty<object>());
				}
				if (common.Token.StartsWith("}"))
				{
					sys.Error("ED_ParseEntity: closing brace without data", Array.Empty<object>());
				}
				flag = true;
				if (text2[0] != '_')
				{
					ddef_t ddef_t = progs.FindField(text2);
					if (ddef_t == null)
					{
						Con.Print("'{0}' is not a field\n", new object[]
						{
							text2
						});
					}
					else
					{
						text = common.Token;
						if (flag2)
						{
							text = "0 " + text + " 0";
						}
						if (!progs.ParsePair(ent, ddef_t, text))
						{
							host.Error("ED_ParseEdict: parse error", Array.Empty<object>());
						}
					}
				}
			}
			if (!flag)
			{
				ent.free = true;
			}
			return data;
		}

		public unsafe static void Print(edict_t ed)
		{
			if (ed.free)
			{
				Con.Print("FREE\n", Array.Empty<object>());
				return;
			}
			Con.Print("\nEDICT {0}:\n", new object[]
			{
				server.NumForEdict(ed)
			});
			for (int i = 1; i < progs._Progs.numfielddefs; i++)
			{
				ddef_t ddef_t = progs._FieldDefs[i];
				string @string = progs.GetString(ddef_t.s_name);
				if (@string.Length <= 2 || @string[@string.Length - 2] != '_')
				{
					int type = (int)ddef_t.type & -32769;
					int num;
					if (ed.IsV((int)ddef_t.ofs, out num))
					{
						try
						{
							fixed (entvars_t* ptr = &ed.v)
							{
								void* ptr2 = (void*)ptr;
								int* ptr3 = (int*)((byte*)ptr2 + (IntPtr)num * 4);
								if (progs.IsEmptyField(type, ptr3))
								{
									goto IL_160;
								}
								Con.Print("{0,15} ", new object[]
								{
									@string
								});
								Con.Print("{0}\n", new object[]
								{
									progs.ValueString((etype_t)ddef_t.type, (void*)ptr3)
								});
								goto IL_160;
							}
						}
						finally
						{
							entvars_t* ptr = null;
						}
					}
					try
					{
						float[] array;
						void* ptr4;
						if ((array = ed.fields) == null || array.Length == 0)
						{
							ptr4 = null;
						}
						else
						{
							ptr4 = (void*)(&array[0]);
						}
						int* ptr5 = (int*)((byte*)ptr4 + (IntPtr)num * 4);
						if (!progs.IsEmptyField(type, ptr5))
						{
							Con.Print("{0,15} ", new object[]
							{
								@string
							});
							Con.Print("{0}\n", new object[]
							{
								progs.ValueString((etype_t)ddef_t.type, (void*)ptr5)
							});
						}
					}
					finally
					{
						float[] array = null;
					}
				}
				IL_160:;
			}
		}

		public static string GetString(int strId)
		{
			int num;
			if (progs.IsStaticString(strId, out num))
			{
				int num2 = num;
				while (num < progs._Strings.Length && progs._Strings[num] != '\0')
				{
					num++;
				}
				int num3 = num - num2;
				if (num3 > 0)
				{
					return progs._Strings.Substring(num2, num3);
				}
				return string.Empty;
			}
			else
			{
				if (num < 0 || num >= progs._DynamicStrings.Count)
				{
					throw new ArgumentException("Invalid string id!");
				}
				return progs._DynamicStrings[num];
			}
		}

		public static bool SameName(int name1, string name2)
		{
			int num = name1;
			if (num + name2.Length > progs._Strings.Length)
			{
				return false;
			}
			int i = 0;
			while (i < name2.Length)
			{
				if (progs._Strings[num] != name2[i])
				{
					return false;
				}
				i++;
				num++;
			}
			return num >= progs._Strings.Length || progs._Strings[num] == '\0';
		}

		public static int NewString(string s)
		{
			int num = progs.AllocString();
			StringBuilder stringBuilder = new StringBuilder(s.Length);
			int length = s.Length;
			for (int i = 0; i < length; i++)
			{
				if (s[i] == '\\' && i < length - 1)
				{
					i++;
					if (s[i] == 'n')
					{
						stringBuilder.Append('\n');
					}
					else
					{
						stringBuilder.Append('\\');
					}
				}
				else
				{
					stringBuilder.Append(s[i]);
				}
			}
			progs.SetString(num, stringBuilder.ToString());
			return num;
		}

		public static float GetEdictFieldFloat(edict_t ed, string field, float defValue = 0f)
		{
			ddef_t ddef_t = progs.CachedSearch(ed, field);
			if (ddef_t == null)
			{
				return defValue;
			}
			return ed.GetFloat((int)ddef_t.ofs);
		}

		public static bool SetEdictFieldFloat(edict_t ed, string field, float value)
		{
			ddef_t ddef_t = progs.CachedSearch(ed, field);
			if (ddef_t != null)
			{
				ed.SetFloat((int)ddef_t.ofs, value);
				return true;
			}
			return false;
		}

		public static int AllocString()
		{
			int count = progs._DynamicStrings.Count;
			progs._DynamicStrings.Add(string.Empty);
			return progs.MakeStingId(count, false);
		}

		public static void SetString(int id, string value)
		{
			int num;
			if (progs.IsStaticString(id, out num))
			{
				throw new ArgumentException("Static strings are read-only!");
			}
			if (num < 0 || num >= progs._DynamicStrings.Count)
			{
				throw new ArgumentException("Invalid string id!");
			}
			progs._DynamicStrings[num] = value;
		}

		public unsafe static void WriteGlobals(StreamWriter writer)
		{
			writer.WriteLine("{");
			for (int i = 0; i < progs._Progs.numglobaldefs; i++)
			{
				ddef_t ddef_t = progs._GlobalDefs[i];
				etype_t etype_t = (etype_t)ddef_t.type;
				if ((ddef_t.type & 32768) != 0)
				{
					etype_t &= (etype_t)(-32769);
					if (etype_t == etype_t.ev_string || etype_t == etype_t.ev_float || etype_t == etype_t.ev_entity)
					{
						writer.Write("\"");
						writer.Write(progs.GetString(ddef_t.s_name));
						writer.Write("\" \"");
						writer.Write(progs.UglyValueString(etype_t, (eval_t*)progs.Get((int)ddef_t.ofs)));
						writer.WriteLine("\"");
					}
				}
			}
			writer.WriteLine("}");
		}

		public unsafe static void WriteEdict(StreamWriter writer, edict_t ed)
		{
			writer.WriteLine("{");
			if (ed.free)
			{
				writer.WriteLine("}");
				return;
			}
			for (int i = 1; i < progs._Progs.numfielddefs; i++)
			{
				ddef_t ddef_t = progs._FieldDefs[i];
				string @string = progs.GetString(ddef_t.s_name);
				if (@string == null || @string.Length <= 2 || @string[@string.Length - 2] != '_')
				{
					int type = (int)ddef_t.type & -32769;
					int num;
					if (ed.IsV((int)ddef_t.ofs, out num))
					{
						try
						{
							fixed (entvars_t* ptr = &ed.v)
							{
								void* ptr2 = (void*)ptr;
								int* ptr3 = (int*)((byte*)ptr2 + (IntPtr)num * 4);
								if (progs.IsEmptyField(type, ptr3))
								{
									goto IL_113;
								}
								writer.WriteLine("\"{0}\" \"{1}\"", @string, progs.UglyValueString((etype_t)ddef_t.type, (eval_t*)ptr3));
								goto IL_113;
							}
						}
						finally
						{
							entvars_t* ptr = null;
						}
					}
					try
					{
						float[] array;
						void* ptr4;
						if ((array = ed.fields) == null || array.Length == 0)
						{
							ptr4 = null;
						}
						else
						{
							ptr4 = (void*)(&array[0]);
						}
						int* ptr5 = (int*)((byte*)ptr4 + (IntPtr)num * 4);
						if (!progs.IsEmptyField(type, ptr5))
						{
							writer.WriteLine("\"{0}\" \"{1}\"", @string, progs.UglyValueString((etype_t)ddef_t.type, (eval_t*)ptr5));
						}
					}
					finally
					{
						float[] array = null;
					}
				}
				IL_113:;
			}
			writer.WriteLine("}");
		}

		public static void ParseGlobals(string data)
		{
			for (;;)
			{
				data = common.Parse(data);
				if (common.Token.StartsWith("}"))
				{
					break;
				}
				if (string.IsNullOrEmpty(data))
				{
					sys.Error("ED_ParseEntity: EOF without closing brace", Array.Empty<object>());
				}
				string token = common.Token;
				data = common.Parse(data);
				if (string.IsNullOrEmpty(data))
				{
					sys.Error("ED_ParseEntity: EOF without closing brace", Array.Empty<object>());
				}
				if (common.Token.StartsWith("}"))
				{
					sys.Error("ED_ParseEntity: closing brace without data", Array.Empty<object>());
				}
				ddef_t ddef_t = progs.FindGlobal(token);
				if (ddef_t == null)
				{
					Con.Print("'{0}' is not a global\n", new object[]
					{
						token
					});
				}
				else if (!progs.ParseGlobalPair(ddef_t, common.Token))
				{
					host.Error("ED_ParseGlobals: parse error", Array.Empty<object>());
				}
			}
		}

		public static void PrintNum(int ent)
		{
			progs.Print(server.EdictNum(ent));
		}

		private static void Test5_f()
		{
			entity_t viewEntity = client.ViewEntity;
			if (viewEntity == null)
			{
				return;
			}
			Vector3 origin = viewEntity.origin;
			for (int i = 0; i < server.sv.edicts.Length; i++)
			{
				edict_t edict_t = server.sv.edicts[i];
				if (!edict_t.free)
				{
					Vector3 vector;
					mathlib.Copy(ref edict_t.v.absmax, out vector);
					Vector3 vector2;
					mathlib.Copy(ref edict_t.v.absmin, out vector2);
					if (origin.X >= vector2.X && origin.Y >= vector2.Y && origin.Z >= vector2.Z && origin.X <= vector.X && origin.Y <= vector.Y && origin.Z <= vector.Z)
					{
						Con.Print("{0}\n", new object[]
						{
							i
						});
					}
				}
			}
		}

		private static void FreeHandles()
		{
			if (progs._HGlobals.IsAllocated)
			{
				progs._HGlobals.Free();
				progs._GlobalsAddr = 0L;
			}
			if (progs._HGlobalStruct.IsAllocated)
			{
				progs._HGlobalStruct.Free();
				progs._GlobalStructAddr = 0L;
			}
		}

		private static void PrintEdict_f()
		{
			int num = common.atoi(cmd.Argv(1));
			if (num >= server.sv.num_edicts)
			{
				Con.Print("Bad edict number\n", Array.Empty<object>());
				return;
			}
			progs.PrintNum(num);
		}

		private static void EdictCount()
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			for (int i = 0; i < server.sv.num_edicts; i++)
			{
				edict_t edict_t = server.EdictNum(i);
				if (!edict_t.free)
				{
					num++;
					if (edict_t.v.solid != 0f)
					{
						num3++;
					}
					if (edict_t.v.model != 0)
					{
						num2++;
					}
					if (edict_t.v.movetype == 4f)
					{
						num4++;
					}
				}
			}
			Con.Print("num_edicts:{0}\n", new object[]
			{
				server.sv.num_edicts
			});
			Con.Print("active    :{0}\n", new object[]
			{
				num
			});
			Con.Print("view      :{0}\n", new object[]
			{
				num2
			});
			Con.Print("touch     :{0}\n", new object[]
			{
				num3
			});
			Con.Print("step      :{0}\n", new object[]
			{
				num4
			});
		}

		private static dfunction_t FindFunction(string name)
		{
			int num = progs.IndexOfFunction(name);
			if (num != -1)
			{
				return progs._Functions[num];
			}
			return null;
		}

		private static int IndexOfFunction(string name)
		{
			for (int i = 0; i < progs._Functions.Length; i++)
			{
				if (progs.SameName(progs._Functions[i].s_name, name))
				{
					return i;
				}
			}
			return -1;
		}

		private unsafe static bool ParsePair(edict_t ent, ddef_t key, string s)
		{
			int num;
			if (ent.IsV((int)key.ofs, out num))
			{
				fixed (entvars_t* ptr = &ent.v)
				{
					return progs.ParsePair((void*)((byte*)ptr + (IntPtr)num * 4), key, s);
				}
			}
			float[] fields;
			float* ptr2;
			if ((fields = ent.fields) == null || fields.Length == 0)
			{
				ptr2 = null;
			}
			else
			{
				ptr2 = &fields[0];
			}
			return progs.ParsePair((void*)(ptr2 + num), key, s);
		}

		private unsafe static bool ParsePair(void* value, ddef_t key, string s)
		{
			switch ((int)key.type & -32769)
			{
			case 1:
				*(int*)value = progs.NewString(s);
				break;
			case 2:
				*(float*)value = common.atof(s);
				break;
			case 3:
			{
				string[] array = s.Split(new char[]
				{
					' '
				});
				*(float*)value = common.atof(array[0]);
				*(float*)((byte*)value + 4) = ((array.Length > 1) ? common.atof(array[1]) : 0f);
				*(float*)((byte*)value + (IntPtr)2 * 4) = ((array.Length > 2) ? common.atof(array[2]) : 0f);
				break;
			}
			case 4:
				*(int*)value = server.EdictToProg(server.EdictNum(common.atoi(s)));
				break;
			case 5:
			{
				int num = progs.IndexOfField(s);
				if (num == -1)
				{
					Con.Print("Can't find field {0}\n", new object[]
					{
						s
					});
					return false;
				}
				*(int*)value = progs.GetInt32((int)progs._FieldDefs[num].ofs);
				break;
			}
			case 6:
			{
				int num2 = progs.IndexOfFunction(s);
				if (num2 == -1)
				{
					Con.Print("Can't find function {0}\n", new object[]
					{
						s
					});
					return false;
				}
				*(int*)value = num2;
				break;
			}
			}
			return true;
		}

		private static int IndexOfField(string name)
		{
			for (int i = 0; i < progs._FieldDefs.Length; i++)
			{
				if (progs.SameName(progs._FieldDefs[i].s_name, name))
				{
					return i;
				}
			}
			return -1;
		}

		private static bool IsGlobalStruct(int ofs, out int offset)
		{
			if (ofs < globalvars_t.SizeInBytes >> 2)
			{
				offset = ofs;
				return true;
			}
			offset = ofs - (globalvars_t.SizeInBytes >> 2);
			return false;
		}

		private unsafe static void* Get(int offset)
		{
			int num;
			if (progs.IsGlobalStruct(offset, out num))
			{
				return (void*)((byte*)((UIntPtr)progs._GlobalStructAddr) + (IntPtr)num * 4);
			}
			return (void*)((byte*)((UIntPtr)progs._GlobalsAddr) + (IntPtr)num * 4);
		}

		private unsafe static void Set(int offset, int value)
		{
			if (offset < globalvars_t.SizeInBytes >> 2)
			{
				*((UIntPtr)progs._GlobalStructAddr + (UIntPtr)((IntPtr)offset * 4)) = value;
				return;
			}
			*((UIntPtr)progs._GlobalsAddr + (UIntPtr)((IntPtr)offset * 4) - (UIntPtr)((IntPtr)(globalvars_t.SizeInBytes >> 2) * 4)) = value;
		}

		private unsafe static int GetInt32(int offset)
		{
			return *(int*)progs.Get(offset);
		}

		private static ddef_t FindField(string name)
		{
			int num = progs.IndexOfField(name);
			if (num != -1)
			{
				return progs._FieldDefs[num];
			}
			return null;
		}

		private unsafe static string ValueString(etype_t type, void* val)
		{
			type &= (etype_t)(-32769);
			string result;
			switch (type)
			{
			case etype_t.ev_void:
				result = "void";
				break;
			case etype_t.ev_string:
				result = progs.GetString(*(int*)val);
				break;
			case etype_t.ev_float:
				result = ((float*)val)->ToString("F1", CultureInfo.InvariantCulture.NumberFormat);
				break;
			case etype_t.ev_vector:
				result = string.Format(CultureInfo.InvariantCulture.NumberFormat, "{0,5:F1} {1,5:F1} {2,5:F1}", *(float*)val, *(float*)((byte*)val + 4), *(float*)((byte*)val + (IntPtr)2 * 4));
				break;
			case etype_t.ev_entity:
				result = "entity " + server.NumForEdict(server.ProgToEdict(*(int*)val));
				break;
			case etype_t.ev_field:
			{
				ddef_t ddef_t = progs.FindField(*(int*)val);
				result = "." + progs.GetString(ddef_t.s_name);
				break;
			}
			case etype_t.ev_function:
				result = progs.GetString(progs._Functions[*(int*)val].s_name) + "()";
				break;
			case etype_t.ev_pointer:
				result = "pointer";
				break;
			default:
				result = "bad type " + type.ToString();
				break;
			}
			return result;
		}

		private static int IndexOfField(int ofs)
		{
			for (int i = 0; i < progs._FieldDefs.Length; i++)
			{
				if ((int)progs._FieldDefs[i].ofs == ofs)
				{
					return i;
				}
			}
			return -1;
		}

		private static ddef_t FindField(int ofs)
		{
			int num = progs.IndexOfField(ofs);
			if (num != -1)
			{
				return progs._FieldDefs[num];
			}
			return null;
		}

		private static ddef_t CachedSearch(edict_t ed, string field)
		{
			for (int i = 0; i < 2; i++)
			{
				if (field == progs._gefvCache[i].field)
				{
					return progs._gefvCache[i].pcache;
				}
			}
			ddef_t ddef_t = progs.FindField(field);
			progs._gefvCache[progs._gefvPos].pcache = ddef_t;
			progs._gefvCache[progs._gefvPos].field = field;
			progs._gefvPos ^= 1;
			return ddef_t;
		}

		private static int MakeStingId(int index, bool isStatic)
		{
			return ((isStatic ? 0 : 1) << 24) + (index & 16777215);
		}

		private static bool IsStaticString(int stringId, out int offset)
		{
			offset = (stringId & 16777215);
			return (stringId >> 24 & 1) == 0;
		}

		private unsafe static string UglyValueString(etype_t type, eval_t* val)
		{
			type &= (etype_t)(-32769);
			string result;
			switch (type)
			{
			case etype_t.ev_void:
				result = "void";
				break;
			case etype_t.ev_string:
				result = progs.GetString(val->_string);
				break;
			case etype_t.ev_float:
				result = val->_float.ToString("F6", CultureInfo.InvariantCulture.NumberFormat);
				break;
			case etype_t.ev_vector:
				result = string.Format(CultureInfo.InvariantCulture.NumberFormat, "{0:F6} {1:F6} {2:F6}", val->vector.FixedElementField, *(ref val->vector.FixedElementField + 4), *(ref val->vector.FixedElementField + (IntPtr)2 * 4));
				break;
			case etype_t.ev_entity:
				result = server.NumForEdict(server.ProgToEdict(val->edict)).ToString();
				break;
			case etype_t.ev_field:
				result = progs.GetString(progs.FindField(val->_int).s_name);
				break;
			case etype_t.ev_function:
				result = progs.GetString(progs._Functions[val->function].s_name);
				break;
			default:
				result = "bad type " + type.ToString();
				break;
			}
			return result;
		}

		private unsafe static bool IsEmptyField(int type, int* v)
		{
			for (int i = 0; i < progs._TypeSize[type]; i++)
			{
				if (v[i] != 0)
				{
					return false;
				}
			}
			return true;
		}

		private static ddef_t FindGlobal(string name)
		{
			for (int i = 0; i < progs._GlobalDefs.Length; i++)
			{
				ddef_t ddef_t = progs._GlobalDefs[i];
				if (name == progs.GetString(ddef_t.s_name))
				{
					return ddef_t;
				}
			}
			return null;
		}

		private unsafe static bool ParseGlobalPair(ddef_t key, string value)
		{
			int num;
			if (progs.IsGlobalStruct((int)key.ofs, out num))
			{
				return progs.ParsePair((void*)((byte*)((UIntPtr)progs._GlobalStructAddr) + (IntPtr)num * 4), key, value);
			}
			return progs.ParsePair((void*)((byte*)((UIntPtr)progs._GlobalsAddr) + (IntPtr)num * 4), key, value);
		}

		private unsafe static string GlobalString(int ofs)
		{
			string text = string.Empty;
			void* val = progs.Get(ofs);
			ddef_t ddef_t = progs.GlobalAtOfs(ofs);
			if (ddef_t == null)
			{
				text = string.Format("{0}(???)", ofs);
			}
			else
			{
				string arg = progs.ValueString((etype_t)ddef_t.type, val);
				text = string.Format("{0}({1}){2} ", ofs, progs.GetString(ddef_t.s_name), arg);
			}
			return text.PadRight(20);
		}

		private static string GlobalStringNoContents(int ofs)
		{
			string text = string.Empty;
			ddef_t ddef_t = progs.GlobalAtOfs(ofs);
			if (ddef_t == null)
			{
				text = string.Format("{0}(???)", ofs);
			}
			else
			{
				text = string.Format("{0}({1}) ", ofs, progs.GetString(ddef_t.s_name));
			}
			return text.PadRight(20);
		}

		private static ddef_t GlobalAtOfs(int ofs)
		{
			for (int i = 0; i < progs._GlobalDefs.Length; i++)
			{
				ddef_t ddef_t = progs._GlobalDefs[i];
				if ((int)ddef_t.ofs == ofs)
				{
					return ddef_t;
				}
			}
			return null;
		}

		public static int Argc
		{
			get
			{
				return progs._Argc;
			}
		}

		public unsafe static void Execute(int fnum)
		{
			if (fnum < 1 || fnum >= progs._Functions.Length)
			{
				if (progs.GlobalStruct.self != 0)
				{
					progs.Print(server.ProgToEdict(progs.GlobalStruct.self));
				}
				host.Error("PR_ExecuteProgram: NULL function", Array.Empty<object>());
			}
			dfunction_t f = progs._Functions[fnum];
			int num = 100000;
			progs.Trace = false;
			int depth = progs._Depth;
			int num2 = progs.EnterFunction(f);
			for (;;)
			{
				num2++;
				eval_t* ptr = (eval_t*)progs.Get((int)progs._Statements[num2].a);
				eval_t* ptr2 = (eval_t*)progs.Get((int)progs._Statements[num2].b);
				eval_t* ptr3 = (eval_t*)progs.Get((int)progs._Statements[num2].c);
				if (--num == 0)
				{
					progs.RunError("runaway loop error", Array.Empty<object>());
				}
				progs.xFunction.profile++;
				progs._xStatement = num2;
				if (progs.Trace)
				{
					progs.PrintStatement(ref progs._Statements[num2]);
				}
				switch (progs._Statements[num2].op)
				{
				case 0:
				case 43:
				{
					float* ptr4 = progs._GlobalStructAddr;
					int a = (int)progs._Statements[num2].a;
					ptr4[1] = *(float*)progs.Get(a);
					ptr4[2] = *(float*)progs.Get(a + 1);
					ptr4[3] = *(float*)progs.Get(a + 2);
					num2 = progs.LeaveFunction();
					if (progs._Depth == depth)
					{
						return;
					}
					break;
				}
				case 1:
					ptr3->_float = ptr->_float * ptr2->_float;
					break;
				case 2:
					ptr3->_float = ptr->vector.FixedElementField * ptr2->vector.FixedElementField + *(ref ptr->vector.FixedElementField + 4) * *(ref ptr2->vector.FixedElementField + 4) + *(ref ptr->vector.FixedElementField + (IntPtr)2 * 4) * *(ref ptr2->vector.FixedElementField + (IntPtr)2 * 4);
					break;
				case 3:
					ptr3->vector.FixedElementField = ptr->_float * ptr2->vector.FixedElementField;
					*(ref ptr3->vector.FixedElementField + 4) = ptr->_float * *(ref ptr2->vector.FixedElementField + 4);
					*(ref ptr3->vector.FixedElementField + (IntPtr)2 * 4) = ptr->_float * *(ref ptr2->vector.FixedElementField + (IntPtr)2 * 4);
					break;
				case 4:
					ptr3->vector.FixedElementField = ptr2->_float * ptr->vector.FixedElementField;
					*(ref ptr3->vector.FixedElementField + 4) = ptr2->_float * *(ref ptr->vector.FixedElementField + 4);
					*(ref ptr3->vector.FixedElementField + (IntPtr)2 * 4) = ptr2->_float * *(ref ptr->vector.FixedElementField + (IntPtr)2 * 4);
					break;
				case 5:
					ptr3->_float = ptr->_float / ptr2->_float;
					break;
				case 6:
					ptr3->_float = ptr->_float + ptr2->_float;
					break;
				case 7:
					ptr3->vector.FixedElementField = ptr->vector.FixedElementField + ptr2->vector.FixedElementField;
					*(ref ptr3->vector.FixedElementField + 4) = *(ref ptr->vector.FixedElementField + 4) + *(ref ptr2->vector.FixedElementField + 4);
					*(ref ptr3->vector.FixedElementField + (IntPtr)2 * 4) = *(ref ptr->vector.FixedElementField + (IntPtr)2 * 4) + *(ref ptr2->vector.FixedElementField + (IntPtr)2 * 4);
					break;
				case 8:
					ptr3->_float = ptr->_float - ptr2->_float;
					break;
				case 9:
					ptr3->vector.FixedElementField = ptr->vector.FixedElementField - ptr2->vector.FixedElementField;
					*(ref ptr3->vector.FixedElementField + 4) = *(ref ptr->vector.FixedElementField + 4) - *(ref ptr2->vector.FixedElementField + 4);
					*(ref ptr3->vector.FixedElementField + (IntPtr)2 * 4) = *(ref ptr->vector.FixedElementField + (IntPtr)2 * 4) - *(ref ptr2->vector.FixedElementField + (IntPtr)2 * 4);
					break;
				case 10:
					ptr3->_float = (float)((ptr->_float == ptr2->_float) ? 1 : 0);
					break;
				case 11:
					ptr3->_float = (float)((ptr->vector.FixedElementField == ptr2->vector.FixedElementField && *(ref ptr->vector.FixedElementField + 4) == *(ref ptr2->vector.FixedElementField + 4) && *(ref ptr->vector.FixedElementField + (IntPtr)2 * 4) == *(ref ptr2->vector.FixedElementField + (IntPtr)2 * 4)) ? 1 : 0);
					break;
				case 12:
					ptr3->_float = (float)((progs.GetString(ptr->_string) == progs.GetString(ptr2->_string)) ? 1 : 0);
					break;
				case 13:
					ptr3->_float = (float)((ptr->_int == ptr2->_int) ? 1 : 0);
					break;
				case 14:
					ptr3->_float = (float)((ptr->function == ptr2->function) ? 1 : 0);
					break;
				case 15:
					ptr3->_float = (float)((ptr->_float != ptr2->_float) ? 1 : 0);
					break;
				case 16:
					ptr3->_float = (float)((ptr->vector.FixedElementField != ptr2->vector.FixedElementField || *(ref ptr->vector.FixedElementField + 4) != *(ref ptr2->vector.FixedElementField + 4) || *(ref ptr->vector.FixedElementField + (IntPtr)2 * 4) != *(ref ptr2->vector.FixedElementField + (IntPtr)2 * 4)) ? 1 : 0);
					break;
				case 17:
					ptr3->_float = (float)((progs.GetString(ptr->_string) != progs.GetString(ptr2->_string)) ? 1 : 0);
					break;
				case 18:
					ptr3->_float = (float)((ptr->_int != ptr2->_int) ? 1 : 0);
					break;
				case 19:
					ptr3->_float = (float)((ptr->function != ptr2->function) ? 1 : 0);
					break;
				case 20:
					ptr3->_float = (float)((ptr->_float <= ptr2->_float) ? 1 : 0);
					break;
				case 21:
					ptr3->_float = (float)((ptr->_float >= ptr2->_float) ? 1 : 0);
					break;
				case 22:
					ptr3->_float = (float)((ptr->_float < ptr2->_float) ? 1 : 0);
					break;
				case 23:
					ptr3->_float = (float)((ptr->_float > ptr2->_float) ? 1 : 0);
					break;
				case 24:
				case 26:
				case 27:
				case 28:
				case 29:
				{
					edict_t edict_t = server.ProgToEdict(ptr->edict);
					edict_t.LoadInt(ptr2->_int, ptr3);
					break;
				}
				case 25:
				{
					edict_t edict_t = server.ProgToEdict(ptr->edict);
					edict_t.LoadVector(ptr2->_int, ptr3);
					break;
				}
				case 30:
				{
					edict_t edict_t = server.ProgToEdict(ptr->edict);
					if (edict_t == server.sv.edicts[0] && server.IsActive)
					{
						progs.RunError("assignment to world entity", Array.Empty<object>());
					}
					ptr3->_int = progs.MakeAddr(ptr->edict, ptr2->_int);
					break;
				}
				case 31:
				case 33:
				case 34:
				case 35:
				case 36:
					ptr2->_int = ptr->_int;
					break;
				case 32:
					ptr2->vector.FixedElementField = ptr->vector.FixedElementField;
					*(ref ptr2->vector.FixedElementField + 4) = *(ref ptr->vector.FixedElementField + 4);
					*(ref ptr2->vector.FixedElementField + (IntPtr)2 * 4) = *(ref ptr->vector.FixedElementField + (IntPtr)2 * 4);
					break;
				case 37:
				case 39:
				case 40:
				case 41:
				case 42:
				{
					int offset;
					edict_t edict_t = progs.EdictFromAddr(ptr2->_int, out offset);
					edict_t.StoreInt(offset, ptr);
					break;
				}
				case 38:
				{
					int offset;
					edict_t edict_t = progs.EdictFromAddr(ptr2->_int, out offset);
					edict_t.StoreVector(offset, ptr);
					break;
				}
				case 44:
					ptr3->_float = (float)((ptr->_float != 0f) ? 0 : 1);
					break;
				case 45:
					ptr3->_float = (float)((ptr->vector.FixedElementField == 0f && *(ref ptr->vector.FixedElementField + 4) == 0f && *(ref ptr->vector.FixedElementField + (IntPtr)2 * 4) == 0f) ? 1 : 0);
					break;
				case 46:
					ptr3->_float = (float)((ptr->_string == 0 || string.IsNullOrEmpty(progs.GetString(ptr->_string))) ? 1 : 0);
					break;
				case 47:
					ptr3->_float = (float)((server.ProgToEdict(ptr->edict) == server.sv.edicts[0]) ? 1 : 0);
					break;
				case 48:
					ptr3->_float = (float)((ptr->function == 0) ? 1 : 0);
					break;
				case 49:
					if (ptr->_int != 0)
					{
						num2 += (int)(progs._Statements[num2].b - 1);
					}
					break;
				case 50:
					if (ptr->_int == 0)
					{
						num2 += (int)(progs._Statements[num2].b - 1);
					}
					break;
				case 51:
				case 52:
				case 53:
				case 54:
				case 55:
				case 56:
				case 57:
				case 58:
				case 59:
				{
					progs._Argc = (int)(progs._Statements[num2].op - 51);
					if (ptr->function == 0)
					{
						progs.RunError("NULL function", Array.Empty<object>());
					}
					dfunction_t dfunction_t = progs._Functions[ptr->function];
					if (dfunction_t.first_statement < 0)
					{
						int num3 = -dfunction_t.first_statement;
						if (num3 >= QBuiltins.Count)
						{
							progs.RunError("Bad builtin call number", Array.Empty<object>());
						}
						QBuiltins.Execute(num3);
					}
					else
					{
						num2 = progs.EnterFunction(dfunction_t);
					}
					break;
				}
				case 60:
				{
					edict_t edict_t = server.ProgToEdict(progs.GlobalStruct.self);
					edict_t.v.nextthink = progs.GlobalStruct.time + 0.1f;
					if (ptr->_float != edict_t.v.frame)
					{
						edict_t.v.frame = ptr->_float;
					}
					edict_t.v.think = ptr2->function;
					break;
				}
				case 61:
					num2 += (int)(progs._Statements[num2].a - 1);
					break;
				case 62:
					ptr3->_float = (float)((ptr->_float != 0f && ptr2->_float != 0f) ? 1 : 0);
					break;
				case 63:
					ptr3->_float = (float)((ptr->_float != 0f || ptr2->_float != 0f) ? 1 : 0);
					break;
				case 64:
					ptr3->_float = (float)((int)ptr->_float & (int)ptr2->_float);
					break;
				case 65:
					ptr3->_float = (float)((int)ptr->_float | (int)ptr2->_float);
					break;
				default:
					progs.RunError("Bad opcode %i", new object[]
					{
						progs._Statements[num2].op
					});
					break;
				}
			}
		}

		public static void RunError(string fmt, params object[] args)
		{
			progs.PrintStatement(ref progs._Statements[progs._xStatement]);
			progs.StackTrace();
			Con.Print(fmt, args);
			progs._Depth = 0;
			host.Error("Program error", Array.Empty<object>());
		}

		public static edict_t EdictFromAddr(int addr, out int ofs)
		{
			int e = addr >> 16 & 65535;
			ofs = (addr & 65535);
			return server.ProgToEdict(e);
		}

		private static void Profile_f()
		{
			if (progs._Functions == null)
			{
				return;
			}
			int num = 0;
			dfunction_t dfunction_t;
			do
			{
				int num2 = 0;
				dfunction_t = null;
				for (int i = 0; i < progs._Functions.Length; i++)
				{
					dfunction_t dfunction_t2 = progs._Functions[i];
					if (dfunction_t2.profile > num2)
					{
						num2 = dfunction_t2.profile;
						dfunction_t = dfunction_t2;
					}
				}
				if (dfunction_t != null)
				{
					if (num < 10)
					{
						Con.Print("{0,7} {1}\n", new object[]
						{
							dfunction_t.profile,
							progs.GetString(dfunction_t.s_name)
						});
					}
					num++;
					dfunction_t.profile = 0;
				}
			}
			while (dfunction_t != null);
		}

		private unsafe static int EnterFunction(dfunction_t f)
		{
			progs._Stack[progs._Depth].s = progs._xStatement;
			progs._Stack[progs._Depth].f = progs.xFunction;
			progs._Depth++;
			if (progs._Depth >= 32)
			{
				progs.RunError("stack overflow", Array.Empty<object>());
			}
			int locals = f.locals;
			if (progs._LocalStackUsed + locals > 2048)
			{
				progs.RunError("PR_ExecuteProgram: locals stack overflow\n", Array.Empty<object>());
			}
			for (int i = 0; i < locals; i++)
			{
				progs._LocalStack[progs._LocalStackUsed + i] = *(int*)progs.Get(f.parm_start + i);
			}
			progs._LocalStackUsed += locals;
			int num = f.parm_start;
			for (int j = 0; j < f.numparms; j++)
			{
				for (int k = 0; k < (int)f.parm_size[j]; k++)
				{
					progs.Set(num, *(int*)progs.Get(4 + j * 3 + k));
					num++;
				}
			}
			progs.xFunction = f;
			return f.first_statement - 1;
		}

		private static void StackTrace()
		{
			if (progs._Depth == 0)
			{
				Con.Print("<NO STACK>\n", Array.Empty<object>());
				return;
			}
			progs._Stack[progs._Depth].f = progs.xFunction;
			for (int i = progs._Depth; i >= 0; i--)
			{
				dfunction_t f = progs._Stack[i].f;
				if (f == null)
				{
					Con.Print("<NO FUNCTION>\n", Array.Empty<object>());
				}
				else
				{
					Con.Print("{0,12} : {1}\n", new object[]
					{
						progs.GetString(f.s_file),
						progs.GetString(f.s_name)
					});
				}
			}
		}

		private static void PrintStatement(ref dstatement_t s)
		{
			if ((int)s.op < progs.OpNames.Length)
			{
				Con.Print("{0,10} ", new object[]
				{
					progs.OpNames[(int)s.op]
				});
			}
			OP op = (OP)s.op;
			if (op == OP.OP_IF || op == OP.OP_IFNOT)
			{
				Con.Print("{0}branch {1}", new object[]
				{
					progs.GlobalString((int)s.a),
					s.b
				});
			}
			else if (op == OP.OP_GOTO)
			{
				Con.Print("branch {0}", new object[]
				{
					s.a
				});
			}
			else if (s.op - 31 < 6)
			{
				Con.Print(progs.GlobalString((int)s.a), Array.Empty<object>());
				Con.Print(progs.GlobalStringNoContents((int)s.b), Array.Empty<object>());
			}
			else
			{
				if (s.a != 0)
				{
					Con.Print(progs.GlobalString((int)s.a), Array.Empty<object>());
				}
				if (s.b != 0)
				{
					Con.Print(progs.GlobalString((int)s.b), Array.Empty<object>());
				}
				if (s.c != 0)
				{
					Con.Print(progs.GlobalStringNoContents((int)s.c), Array.Empty<object>());
				}
			}
			Con.Print("\n", Array.Empty<object>());
		}

		private static int LeaveFunction()
		{
			if (progs._Depth <= 0)
			{
				sys.Error("prog stack underflow", Array.Empty<object>());
			}
			int locals = progs.xFunction.locals;
			progs._LocalStackUsed -= locals;
			if (progs._LocalStackUsed < 0)
			{
				progs.RunError("PR_ExecuteProgram: locals stack underflow\n", Array.Empty<object>());
			}
			for (int i = 0; i < locals; i++)
			{
				progs.Set(progs.xFunction.parm_start + i, progs._LocalStack[progs._LocalStackUsed + i]);
			}
			progs._Depth--;
			progs.xFunction = progs._Stack[progs._Depth].f;
			return progs._Stack[progs._Depth].s;
		}

		private static int MakeAddr(int prog, int offset)
		{
			return ((prog & 65535) << 16) + (offset & 65535);
		}

		public const int DEF_SAVEGLOBAL = 32768;

		public const int MAX_PARMS = 8;

		public const int MAX_ENT_LEAFS = 16;

		private const int PROG_VERSION = 6;

		private const int PROGHEADER_CRC = 5927;

		public static globalvars_t GlobalStruct;

		private const int MAX_FIELD_LEN = 64;

		private const int GEFV_CACHESIZE = 2;

		private static progs.gefv_cache[] _gefvCache = new progs.gefv_cache[2];

		private static int _gefvPos;

		private static int[] _TypeSize = new int[]
		{
			1,
			1,
			1,
			3,
			1,
			1,
			1,
			0
		};

		private static cvar _NoMonsters;

		private static cvar _GameCfg;

		private static cvar _Scratch1;

		private static cvar _Scratch2;

		private static cvar _Scratch3;

		private static cvar _Scratch4;

		private static cvar _SavedGameCfg;

		private static cvar _Saved1;

		private static cvar _Saved2;

		private static cvar _Saved3;

		private static cvar _Saved4;

		private static dprograms_t _Progs;

		private static dfunction_t[] _Functions;

		private static string _Strings;

		private static ddef_t[] _FieldDefs;

		private static ddef_t[] _GlobalDefs;

		private static dstatement_t[] _Statements;

		private static float[] _Globals;

		private static int _EdictSize;

		private static ushort _Crc;

		private static GCHandle _HGlobalStruct;

		private static GCHandle _HGlobals;

		private static long _GlobalStructAddr;

		private static long _GlobalsAddr;

		private static List<string> _DynamicStrings = new List<string>(512);

		public static bool Trace;

		public static dfunction_t xFunction;

		private const int MAX_STACK_DEPTH = 32;

		private const int LOCALSTACK_SIZE = 2048;

		private static readonly string[] OpNames = new string[]
		{
			"DONE",
			"MUL_F",
			"MUL_V",
			"MUL_FV",
			"MUL_VF",
			"DIV",
			"ADD_F",
			"ADD_V",
			"SUB_F",
			"SUB_V",
			"EQ_F",
			"EQ_V",
			"EQ_S",
			"EQ_E",
			"EQ_FNC",
			"NE_F",
			"NE_V",
			"NE_S",
			"NE_E",
			"NE_FNC",
			"LE",
			"GE",
			"LT",
			"GT",
			"INDIRECT",
			"INDIRECT",
			"INDIRECT",
			"INDIRECT",
			"INDIRECT",
			"INDIRECT",
			"ADDRESS",
			"STORE_F",
			"STORE_V",
			"STORE_S",
			"STORE_ENT",
			"STORE_FLD",
			"STORE_FNC",
			"STOREP_F",
			"STOREP_V",
			"STOREP_S",
			"STOREP_ENT",
			"STOREP_FLD",
			"STOREP_FNC",
			"RETURN",
			"NOT_F",
			"NOT_V",
			"NOT_S",
			"NOT_ENT",
			"NOT_FNC",
			"IF",
			"IFNOT",
			"CALL0",
			"CALL1",
			"CALL2",
			"CALL3",
			"CALL4",
			"CALL5",
			"CALL6",
			"CALL7",
			"CALL8",
			"STATE",
			"GOTO",
			"AND",
			"OR",
			"BITAND",
			"BITOR"
		};

		private static progs.prstack_t[] _Stack = new progs.prstack_t[32];

		private static int _Depth;

		private static int[] _LocalStack = new int[2048];

		private static int _LocalStackUsed;

		private static int _xStatement;

		private static int _Argc;

		private struct gefv_cache
		{
			public ddef_t pcache;

			public string field;
		}

		private struct prstack_t
		{
			public int s;

			public dfunction_t f;
		}
	}
}
