/// <summary> /// PR_LoadProgs /// </summary> public static void LoadProgs() { FreeHandles(); QBuiltins.ClearState(); _DynamicStrings.Clear(); // flush the non-C variable lookup cache for (int i = 0; i < GEFV_CACHESIZE; i++) { _gefvCache[i].field = null; } CRC.Init(out _Crc); byte[] buf = Common.LoadFile("progs.dat"); _Progs = Sys.BytesToStructure <dprograms_t>(buf, 0); if (_Progs == null) { Sys.Error("PR_LoadProgs: couldn't load progs.dat"); } Con.DPrint("Programs occupy {0}K.\n", buf.Length / 1024); for (int i = 0; i < buf.Length; i++) { CRC.ProcessByte(ref _Crc, buf[i]); } // byte swap the header _Progs.SwapBytes(); if (_Progs.version != PROG_VERSION) { Sys.Error("progs.dat has wrong version number ({0} should be {1})", _Progs.version, PROG_VERSION); } if (_Progs.crc != PROGHEADER_CRC) { Sys.Error("progs.dat system vars have been modified, progdefs.h is out of date"); } // Functions _Functions = new dfunction_t[_Progs.numfunctions]; int offset = _Progs.ofs_functions; for (int i = 0; i < _Functions.Length; i++, offset += dfunction_t.SizeInBytes) { _Functions[i] = Sys.BytesToStructure <dfunction_t>(buf, offset); _Functions[i].SwapBytes(); } // strings offset = _Progs.ofs_strings; int str0 = offset; for (int i = 0; i < _Progs.numstrings; i++, offset++) { // count string length while (buf[offset] != 0) { offset++; } } int length = offset - str0; _Strings = Encoding.ASCII.GetString(buf, str0, length); // Globaldefs _GlobalDefs = new ddef_t[_Progs.numglobaldefs]; offset = _Progs.ofs_globaldefs; for (int i = 0; i < _GlobalDefs.Length; i++, offset += ddef_t.SizeInBytes) { _GlobalDefs[i] = Sys.BytesToStructure <ddef_t>(buf, offset); _GlobalDefs[i].SwapBytes(); } // Fielddefs _FieldDefs = new ddef_t[_Progs.numfielddefs]; offset = _Progs.ofs_fielddefs; for (int i = 0; i < _FieldDefs.Length; i++, offset += ddef_t.SizeInBytes) { _FieldDefs[i] = Sys.BytesToStructure <ddef_t>(buf, offset); _FieldDefs[i].SwapBytes(); if ((_FieldDefs[i].type & DEF_SAVEGLOBAL) != 0) { Sys.Error("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); } } // Statements _Statements = new dstatement_t[_Progs.numstatements]; offset = _Progs.ofs_statements; for (int i = 0; i < _Statements.Length; i++, offset += dstatement_t.SizeInBytes) { _Statements[i] = Sys.BytesToStructure <dstatement_t>(buf, offset); _Statements[i].SwapBytes(); } // Swap bytes inplace if needed if (!BitConverter.IsLittleEndian) { offset = _Progs.ofs_globals; for (int i = 0; i < _Progs.numglobals; i++, offset += 4) { SwapHelper.Swap4b(buf, offset); } } GlobalStruct = Sys.BytesToStructure <globalvars_t>(buf, _Progs.ofs_globals); _Globals = new float[_Progs.numglobals - globalvars_t.SizeInBytes / 4]; Buffer.BlockCopy(buf, _Progs.ofs_globals + globalvars_t.SizeInBytes, _Globals, 0, _Globals.Length * 4); _EdictSize = _Progs.entityfields * 4 + dedict_t.SizeInBytes - entvars_t.SizeInBytes; _HGlobals = GCHandle.Alloc(_Globals, GCHandleType.Pinned); _GlobalsAddr = _HGlobals.AddrOfPinnedObject().ToInt64(); _HGlobalStruct = GCHandle.Alloc(Progs.GlobalStruct, GCHandleType.Pinned); _GlobalStructAddr = _HGlobalStruct.AddrOfPinnedObject().ToInt64(); }
/// <summary> /// PR_LoadProgs /// </summary> public static void LoadProgs() { FreeHandles(); QBuiltins.ClearState(); _DynamicStrings.Clear(); // flush the non-C variable lookup cache for (int i = 0; i < GEFV_CACHESIZE; i++) _gefvCache[i].field = null; CRC.Init(out _Crc); byte[] buf = Common.LoadFile("progs.dat"); _Progs = Sys.BytesToStructure<dprograms_t>(buf, 0); if (_Progs == null) Sys.Error("PR_LoadProgs: couldn't load progs.dat"); Con.DPrint("Programs occupy {0}K.\n", buf.Length / 1024); for (int i = 0; i < buf.Length; i++) CRC.ProcessByte(ref _Crc, buf[i]); // byte swap the header _Progs.SwapBytes(); if (_Progs.version != PROG_VERSION) Sys.Error("progs.dat has wrong version number ({0} should be {1})", _Progs.version, PROG_VERSION); if (_Progs.crc != PROGHEADER_CRC) Sys.Error("progs.dat system vars have been modified, progdefs.h is out of date"); // Functions _Functions = new dfunction_t[_Progs.numfunctions]; int offset = _Progs.ofs_functions; for (int i = 0; i < _Functions.Length; i++, offset += dfunction_t.SizeInBytes) { _Functions[i] = Sys.BytesToStructure<dfunction_t>(buf, offset); _Functions[i].SwapBytes(); } // strings offset = _Progs.ofs_strings; int str0 = offset; for(int i = 0; i < _Progs.numstrings; i++, offset++) { // count string length while (buf[offset] != 0) offset++; } int length = offset - str0; _Strings = Encoding.ASCII.GetString(buf, str0, length); // Globaldefs _GlobalDefs = new ddef_t[_Progs.numglobaldefs]; offset = _Progs.ofs_globaldefs; for (int i = 0; i < _GlobalDefs.Length; i++, offset += ddef_t.SizeInBytes) { _GlobalDefs[i] = Sys.BytesToStructure<ddef_t>(buf, offset); _GlobalDefs[i].SwapBytes(); } // Fielddefs _FieldDefs = new ddef_t[_Progs.numfielddefs]; offset = _Progs.ofs_fielddefs; for (int i = 0; i < _FieldDefs.Length; i++, offset += ddef_t.SizeInBytes) { _FieldDefs[i] = Sys.BytesToStructure<ddef_t>(buf, offset); _FieldDefs[i].SwapBytes(); if ((_FieldDefs[i].type & DEF_SAVEGLOBAL) != 0) Sys.Error("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); } // Statements _Statements = new dstatement_t[_Progs.numstatements]; offset = _Progs.ofs_statements; for (int i = 0; i < _Statements.Length; i++, offset += dstatement_t.SizeInBytes) { _Statements[i] = Sys.BytesToStructure<dstatement_t>(buf, offset); _Statements[i].SwapBytes(); } // Swap bytes inplace if needed if (!BitConverter.IsLittleEndian) { offset = _Progs.ofs_globals; for (int i = 0; i < _Progs.numglobals; i++, offset += 4) { SwapHelper.Swap4b(buf, offset); } } GlobalStruct = Sys.BytesToStructure<globalvars_t>(buf, _Progs.ofs_globals); _Globals = new float[_Progs.numglobals - globalvars_t.SizeInBytes / 4]; Buffer.BlockCopy(buf, _Progs.ofs_globals + globalvars_t.SizeInBytes, _Globals, 0, _Globals.Length * 4); _EdictSize = _Progs.entityfields * 4 + dedict_t.SizeInBytes - entvars_t.SizeInBytes; _HGlobals = GCHandle.Alloc(_Globals, GCHandleType.Pinned); _GlobalsAddr = _HGlobals.AddrOfPinnedObject().ToInt64(); _HGlobalStruct = GCHandle.Alloc(Progs.GlobalStruct, GCHandleType.Pinned); _GlobalStructAddr = _HGlobalStruct.AddrOfPinnedObject().ToInt64(); }