⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archive.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//
//  $Logfile:: /Quake 2 Engine/Sin/code/game/archive.cpp                      $
// $Revision:: 19                                                             $
//   $Author:: Aldie                                                          $
//     $Date:: 11/12/98 3:46p                                                 $
//
// Copyright (C) 1997 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// $Log:: /Quake 2 Engine/Sin/code/game/archive.cpp                           $
// 
// 19    11/12/98 3:46p Aldie
// Fixed length check for files not found.
// 
// 18    11/12/98 2:41p Markd
// added assert for pos in Read
// 
// 17    11/12/98 12:19p Markd
// archive file was being loaded as TAG_GAME this was a VERY BAD thing.
// 
// 16    11/12/98 2:31a Jimdose
// Added ReadFile.  Archives now read from pak files
// 
// 15    10/19/98 12:04a Jimdose
// made all code use fast checks for inheritance (no text lookups when
// possible)
// isSubclassOf no longer requires ::_classinfo()
// 
// 14    10/10/98 1:26a Jimdose
// ReadObject no longer cancels objects events
// 
// 13    10/07/98 11:41p Jimdose
// Got savegames working!!!
// Rewrote event archiving
// 
// 12    9/22/98 7:18p Markd
// forgot to free up a list of objects when closing the file
// 
// 11    9/22/98 3:58a Jimdose
// Incremented the archive version number
// 
// 10    9/21/98 10:15p Markd
// Putting archiving and unarchiving functions in
// 
// 9     9/21/98 4:21p Markd
// Put in archive functions and rewrote all archive routines
// 
// 8     7/26/98 2:15a Jimdose
// ReadObject was casting a Class * as a Entity *.  Not bad, but wrong.
// 
// 7     6/11/98 7:18p Jimdose
// FileError now closes the file before exiting.  This prevents an assertion
// when the object is deleted but the file is still open.
// 
// 6     5/24/98 8:46p Jimdose
// Made a lot of functions more str-friendly.
// Got rid of a lot of char * based strings
// Cleaned up get spawn arg functions and sound functions
// sound functions now use consistant syntax
// 
// 5     5/24/98 4:48p Jimdose
// Made char *'s const
// 
// 4     5/09/98 8:04p Jimdose
// Create now creates the path if it doesn't exist
// 
// 3     5/08/98 2:50p Jimdose
// fixed bugs
// 
// 2     5/07/98 10:39p Jimdose
// created file
// 
// 1     5/06/98 8:19p Jimdose
// 
// DESCRIPTION:
// Class for archiving objects
// 
#include "g_local.h"
#include "archive.h"

#define ARCHIVE_WRITE 0
#define ARCHIVE_READ  1

enum
	{
   ARC_NULL, ARC_Vector, ARC_Integer, ARC_Unsigned, ARC_Byte, ARC_Char, ARC_Short, ARC_UnsignedShort,
	ARC_Float, ARC_Double, ARC_Boolean, ARC_String, ARC_Raw, ARC_Object, ARC_ObjectPointer,
   ARC_SafePointer, ARC_Event, ARC_Quat, ARC_Entity,
	ARC_NUMTYPES
	};

static const char *typenames[] =
	{
   "NULL", "vector", "int", "unsigned", "byte", "char", "short", "unsigned short",
	"float", "double", "qboolean", "string", "raw data", "object", "objectpointer",
   "safepointer", "event", "quaternion", "entity"
	};

#define ArchiveHeader   ( *( int * )"SIN\0" )
#define ArchiveVersion	2                       // This must be changed any time the format changes!
#define ArchiveInfo     "Sin Archive Version 2" // This must be changed any time the format changes!

CLASS_DECLARATION( Class, ReadFile, NULL );

ResponseDef ReadFile::Responses[] =
	{
		{ NULL, NULL }
	};

ReadFile::ReadFile()
	{
   length = 0;
   buffer = NULL;
   pos = 0;
   }

ReadFile::~ReadFile()
	{
   Close();
   }

