Пример #1
0
void G_LoadCachedRoffs()
{
	int		i, count = 0, len = 0;
	char	buffer[MAX_QPATH];

	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	// Get the count of goodies we need to revive
	saved_game.read_chunk<int32_t>(
		INT_ID('R', 'O', 'F', 'F'),
		count);

	// Now bring 'em back to life
	for ( i = 0; i < count; i++ )
	{
		saved_game.read_chunk<int32_t>(
			INT_ID('S', 'L', 'E', 'N'),
			len);

		if (len < 0 || static_cast<size_t>(len) >= sizeof(buffer))
		{
			len = 0;
		}

		saved_game.read_chunk(
			INT_ID('R', 'S', 'T', 'R'),
			buffer,
			len);

		G_LoadRoff( buffer );
	}
}
Пример #2
0
void TIMER_Load( void )
{
	int j;
	gentity_t	*ent;

	for ( j = 0, ent = &g_entities[0]; j < MAX_GENTITIES; j++, ent++ )
	{
		unsigned char numTimers;

		gi.ReadFromSaveGame( INT_ID('T','I','M','E'), (void *)&numTimers, sizeof(numTimers), NULL );

		//Read back all entries
		for ( int i = 0; i < numTimers; i++ )
		{
			int		time;
			char	tempBuffer[1024];	// Still ugly. Setting ourselves up for 007 AUF all over again. =)

			assert (sizeof(g_timers[0]->time) == sizeof(time) );//make sure we're reading the same size as we wrote

			//Read the id string and time
			gi.ReadFromSaveGame( INT_ID('T','M','I','D'), (char *) tempBuffer, 0, NULL );
			gi.ReadFromSaveGame( INT_ID('T','D','T','A'), (void *) &time, sizeof( time ), NULL );

			//this is odd, we saved all the timers in the autosave, but not all the ents are spawned yet from an auto load, so skip it
			if (ent->inuse)
			{	//Restore it
				TIMER_Set(ent, tempBuffer, time);
			}
		}
	}
}
Пример #3
0
void G_SaveCachedRoffs()
{
	int i, len;

	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	// Write out the number of cached ROFFs
	saved_game.write_chunk<int32_t>(
		INT_ID('R', 'O', 'F', 'F'),
		::num_roffs);

	// Now dump out the cached ROFF file names in order so they can be loaded on the other end
	for ( i = 0; i < num_roffs; i++ )
	{
		// Dump out the string length to make things a bit easier on the other end...heh heh.
		len = strlen( roffs[i].fileName ) + 1;

		saved_game.write_chunk<int32_t>(
			INT_ID('S', 'L', 'E', 'N'),
			len);

		saved_game.write_chunk(
			INT_ID('R', 'S', 'T', 'R'),
			::roffs[i].fileName,
			len);
	}
}
Пример #4
0
void TIMER_Save( void )
{
	int			j;
	gentity_t	*ent;

	for ( j = 0, ent = &g_entities[0]; j < MAX_GENTITIES; j++, ent++ )
	{
		int numTimers = g_timers[ent->s.number].size();
		int	i;

		//Write out the timer information
		gi.AppendToSaveGame(INT_ID('T','I','M','E'), (void *)&numTimers, sizeof(numTimers));
		
		timer_m::iterator	ti;

		for ( i = 0, ti = g_timers[ j ].begin(); i < numTimers; i++, ti++ )
		{
			const char *id = ((*ti).first).c_str();
			int			length = strlen( id );

			//Write out the string size and data
			gi.AppendToSaveGame(INT_ID('T','S','L','N'), (void *) &length, sizeof(length) );
			gi.AppendToSaveGame(INT_ID('T','S','N','M'), (void *) id, length );

			//Write out the timer data
			gi.AppendToSaveGame(INT_ID('T','D','T','A'), (void *) &(*ti).second, sizeof( (*ti).second ) );
		}
	}
}
Пример #5
0
void WriteLevel(qboolean qbAutosave)
{
	if (!qbAutosave) //-always save the client
	{
		// write out one client - us!
		//
		assert(level.maxclients == 1);	// I'll need to know if this changes, otherwise I'll need to change the way ReadGame works
		gclient_t client = level.clients[0];
		EnumerateFields(savefields_gClient, (byte *)&client, INT_ID('G','C','L','I'), sizeof(client));	
		WriteLevelLocals();	// level_locals_t level	
	}

	OBJ_SaveObjectiveData();

	/////////////
	WriteGEntities(qbAutosave);
	Q3_VariableSave();
	G_LoadSave_WriteMiscData();

	extern void CG_WriteTheEvilCGHackStuff(void);
	CG_WriteTheEvilCGHackStuff();

	// (Do NOT put any write-code below this line)
	//
	// put out an end-marker so that the load code can check everything was read in...
	//
	static int iDONE = 1234;
	gi.AppendToSaveGame(INT_ID('D','O','N','E'), &iDONE, sizeof(iDONE));
}
Пример #6
0
void TIMER_Load( void )
{
	int j;
	gentity_t	*ent;

	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	for ( j = 0, ent = &g_entities[0]; j < MAX_GENTITIES; j++, ent++ )
	{
		unsigned char numTimers = 0;

		saved_game.read_chunk<uint8_t>(
			INT_ID('T', 'I', 'M', 'E'),
			numTimers);

		//Read back all entries
		for ( int i = 0; i < numTimers; i++ )
		{
			int		time = 0;
			char	tempBuffer[1024];	// Still ugly. Setting ourselves up for 007 AUF all over again. =)

			assert (sizeof(g_timers[0]->time) == sizeof(time) );//make sure we're reading the same size as we wrote

			//Read the id string and time
			saved_game.read_chunk(
				INT_ID('T', 'M', 'I', 'D'));

			const char* sg_buffer_data = static_cast<const char*>(
				saved_game.get_buffer_data());

			int sg_buffer_size = saved_game.get_buffer_size();

			if (sg_buffer_size < 0 || static_cast<size_t>(sg_buffer_size) >= sizeof(tempBuffer))
			{
				sg_buffer_size = 0;
			}
			else
			{
				std::uninitialized_copy_n(
					sg_buffer_data,
					sg_buffer_size,
					tempBuffer);
			}

			tempBuffer[sg_buffer_size] = '\0';

			saved_game.read_chunk<int32_t>(
				INT_ID('T', 'D', 'T', 'A'),
				time);

			//this is odd, we saved all the timers in the autosave, but not all the ents are spawned yet from an auto load, so skip it
			if (ent->inuse)
			{	//Restore it
				TIMER_Set(ent, tempBuffer, time);
			}
		}
	}
}
Пример #7
0
void TIMER_Load( void )
{
	int j;
	gentity_t	*ent;

	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	for ( j = 0, ent = &g_entities[0]; j < MAX_GENTITIES; j++, ent++ )
	{
		int numTimers = 0;

		saved_game.read_chunk<int32_t>(
			INT_ID('T', 'I', 'M', 'E'),
			numTimers);

		//Make sure there's something to read
		if ( numTimers == 0 )
			continue;

		//Read back all entries
		for ( int i = 0; i < numTimers; i++ )
		{
			int		length = 0, time = 0;
			char	tempBuffer[1024];	// Still ugly. Setting ourselves up for 007 AUF all over again. =)

			assert (sizeof(g_timers[0]->time) == sizeof(time) );//make sure we're reading the same size as we wrote

			saved_game.read_chunk<int32_t>(
				INT_ID('T', 'S', 'L', 'N'),
				length);
			
			if ( length >= 1024 ) {
				assert( 0 );
				continue;
			}

			//Read the id and time
			saved_game.read_chunk(
				INT_ID('T', 'S', 'N', 'M'),
				tempBuffer,
				length);

			tempBuffer[length] = '\0';

			saved_game.read_chunk<int32_t>(
				INT_ID('T', 'D', 'T', 'A'),
				time);

			//this is odd, we saved all the timers in the autosave, but not all the ents are spawned yet from an auto load, so skip it
			if (ent->inuse)
			{	//Restore it
				TIMER_Set(ent, tempBuffer, time);
			}
		}
	}
}
Пример #8
0
void ReadLevel(qboolean qbAutosave, qboolean qbLoadTransition)
{
	if ( qbLoadTransition )
	{
		//loadtransitions do not need to read the objectives and client data from the level they're going to
		//In a loadtransition, client data is carried over on the server and will be stomped later anyway.
		//The objective info (in client->sess data), however, is read in from G_ReadSessionData which is called before this func,
		//we do NOT want to stomp that session data when doing a load transition
		
		//However, we should still save this info out because these savegames may need to be
		//loaded normally later- perhaps if you die and need to respawn, perhaps as some kind
		//of emergency savegame for resuming, etc.

		//SO: We read it in, but throw it away.
		
		//Read & throw away gclient info
		gclient_t junkClient;
		EvaluateFields(savefields_gClient, (byte *)&junkClient, (byte *)&level.clients[0], INT_ID('G','C','L','I'), sizeof(*level.clients), qfalse);

		//Read & throw away objective info
		objectives_t	junkObj[MAX_MISSION_OBJ];
		gi.ReadFromSaveGame(INT_ID('O','B','J','T'), (void *) &junkObj, 0, NULL);

		ReadLevelLocals();	// level_locals_t level	
	}
	else
	{
		if (!qbAutosave )//always load the client unless it's an autosave
		{
			assert(level.maxclients == 1);	// I'll need to know if this changes, otherwise I'll need to change the way things work
		
			gclient_t GClient;
			EvaluateFields(savefields_gClient, (byte *)&GClient, (byte *)&level.clients[0], INT_ID('G','C','L','I'), sizeof(*level.clients), qfalse);
			level.clients[0] = GClient;	// struct copy
			ReadLevelLocals();	// level_locals_t level	
		}
		
		OBJ_LoadObjectiveData();//loads mission objectives AND tactical info
	}

	/////////////

	ReadGEntities(qbAutosave);
	Q3_VariableLoad();
	G_LoadSave_ReadMiscData();

	extern void CG_ReadTheEvilCGHackStuff(void);
	CG_ReadTheEvilCGHackStuff();

	// (Do NOT put any read-code below this line)
	//
	// check that the whole file content was loaded by specifically requesting an end-marker...
	//
	static int iDONE = 1234;
	gi.ReadFromSaveGame(INT_ID('D','O','N','E'), &iDONE, sizeof(iDONE), NULL);
}
Пример #9
0
void TIMER_Save( void )
{
	int			j;
	gentity_t	*ent;

	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	for ( j = 0, ent = &g_entities[0]; j < MAX_GENTITIES; j++, ent++ )
	{
		int numTimers = TIMER_GetCount(j);

		if ( !ent->inuse && numTimers)
		{
//			Com_Printf( "WARNING: ent with timers not inuse\n" );
			assert(numTimers);
			TIMER_Clear( j );
			numTimers = 0;
		}

		//Write out the timer information
		saved_game.write_chunk<int32_t>(
			INT_ID('T', 'I', 'M', 'E'),
			numTimers);
	
		gtimer_t *p = g_timers[j];
		assert ((numTimers && p) || (!numTimers && !p));

		while(p)
		{
			const char	*timerID = p->id.c_str();
			const int	length = strlen(timerID) + 1;
			const int	time = p->time - level.time;	//convert this back to delta so we can use SET after loading

			assert( length < 1024 );//This will cause problems when loading the timer if longer

			//Write out the string size and data
			saved_game.write_chunk<int32_t>(
				INT_ID('T', 'S', 'L', 'N'),
				length);

			saved_game.write_chunk(
				INT_ID('T', 'S', 'N', 'M'),
				timerID,
				length);

			//Write out the timer data
			saved_game.write_chunk<int32_t>(
				INT_ID('T', 'D', 'T', 'A'),
				time);

			p = p->next;
		}
	}
}
Пример #10
0
void EvaluateFields(field_t *pFields, byte *pbData, byte *pbOriginalRefData, unsigned int ulChid, int iSize, qboolean bOkToSizeMisMatch)
{	
	int iReadSize = gi.ReadFromSaveGame(ulChid, pbData, bOkToSizeMisMatch?0:iSize, NULL);

	if (iReadSize != iSize)
	{
		// handle any chunks that are ok to change length (typically this is a last minute hack, 
		//	so hopefully we won't need it any more... ;-)
		//
		switch (ulChid)
		{
			// example chunk handler...
			//				
			case INT_ID('G','C','L','I'):
/*				assert(iSize>iReadSize);
				memset(&pbData[iReadSize], 0, iSize-iReadSize);	// zero out new objectives that weren't in old-format save file			
				break;
*/
			default:
				// won't return...
				//
				G_Error(va("EvaluateFields(): variable-sized chunk '%s' without handler!",SG_GetChidText(ulChid)));
				break;
		}
	}
	
	if (pFields)
	{
		for (field_t *pField = pFields; pField->psName; pField++)
		{
			EvaluateField(pField, pbData, pbOriginalRefData);
		}
	}
}
Пример #11
0
void EnumerateFields(field_t *pFields, byte *pbData, unsigned int ulChid, int iLen)
{
	assert(strList.empty());

	// enumerate all the fields...
	//
	if (pFields)
	{
		for (field_t *pField = pFields; pField->psName; pField++)
		{
			assert(pField->iOffset < iLen);
			EnumerateField(pField, pbData);
		}
	}
	
	// save out raw data...
	//
	gi.AppendToSaveGame(ulChid, pbData, iLen);

	// save out any associated strings..
	//
	list<sstring_t>::iterator it = strList.begin();
	for (unsigned int i=0; i<strList.size(); i++, ++it)
	{
		gi.AppendToSaveGame(INT_ID('S','T','R','G'), (void *)(*it).c_str(), (*it).length() + 1);
	}
	
	strList.clear();	// make sure everything is cleaned up nicely
}
Пример #12
0
static void EnumerateFields(const field_t *pFields, byte *pbData, unsigned int ulChid, size_t iLen)
{
	strList = new list<sstring_t>;

	// enumerate all the fields...
	//
	if (pFields)
	{
		for (const field_t *pField = pFields; pField->psName; pField++)
		{
			assert(pField->iOffset < iLen);
			EnumerateField(pField, pbData);
		}
	}

	// save out raw data...
	//
	gi.AppendToSaveGame(ulChid, pbData, iLen);

	// save out any associated strings..
	//
	for (list<sstring_t>::iterator it = strList->begin(); it != strList->end(); ++it)
	{
		gi.AppendToSaveGame(INT_ID('S','T','R','G'), (void*)it->c_str(), it->length()+1);
	}

	delete strList;
	strList = NULL;
}
Пример #13
0
qboolean SG_Open( const char *psPathlessBaseName )
{
//	if ( fhSaveGame )		// hmmm...
//	{						//
//		SG_Close();			//
//	}						//
	assert( !fhSaveGame);	// I'd rather know about this
	if(!psPathlessBaseName)
	{
		return qfalse;
	}
//JLFSAVEGAME

	const char *psLocalFilename = SG_AddSavePath( psPathlessBaseName );
	FS_FOpenFileRead( psLocalFilename, &fhSaveGame, qtrue );	//qtrue = dup handle, so I can close it ok later
	if (!fhSaveGame)
	{
//		Com_Printf(S_COLOR_RED "Failed to open savegame file %s\n", psLocalFilename);
		Com_DPrintf(GetString_FailedToOpenSaveGame(psLocalFilename, qtrue));

		return qfalse;
	}
	giSaveGameVersion=-1;//jic
	SG_Read(INT_ID('_','V','E','R'), &giSaveGameVersion, sizeof(giSaveGameVersion));
	if (giSaveGameVersion != iSAVEGAME_VERSION)
	{
		SG_Close();
		Com_Printf (S_COLOR_RED "File \"%s\" has version # %d (expecting %d)\n",psPathlessBaseName, giSaveGameVersion, iSAVEGAME_VERSION);
		return qfalse;
	}

	return qtrue;
}
Пример #14
0
void process_text(char *in_buffer) {
    uint8_t last_pos = *ringbuffer_pos;
    char buffer[64] = {0};

    while(1) {
        uint8_t new_pos;
        while(last_pos == (new_pos = *ringbuffer_pos)) {
            uint64_t info = wait_for_interrupt();
            if(INT_ID(info) == CLOCK_ID) {
                toggle_pos(cursor_pos, normal, inverted);
            }
        }
        while(last_pos != new_pos) {
            uint8_t c;
            c = keyboard_ringbuffer[last_pos];
            process_char(c,1);
            last_pos = ((last_pos + 1) % RINGBUFFER_SIZE);
            if(c == '\r') {
                strcpy(in_buffer, input);
                process_char('\r',0);
                input_size = 0;
                memset(input,0,sizeof(input));
                goto done;
            }
        }
    }
done:
    return;
}
Пример #15
0
static char *GetStringPtr(int iStrlen, char *psOriginal/*may be NULL*/)
{
	if (iStrlen != -1)
	{
		char sString[768];	// arb, inc if nec.

		sString[0]=0;

		assert(iStrlen+1<=(int)sizeof(sString));

		ojk::SavedGameHelper saved_game(
			::gi.saved_game);

		saved_game.read_chunk(
			INT_ID('S', 'T', 'R', 'G'),
			sString,
			iStrlen);

		// TAG_G_ALLOC is always blown away, we can never recycle
		if (psOriginal && gi.bIsFromZone(psOriginal, TAG_G_ALLOC)) {
			if (!strcmp(psOriginal,sString))
			{//it's a legal ptr and they're the same so let's just reuse it instead of free/alloc
				return psOriginal;
			}
			gi.Free(psOriginal);
		}

		return G_NewString(sString);
	}

	return NULL;
}
Пример #16
0
/*
==============
WriteLevelLocals

All pointer variables (except function pointers) must be handled specially.
==============
*/
static void WriteLevelLocals ()
{
	level_locals_t *temp = (level_locals_t *)gi.Malloc(sizeof(level_locals_t), TAG_TEMP_WORKSPACE, qfalse);
	*temp = level;	// copy out all data into a temp space

	EnumerateFields(savefields_LevelLocals, temp, INT_ID('L','V','L','C'));
	gi.Free(temp);
}
Пример #17
0
/*
==============
WriteLevelLocals

All pointer variables (except function pointers) must be handled specially.
==============
*/
static void WriteLevelLocals ()
{
	level_locals_t *temp = (level_locals_t *)gi.Malloc(sizeof(level_locals_t), TAG_TEMP_WORKSPACE, qfalse);
	*temp = level;	// copy out all data into a temp space

	EnumerateFields(savefields_LevelLocals, (byte *)temp, INT_ID('L','V','L','C'), LLOFS(LEVEL_LOCALS_T_SAVESTOP));	// sizeof(temp));
	gi.Free(temp);
}
Пример #18
0
void G_LoadSave_ReadMiscData(void)
{
	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	saved_game.read_chunk<int32_t>(
		INT_ID('L', 'C', 'K', 'D'),
		::player_locked);
}
Пример #19
0
void WriteInUseBits()
{
	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	saved_game.write_chunk<uint32_t>(
		INT_ID('I', 'N', 'U', 'S'),
		::g_entityInUseBits);
}
Пример #20
0
void ReadInUseBits(void)
{
	gi.ReadFromSaveGame(INT_ID('I','N','U','S'), &g_entityInUseBits, sizeof(g_entityInUseBits), NULL);
	// This is only temporary. Once I have converted all the ent->inuse refs,
	// it won;t be needed -MW.
	for(int i=0;i<MAX_GENTITIES;i++)
	{
		g_entities[i].inuse=PInUse(i);
	}
}
Пример #21
0
static void EvaluateFields(
	const save_field_t* pFields,
	T* pbData,
	byte* pbOriginalRefData,
	unsigned int ulChid)
{
	T& instance = *pbData;

	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	if (ulChid != INT_ID('G', 'C', 'L', 'I'))
	{
		saved_game.read_chunk(
			ulChid,
			instance);
	}
	else
	{
		if (!saved_game.try_read_chunk(
			ulChid,
			instance))
		{
			RetailGClient retail_client;

			saved_game.reset_buffer_offset();

			if (saved_game.try_read(
				retail_client))
			{
				copy_retail_gclient_to_current(
					retail_client,
					*reinterpret_cast<gclient_t*>(pbData));
			}
			else
			{
				::G_Error(
					::va("EvaluateFields(): variable-sized chunk '%s' without handler!",
						::SG_GetChidText(ulChid)));
			}
		}
	}

	if (pFields)
	{
		for (const save_field_t* pField = pFields; pField->psName; ++pField)
		{
			::EvaluateField(
				pField,
				reinterpret_cast<byte*>(pbData),
				pbOriginalRefData);
		}
	}
}
Пример #22
0
/*
==============
ReadLevelLocals

All pointer variables (except function pointers) must be handled specially.
==============
*/
void ReadLevelLocals ()
{
	// preserve client ptr either side of the load, because clients are already saved/loaded through Read/Writegame...
	//
	gclient_t *pClients = level.clients;	// save clients

	level_locals_t temp = level;	// struct copy
	EvaluateFields(savefields_LevelLocals, (byte *)&temp, (byte *)&level, INT_ID('L','V','L','C'), LLOFS(LEVEL_LOCALS_T_SAVESTOP),qfalse);	// sizeof(level_locals_t));
	level = temp;					// struct copy

	level.clients = pClients;				// restore clients
}
Пример #23
0
void TIMER_Save( void )
{
	int			j;
	gentity_t	*ent;

	for ( j = 0, ent = &g_entities[0]; j < MAX_GENTITIES; j++, ent++ )
	{
		unsigned char numTimers = TIMER_GetCount(j);

		if ( !ent->inuse && numTimers)
		{
//			Com_Printf( "WARNING: ent with timers not inuse\n" );
			assert(numTimers);
			TIMER_Clear( j );
			numTimers = 0;
		}

		//Write out the timer information
		gi.AppendToSaveGame(INT_ID('T','I','M','E'), (void *)&numTimers, sizeof(numTimers));
	
		gtimer_t *p = g_timers[j];
		assert ((numTimers && p) || (!numTimers && !p));

		while(p)
		{
			const char	*timerID = p->id.c_str();
			const int	length = strlen(timerID) + 1;
			const int	time = p->time - level.time;	//convert this back to delta so we can use SET after loading

			assert( length < 1024 );//This will cause problems when loading the timer if longer

			//Write out the id string
			gi.AppendToSaveGame(INT_ID('T','M','I','D'), (void *) timerID, length);

			//Write out the timer data
			gi.AppendToSaveGame(INT_ID('T','D','T','A'), (void *) &time, sizeof( time ) );
			p = p->next;
		}
	}
}
Пример #24
0
int CSequence::SaveCommand( CBlock *block )
{
	unsigned char	flags;
	int				numMembers, bID, size;
	CBlockMember	*bm;

	ojk::SavedGameHelper saved_game(
		m_owner->GetInterface()->saved_game);

	//Save out the block ID
	bID = block->GetBlockID();

	saved_game.write_chunk<int32_t>(
		INT_ID('B', 'L', 'I', 'D'),
		bID);

	//Save out the block's flags
	flags = block->GetFlags();

	saved_game.write_chunk<uint8_t>(
		INT_ID('B', 'F', 'L', 'G'),
		flags);

	//Save out the number of members to read
	numMembers = block->GetNumMembers();

	saved_game.write_chunk<int32_t>(
		INT_ID('B', 'N', 'U', 'M'),
		numMembers);

	for ( int i = 0; i < numMembers; i++ )
	{
		bm = block->GetMember( i );

		//Save the block id
		bID = bm->GetID();

		saved_game.write_chunk<int32_t>(
			INT_ID('B', 'M', 'I', 'D'),
			bID);
		
		//Save out the data size
		size = bm->GetSize();

		saved_game.write_chunk<int32_t>(
			INT_ID('B', 'S', 'I', 'Z'),
			size);
		
		//Save out the raw data
        const uint8_t* raw_data = static_cast<const uint8_t*>(bm->GetData());

		saved_game.write_chunk(
			INT_ID('B', 'M', 'E', 'M'),
			raw_data,
			size);
	}

	return true;
}
Пример #25
0
void TIMER_Load( void )
{
	int j;
	gentity_t	*ent;

	for ( j = 0, ent = &g_entities[0]; j < MAX_GENTITIES; j++, ent++ )
	{
		int numTimers;

		gi.ReadFromSaveGame( INT_ID('T','I','M','E'), (void *)&numTimers, sizeof(numTimers), NULL );

		//Make sure there's something to read
		if ( numTimers == 0 )
			continue;
		
		//Read back all entries
		for ( int i = 0; i < numTimers; i++ )
		{
			int		length, time;
			char	tempBuffer[1024];	//FIXME: Blech!

			gi.ReadFromSaveGame( INT_ID('T','S','L','N'), (void *) &length, sizeof( length ), NULL );

			//Validity check, though this will never happen (unless of course you pass in gibberish)
			if ( length >= 1024 )
			{
				assert(0);
				continue;
			}

			//Read the id and time
			gi.ReadFromSaveGame( INT_ID('T','S','N','M'), (char *) tempBuffer, length, NULL );
			gi.ReadFromSaveGame( INT_ID('T','D','T','A'), (void *) &time, sizeof( time ), NULL );

			//Restore it
			g_timers[ j ][(const char *) tempBuffer ] = time;
		}
	}
}
Пример #26
0
/*
==============
ReadLevelLocals

All pointer variables (except function pointers) must be handled specially.
==============
*/
static void ReadLevelLocals ()
{
	// preserve client ptr either side of the load, because clients are already saved/loaded through Read/Writegame...
	//
	gclient_t *pClients = level.clients;	// save clients

	level_locals_t *temp = (level_locals_t *)gi.Malloc(sizeof(level_locals_t), TAG_TEMP_WORKSPACE, qfalse);
	*temp = level;	// struct copy
	EvaluateFields(savefields_LevelLocals, temp, (byte *)&level, INT_ID('L','V','L','C'));
	level = *temp;					// struct copy

	level.clients = pClients;				// restore clients
	gi.Free(temp);
}
Пример #27
0
int CSequence::Save( void )
{
	sequence_l::iterator	ci;
	block_l::iterator		bi;
	int						id;

	//Save the parent (by GUID)
	id = ( m_parent != NULL ) ? m_parent->GetID() : -1;
	(m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','P','I','D'), &id, sizeof( id ) );

	//Save the return (by GUID)
	id = ( m_return != NULL ) ? m_return->GetID() : -1;
	(m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','R','I','D'), &id, sizeof( id ) );
	
	//Save the number of children
	(m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','N','C','H'), &m_numChildren, sizeof( m_numChildren ) );

	//Save out the children (only by GUID)
	STL_ITERATE( ci, m_children )
	{
		id = (*ci)->GetID();
		(m_owner->GetInterface())->I_WriteSaveData( INT_ID('S','C','H','D'), &id, sizeof( id ) );
	}
Пример #28
0
int CSequence::Save( void )
{
	sequence_l::iterator	ci;
	block_l::iterator		bi;
	int						id;

	ojk::SavedGameHelper saved_game(
		m_owner->GetInterface()->saved_game);

	//Save the parent (by GUID)
	id = ( m_parent != NULL ) ? m_parent->GetID() : -1;

	saved_game.write_chunk<int32_t>(
		INT_ID('S', 'P', 'I', 'D'),
		id);

	//Save the return (by GUID)
	id = ( m_return != NULL ) ? m_return->GetID() : -1;

	saved_game.write_chunk<int32_t>(
		INT_ID('S', 'R', 'I', 'D'),
		id);
	
	//Save the number of children
	saved_game.write_chunk<int32_t>(
		INT_ID('S', 'N', 'C', 'H'),
		m_numChildren);

	//Save out the children (only by GUID)
	STL_ITERATE( ci, m_children )
	{
		id = (*ci)->GetID();

		saved_game.write_chunk<int32_t>(
			INT_ID('S', 'C', 'H', 'D'),
			id);
	}
Пример #29
0
void ReadInUseBits()
{
	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	saved_game.read_chunk<uint32_t>(
		INT_ID('I', 'N', 'U', 'S'),
		::g_entityInUseBits);

	// This is only temporary. Once I have converted all the ent->inuse refs,
	// it won;t be needed -MW.
	for(int i=0;i<MAX_GENTITIES;i++)
	{
		g_entities[i].inuse=PInUse(i);
	}
}
Пример #30
0
static void EvaluateFields(const save_field_t *pFields, byte *pbData, byte *pbOriginalRefData, unsigned int ulChid, int iSize, qboolean bOkToSizeMisMatch)
{
	int iReadSize = gi.ReadFromSaveGame(ulChid, pbData, bOkToSizeMisMatch?0:iSize, NULL);

	if (iReadSize != iSize)
	{
		// handle any chunks that are ok to change length (typically this is a last minute hack,
		//	so hopefully we won't need it any more... ;-)
		//
		switch (ulChid)
		{
			// example chunk handler...
			//
			case INT_ID('G','C','L','I'):
				if ( iSize == (int)(iReadSize+((sizeof(saberInfo_t)-sizeof(saberInfoRetail_t))*2)) )
				{
					gclient_t newClient;
					const int	preSaberDataSize = ((intptr_t)&newClient.ps.saber[0]-(intptr_t)&newClient);
					memcpy( &newClient, pbData, preSaberDataSize );
					SG_ConvertRetailSaberinfoToNewSaberinfo( ((void *)(&((gclient_t *)(pbData))->ps.saber[0])), &newClient.ps.saber[0] );
					memcpy( &newClient.ps.dualSabers, pbData+preSaberDataSize+(sizeof(saberInfoRetail_t)*2), sizeof(newClient)-(preSaberDataSize+(sizeof(saberInfo_t)*2)) );
					memcpy( pbData, &newClient, sizeof(gclient_t) );
				}
				else
				{//opps, not a saberInfo size mismatch, some other FUBAR-ness...
					G_Error(va("EvaluateFields(): variable-sized chunk '%s' without handler!",SG_GetChidText(ulChid)));
				}
				break;

			default:
				// won't return...
				//
				G_Error(va("EvaluateFields(): variable-sized chunk '%s' without handler!",SG_GetChidText(ulChid)));
				break;
		}
	}

	if (pFields)
	{
		for (const save_field_t *pField = pFields; pField->psName; pField++)
		{
			EvaluateField(pField, pbData, pbOriginalRefData);
		}
	}
}