/// <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();
}