void ReadFile::Close
   (
   void
   )

   {
	if ( buffer )
		{
		gi.TagFree( ( void * )buffer );
      buffer = NULL;
		}

   filename = "";
   length = 0;
   pos = 0;
   }

const char *ReadFile::Filename
   (
   void
   )

   {
   return filename.c_str();
   }

size_t ReadFile::Length
   (
   void
   )

   {
   return length;
   }

size_t ReadFile::Pos
   (
   void
   )

   {
   return pos - buffer;
   }

qboolean ReadFile::Seek
   (
   size_t newpos
   )

   {
   if ( !buffer )
      {
      return false;
      }

   if ( newpos < 0 )
      {
      return false;
      }

   if ( newpos > length )
      {
      return false;
      }

   pos = buffer + newpos;

   return true;
   }

qboolean ReadFile::Open
   (
   const char *name
   )

   {
   assert( name );

   assert( !buffer );
   Close();

   if ( !name )
      {
      return false;
      }

	length = gi.LoadFile( name, ( void ** )&buffer, 0 );
	if ( length == ( size_t )( -1 ) )
		{
      return false;
      }

   filename = name;
   pos = buffer;

   return true;
   }

qboolean ReadFile::Read
   (
   void *dest,
   size_t size
   )

   {
   assert( dest );
   assert( buffer );
   assert( pos );

   if ( !dest )
      {
      return false;
      }

   if ( size <= 0 )
      {
      return false;
      }

   if ( ( pos + size ) > ( buffer + length ) )
      {
      return false;
      }

   memcpy( dest, pos, size );
   pos += size;

   return true;
   }

CLASS_DECLARATION( Class, Archiver, NULL );

ResponseDef Archiver::Responses[] =
	{
		{ NULL, NULL }
	};

Archiver::Archiver()
	{
	file = NULL;
	fileerror = false;
	assert( ( sizeof( typenames ) / sizeof( typenames[ 0 ] ) ) == ARC_NUMTYPES );
	}

Archiver::~Archiver()
	{
	if ( file )
		{
		Close();
		}

   readfile.Close();
	}

void Archiver::FileError
	(
	const char *fmt,
	...
	)

	{
	va_list	argptr;
	char		text[ 1024 ];

	va_start( argptr, fmt );
	vsprintf( text, fmt, argptr );
	va_end( argptr );

	fileerror = true;
	Close();
	if ( archivemode == ARCHIVE_READ )
		{
		gi.error( "Error while loading %s : %s\n", filename.c_str(), text );
		}
	else
		{
		gi.error( "Error while writing to %s : %s\n", filename.c_str(), text );
		}
	}

void Archiver::Close
	(
	void
	)

	{
	if ( file )
		{
      if ( archivemode == ARCHIVE_WRITE )
         {
         // write out the number of classpointers
		   fseek( file, numclassespos, SEEK_SET );
         numclassespos = ftell( file );
         WriteInteger( classpointerList.NumObjects() );
         }

		fclose( file );
		file = NULL;
		}

   readfile.Close();

	if ( archivemode == ARCHIVE_READ )
      {
      int i, num;
      Class * classptr;
      pointer_fixup_t *fixup;

      num = fixupList.NumObjects();
      for( i = 1; i <= num; i++ )
         {
         fixup = fixupList.ObjectAt( i );
         classptr = classpointerList.ObjectAt( fixup->index );
         if ( fixup->type == pointer_fixup_normal )
            {
            Class ** fixupptr;
            fixupptr = ( Class ** )fixup->ptr;
            *fixupptr = classptr;
            }
         else if ( fixup->type == pointer_fixup_safe )
            {
            SafePtrBase * fixupptr;
            fixupptr = ( SafePtrBase * )fixup->ptr;
            fixupptr->InitSafePtr( classptr );
            }
         delete fixup;
         }
      fixupList.FreeObjectList();
      classpointerList.FreeObjectList();
      }
	}

/****************************************************************************************

  File Read functions

*****************************************************************************************/

