Source/ThunderBeast/QuakeToon/game/g_save.c
void ReadLevel (char *filename)
{
	int		entnum;
	FILE	*f;
	int		i;
	void	*base;
	edict_t	*ent;

	f = fopen (filename, "rb");
	if (!f)
		gi.error ("Couldn't open %s", filename);

	// free any dynamic memory allocated by loading the level
	// base state
	gi.FreeTags (TAG_LEVEL);

	// wipe all the entities
	memset (g_edicts, 0, game.maxentities*sizeof(g_edicts[0]));
	globals.num_edicts = maxclients->value+1;

	// check edict size
	fread (&i, sizeof(i), 1, f);
	if (i != sizeof(edict_t))
	{
		fclose (f);
		gi.error ("ReadLevel: mismatched edict size");
	}

	// check function pointer base address
	fread (&base, sizeof(base), 1, f);
#ifdef _WIN32
	if (base != (void *)InitGame)
	{
		fclose (f);
		gi.error ("ReadLevel: function pointers have moved");
	}
#else
	gi.dprintf("Function offsets %d\n", ((byte *)base) - ((byte *)InitGame));
#endif

	// load the level locals
	ReadLevelLocals (f);

	// load all the entities
	while (1)
	{
		if (fread (&entnum, sizeof(entnum), 1, f) != 1)
		{
			fclose (f);
			gi.error ("ReadLevel: failed to read entnum");
		}
		if (entnum == -1)
			break;
		if (entnum >= globals.num_edicts)
			globals.num_edicts = entnum+1;

		ent = &g_edicts[entnum];
		ReadEdict (f, ent);

		// let the server rebuild world links for this ent
		memset (&ent->area, 0, sizeof(ent->area));
		gi.linkentity (ent);
	}

	fclose (f);

	// mark all clients as unconnected
	for (i=0 ; i<maxclients->value ; i++)
	{
		ent = &g_edicts[i+1];
		ent->client = game.clients + i;
		ent->client->pers.connected = false;
	}

	// do any load time things at this point
	for (i=0 ; i<globals.num_edicts ; i++)
	{
		ent = &g_edicts[i];

		if (!ent->inuse)
			continue;

		// fire any cross-level triggers
		if (ent->classname)
			if (strcmp(ent->classname, "target_crosslevel_target") == 0)
				ent->nextthink = level.time + ent->delay;
	}
}
/*
=================
ReadLevel

SpawnEntities will allready have been called on the
level the same way it was when the level was saved.

That is necessary to get the baselines
set up identically.

The server will have cleared all of the world links before
calling ReadLevel.

No clients are connected yet.
=================
*/
ReadLevel
SpawnEntities will allready have been called on the
level the same way it was when the level was saved.

That is necessary to get the baselines
set up identically.

The server will have cleared all of the world links before
calling ReadLevel.

No clients are connected yet.
ReadLevel SpawnEntities will allready have been called on the level the same way it was when the level was saved . That is necessary to get the baselines set up identically . The server will have cleared all of the world links before calling ReadLevel . No clients are connected yet .
void ReadLevel (char *filename)
{
	int		entnum;
	FILE	*f;
	int		i;
	void	*base;
	edict_t	*ent;
	f = fopen (filename, "rb");
	if (!f)
		gi.error ("Couldn't open %s", filename);
	gi.FreeTags (TAG_LEVEL);
	memset (g_edicts, 0, game.maxentities*sizeof(g_edicts[0]));
	globals.num_edicts = maxclients->value+1;
	fread (&i, sizeof(i), 1, f);
	if (i != sizeof(edict_t))
	{
		fclose (f);
		gi.error ("ReadLevel: mismatched edict size");
	}
	fread (&base, sizeof(base), 1, f);
#ifdef _WIN32
	if (base != (void *)InitGame)
	{
		fclose (f);
		gi.error ("ReadLevel: function pointers have moved");
	}
#else
	gi.dprintf("Function offsets %d\n", ((byte *)base) - ((byte *)InitGame));
#endif
	ReadLevelLocals (f);
	while (1)
	{
		if (fread (&entnum, sizeof(entnum), 1, f) != 1)
		{
			fclose (f);
			gi.error ("ReadLevel: failed to read entnum");
		}
		if (entnum == -1)
			break;
		if (entnum >= globals.num_edicts)
			globals.num_edicts = entnum+1;
		ent = &g_edicts[entnum];
		ReadEdict (f, ent);
		memset (&ent->area, 0, sizeof(ent->area));
		gi.linkentity (ent);
	}
	fclose (f);
	for (i=0 ; i<maxclients->value ; i++)
	{
		ent = &g_edicts[i+1];
		ent->client = game.clients + i;
		ent->client->pers.connected = false;
	}
	for (i=0 ; i<globals.num_edicts ; i++)
	{
		ent = &g_edicts[i];
		if (!ent->inuse)
			continue;
		if (ent->classname)
			if (strcmp(ent->classname, "target_crosslevel_target") == 0)
				ent->nextthink = level.time + ent->delay;
	}
}
void ReadLevel ( char * filename ) { int entnum ; FILE * f ; int i ; void * base ; edict_t * ent ; f = fopen ( filename , " " ) ; if ( ! f ) gi . error ( " " , filename ) ; gi . FreeTags ( TAG_LEVEL ) ; memset ( g_edicts , 0 , game . maxentities * sizeof ( g_edicts [ 0 ] ) ) ; globals . num_edicts = maxclients -> value + 1 ; fread ( & i , sizeof ( i ) , 1 , f ) ; if ( i != sizeof ( edict_t ) ) { fclose ( f ) ; gi . error ( " " ) ; } fread ( & base , sizeof ( base ) , 1 , f ) ; #ifdef _WIN32 if ( base != ( void * ) InitGame ) { fclose ( f ) ; gi . error ( " " ) ; } #else gi . dprintf ( " \n " , ( ( byte * ) base ) - ( ( byte * ) InitGame ) ) ; #endif ReadLevelLocals ( f ) ; while ( 1 ) { if ( fread ( & entnum , sizeof ( entnum ) , 1 , f ) != 1 ) { fclose ( f ) ; gi . error ( " " ) ; } if ( entnum == -1 ) break ; if ( entnum >= globals . num_edicts ) globals . num_edicts = entnum + 1 ; ent = & g_edicts [ entnum ] ; ReadEdict ( f , ent ) ; memset ( & ent -> area , 0 , sizeof ( ent -> area ) ) ; gi . linkentity ( ent ) ; } fclose ( f ) ; for ( i = 0 ; i < maxclients -> value ; i ++ ) { ent = & g_edicts [ i + 1 ] ; ent -> client = game . clients + i ; ent -> client -> pers . connected = false ; } for ( i = 0 ; i < globals . num_edicts ; i ++ ) { ent = & g_edicts [ i ] ; if ( ! ent -> inuse ) continue ; if ( ent -> classname ) if ( strcmp ( ent -> classname , " " ) == 0 ) ent -> nextthink = level . time + ent -> delay ; } }
ReadLevel
SpawnEntities will allready have been called on the
level the same way it was when the level was saved.
ReadLevel SpawnEntities will allready have been called on the level the same way it was when the level was saved .
// free any dynamic memory allocated by loading the level // base state // wipe all the entities // check edict size // check function pointer base address // load the level locals // load all the entities // let the server rebuild world links for this ent // mark all clients as unconnected // do any load time things at this point // fire any cross-level triggers