void Archiver::Read
	(
   const char *name
	)

	{
	unsigned header;
	unsigned version;
	str		info;
   int      num;
   int      i;
   Class    *null;

   assert( name );
   if ( !name )
      {
      gi.error( "NULL pointer for filename in Archiver::Read.\n" );
      }

	fileerror = false;

	archivemode = ARCHIVE_READ;

	filename = name;

	if ( !readfile.Open( filename.c_str() ) )
		{
		FileError( "Couldn't open file." );
		}

	header = ReadUnsigned();
	if ( header != ArchiveHeader )
		{
      readfile.Close();
		FileError( "Not a valid Sin archive." );
		}

	version = ReadUnsigned();
	if ( version > ArchiveVersion )
		{
		readfile.Close();
		FileError( "Archive is from version %.2f.  Check http://www.ritual.com for an update.", version );
		}

	if ( version < ArchiveVersion )
		{
		readfile.Close();
		FileError( "Archive is out of date." );
		}

	info = ReadString();
	gi.dprintf( "%s\n", info.c_str() );

   // setup out class pointers
   num = ReadInteger();
   classpointerList.Resize( num );
   null = NULL;
   for( i = 1; i <= num; i++ )
      {
      classpointerList.AddObject( null );
      }
	}

inline void Archiver::CheckRead
	(
	void
	)

	{
	assert( archivemode == ARCHIVE_READ );
	if ( !fileerror && ( archivemode != ARCHIVE_READ ) )
		{
		FileError( "File read during a write operation." );
		}
	}

inline int Archiver::ReadType
	(
	void
	)

	{
	int t;

	if ( !fileerror )
		{
      readfile.Read( &t, sizeof( t ) );

      return t;
		}

   return ARC_NULL;
	}

inline void Archiver::CheckType
	(
	int type
	)

	{
	int t;

	assert( ( type >= 0 ) && ( type < ARC_NUMTYPES ) );

	if ( !fileerror )
		{
      t = ReadType();
		if ( t != type )
			{
			FileError( "Expecting %s", typenames[ type ] );
			}
		}
	}

inline size_t Archiver::ReadSize
	(
	void
	)

	{
	size_t s;

	s = 0;
	if ( !fileerror )
		{
      readfile.Read( &s, sizeof( s ) );
		}

	return s;
	}

inline void Archiver::CheckSize
	(
	int type,
	size_t size
	)

	{
	size_t s;

	if ( !fileerror )
		{
		s = ReadSize();

		if ( size != s )
			{
			FileError( "Invalid data size of %d on %s.", s, typenames[ type ] );
			}
		}
	}

inline void Archiver::ReadData
	(
	int type,
	void *data,
	size_t size
	)

	{
	CheckRead();
	CheckType( type );
	CheckSize( type, size );

	if ( !fileerror && size )
		{
      readfile.Read( data, size );
		}
	}

#define READ( func, type )									\
type Archiver::Read##func									\
	(																\
	void															\
	)																\
																	\
	{																\
	type v;														\
																	\
	ReadData( ARC_##func, &v, sizeof( type ) );		\
																	\
	return v;													\
	}

	READ( Vector, Vector );
	READ( Integer, int );
	READ( Unsigned, unsigned );
	READ( Byte, byte );
	READ( Char, char );
	READ( Short, short );
	READ( UnsignedShort, unsigned short );
	READ( Float, float );
	READ( Double, double );
	READ( Boolean, qboolean );
	READ( Quat, Quat );

#define READPTR( func, type )								\
void Archiver::Read##func									\
	(																\
	type * v														\
	)																\
																	\
	{																\
	ReadData( ARC_##func, v, sizeof( type ) );		\
	}

	READPTR( Vector, Vector );
	READPTR( Integer, int );
	READPTR( Unsigned, unsigned );
	READPTR( Byte, byte );
	READPTR( Char, char );
	READPTR( Short, short );
	READPTR( UnsignedShort, unsigned short );
	READPTR( Float, float );
	READPTR( Double, double );
	READPTR( Boolean, qboolean );
	READPTR( Quat, Quat );

void Archiver::ReadObjectPointer
	(
   Class ** ptr

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -