mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-13 00:31:10 +02:00
1911 lines
38 KiB
C++
1911 lines
38 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
IceTech GPL Source Code
|
|
Copyright (C) 2026 Justin Marshall
|
|
|
|
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
|
|
|
|
IceTech Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
IceTech Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with IceTech Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#include "precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "Unzip.h"
|
|
|
|
#define MAX_PRINT_MSG 4096
|
|
|
|
#ifdef QUAKE4
|
|
#define FILE_SYNC_ID 518508557 // 0x1EE7D00D
|
|
#define ID_FILE_TIMESTAMP_TYPE unsigned int
|
|
#else
|
|
#define ID_FILE_TIMESTAMP_TYPE ID_TIME_T
|
|
#endif
|
|
|
|
|
|
/*
|
|
=================
|
|
FS_WriteFloatString
|
|
=================
|
|
*/
|
|
#ifdef QUAKE4
|
|
int FS_WriteFloatString( char *buf, int max, const char *fmt, va_list argPtr ) {
|
|
int i;
|
|
unsigned int u;
|
|
double f;
|
|
char *str;
|
|
int index;
|
|
idStr tmp, format;
|
|
|
|
index = 0;
|
|
|
|
while( *fmt && index < max ) {
|
|
switch( *fmt ) {
|
|
case '%':
|
|
format = "";
|
|
format += *fmt++;
|
|
while ( (*fmt >= '0' && *fmt <= '9') ||
|
|
*fmt == '.' || *fmt == '-' || *fmt == '+' || *fmt == '#') {
|
|
format += *fmt++;
|
|
}
|
|
format += *fmt;
|
|
switch( *fmt ) {
|
|
case 'f':
|
|
case 'e':
|
|
case 'E':
|
|
case 'g':
|
|
case 'G':
|
|
f = va_arg( argPtr, double );
|
|
if ( format.Length() <= 2 ) {
|
|
// high precision floating point number without trailing zeros
|
|
sprintf( tmp, "%1.10f", f );
|
|
tmp.StripTrailing( '0' );
|
|
tmp.StripTrailing( '.' );
|
|
index += idStr::snPrintf( buf + index, max - index, "%s", tmp.c_str() );
|
|
}
|
|
else {
|
|
index += idStr::snPrintf( buf + index, max - index, format.c_str(), f );
|
|
}
|
|
break;
|
|
case 'd':
|
|
case 'i':
|
|
i = va_arg( argPtr, int );
|
|
index += idStr::snPrintf( buf + index, max - index, format.c_str(), i );
|
|
break;
|
|
case 'u':
|
|
u = va_arg( argPtr, unsigned int );
|
|
index += idStr::snPrintf( buf + index, max - index, format.c_str(), u );
|
|
break;
|
|
case 'o':
|
|
u = va_arg( argPtr, unsigned int );
|
|
index += idStr::snPrintf( buf + index, max - index, format.c_str(), u );
|
|
break;
|
|
case 'x':
|
|
u = va_arg( argPtr, unsigned int );
|
|
index += idStr::snPrintf( buf + index, max - index, format.c_str(), u );
|
|
break;
|
|
case 'X':
|
|
u = va_arg( argPtr, unsigned int );
|
|
index += idStr::snPrintf( buf + index, max - index, format.c_str(), u );
|
|
break;
|
|
case 'c':
|
|
i = va_arg( argPtr, int );
|
|
index += idStr::snPrintf( buf + index, max - index, format.c_str(), (char) i );
|
|
break;
|
|
case 's':
|
|
str = va_arg( argPtr, char * );
|
|
index += idStr::snPrintf( buf + index, max - index, format.c_str(), str );
|
|
break;
|
|
case '%':
|
|
index += idStr::snPrintf( buf + index, max - index, format.c_str() );
|
|
break;
|
|
default:
|
|
common->Error( "FS_WriteFloatString: invalid format %s", format.c_str() );
|
|
break;
|
|
}
|
|
fmt++;
|
|
break;
|
|
case '\\':
|
|
fmt++;
|
|
switch( *fmt ) {
|
|
case 't':
|
|
index += idStr::snPrintf( buf + index, max - index, "\t" );
|
|
break;
|
|
case 'v':
|
|
index += idStr::snPrintf( buf + index, max - index, "\v" );
|
|
break;
|
|
case 'n':
|
|
index += idStr::snPrintf( buf + index, max - index, "\n" );
|
|
break;
|
|
case '\\':
|
|
index += idStr::snPrintf( buf + index, max - index, "\\" );
|
|
break;
|
|
default:
|
|
common->Error( "FS_WriteFloatString: unknown escape character \'%c\'", *fmt );
|
|
break;
|
|
}
|
|
fmt++;
|
|
break;
|
|
default:
|
|
index += idStr::snPrintf( buf + index, max - index, "%c", *fmt );
|
|
fmt++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return index;
|
|
}
|
|
#else
|
|
int FS_WriteFloatString( char *buf, const char *fmt, va_list argPtr ) {
|
|
long i;
|
|
unsigned long u;
|
|
double f;
|
|
char *str;
|
|
int index;
|
|
idStr tmp, format;
|
|
|
|
index = 0;
|
|
|
|
while( *fmt ) {
|
|
switch( *fmt ) {
|
|
case '%':
|
|
format = "";
|
|
format += *fmt++;
|
|
while ( (*fmt >= '0' && *fmt <= '9') ||
|
|
*fmt == '.' || *fmt == '-' || *fmt == '+' || *fmt == '#') {
|
|
format += *fmt++;
|
|
}
|
|
format += *fmt;
|
|
switch( *fmt ) {
|
|
case 'f':
|
|
case 'e':
|
|
case 'E':
|
|
case 'g':
|
|
case 'G':
|
|
f = va_arg( argPtr, double );
|
|
if ( format.Length() <= 2 ) {
|
|
// high precision floating point number without trailing zeros
|
|
sprintf( tmp, "%1.10f", f );
|
|
tmp.StripTrailing( '0' );
|
|
tmp.StripTrailing( '.' );
|
|
index += sprintf( buf+index, "%s", tmp.c_str() );
|
|
}
|
|
else {
|
|
index += sprintf( buf+index, format.c_str(), f );
|
|
}
|
|
break;
|
|
case 'd':
|
|
case 'i':
|
|
i = va_arg( argPtr, long );
|
|
index += sprintf( buf+index, format.c_str(), i );
|
|
break;
|
|
case 'u':
|
|
u = va_arg( argPtr, unsigned long );
|
|
index += sprintf( buf+index, format.c_str(), u );
|
|
break;
|
|
case 'o':
|
|
u = va_arg( argPtr, unsigned long );
|
|
index += sprintf( buf+index, format.c_str(), u );
|
|
break;
|
|
case 'x':
|
|
u = va_arg( argPtr, unsigned long );
|
|
index += sprintf( buf+index, format.c_str(), u );
|
|
break;
|
|
case 'X':
|
|
u = va_arg( argPtr, unsigned long );
|
|
index += sprintf( buf+index, format.c_str(), u );
|
|
break;
|
|
case 'c':
|
|
i = va_arg( argPtr, long );
|
|
index += sprintf( buf+index, format.c_str(), (char) i );
|
|
break;
|
|
case 's':
|
|
str = va_arg( argPtr, char * );
|
|
index += sprintf( buf+index, format.c_str(), str );
|
|
break;
|
|
case '%':
|
|
index += sprintf( buf+index, format.c_str() );
|
|
break;
|
|
default:
|
|
common->Error( "FS_WriteFloatString: invalid format %s", format.c_str() );
|
|
break;
|
|
}
|
|
fmt++;
|
|
break;
|
|
case '\\':
|
|
fmt++;
|
|
switch( *fmt ) {
|
|
case 't':
|
|
index += sprintf( buf+index, "\t" );
|
|
break;
|
|
case 'v':
|
|
index += sprintf( buf+index, "\v" );
|
|
break;
|
|
case 'n':
|
|
index += sprintf( buf+index, "\n" );
|
|
break;
|
|
case '\\':
|
|
index += sprintf( buf+index, "\\" );
|
|
break;
|
|
default:
|
|
common->Error( "FS_WriteFloatString: unknown escape character \'%c\'", *fmt );
|
|
break;
|
|
}
|
|
fmt++;
|
|
break;
|
|
default:
|
|
index += sprintf( buf+index, "%c", *fmt );
|
|
fmt++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return index;
|
|
}
|
|
#endif
|
|
|
|
#ifdef QUAKE4
|
|
#define IDFILE_COMMON idFile_Common
|
|
#else
|
|
#define IDFILE_COMMON idFile
|
|
#endif
|
|
|
|
/*
|
|
=================================================================================
|
|
|
|
idFile
|
|
|
|
=================================================================================
|
|
*/
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::GetName
|
|
=================
|
|
*/
|
|
const char *IDFILE_COMMON::GetName( void ) {
|
|
return "";
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::GetFullPath
|
|
=================
|
|
*/
|
|
const char *IDFILE_COMMON::GetFullPath( void ) {
|
|
return "";
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::Read
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::Read( void *buffer, int len ) {
|
|
#ifdef QUAKE4
|
|
common->FatalError( "idFile_Common::Read: cannot read from idFile_Common" );
|
|
#else
|
|
common->FatalError( "idFile::Read: cannot read from idFile" );
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::Write
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::Write( const void *buffer, int len ) {
|
|
#ifdef QUAKE4
|
|
common->FatalError( "idFile_Common::Write: cannot write to idFile_Common" );
|
|
#else
|
|
common->FatalError( "idFile::Write: cannot write to idFile" );
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::Length
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::Length( void ) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::Timestamp
|
|
=================
|
|
*/
|
|
ID_FILE_TIMESTAMP_TYPE IDFILE_COMMON::Timestamp( void ) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::Tell
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::Tell( void ) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ForceFlush
|
|
=================
|
|
*/
|
|
void IDFILE_COMMON::ForceFlush( void ) {
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::Flush
|
|
=================
|
|
*/
|
|
void IDFILE_COMMON::Flush( void ) {
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::Seek
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::Seek( long offset, fsOrigin_t origin ) {
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::Rewind
|
|
=================
|
|
*/
|
|
void IDFILE_COMMON::Rewind( void ) {
|
|
Seek( 0, FS_SEEK_SET );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::Printf
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::Printf( const char *fmt, ... ) {
|
|
char buf[MAX_PRINT_MSG];
|
|
int length;
|
|
va_list argptr;
|
|
|
|
va_start( argptr, fmt );
|
|
length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, argptr );
|
|
va_end( argptr );
|
|
|
|
// so notepad formats the lines correctly
|
|
idStr work( buf );
|
|
work.Replace( "\n", "\r\n" );
|
|
|
|
return Write( work.c_str(), work.Length() );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::VPrintf
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::VPrintf( const char *fmt, va_list args ) {
|
|
char buf[MAX_PRINT_MSG];
|
|
int length;
|
|
|
|
length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, args );
|
|
return Write( buf, length );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteFloatString
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteFloatString( const char *fmt, ... ) {
|
|
char buf[MAX_PRINT_MSG];
|
|
int len;
|
|
va_list argPtr;
|
|
|
|
va_start( argPtr, fmt );
|
|
#ifdef QUAKE4
|
|
len = FS_WriteFloatString( buf, sizeof( buf ), fmt, argPtr );
|
|
#else
|
|
len = FS_WriteFloatString( buf, fmt, argPtr );
|
|
#endif
|
|
va_end( argPtr );
|
|
|
|
return Write( buf, len );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadInt
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadInt( int &value ) {
|
|
int result = Read( &value, sizeof( value ) );
|
|
value = LittleLong(value);
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadUnsignedInt
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadUnsignedInt( unsigned int &value ) {
|
|
int result = Read( &value, sizeof( value ) );
|
|
value = LittleLong(value);
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadShort
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadShort( short &value ) {
|
|
int result = Read( &value, sizeof( value ) );
|
|
value = LittleShort(value);
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadUnsignedShort
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadUnsignedShort( unsigned short &value ) {
|
|
int result = Read( &value, sizeof( value ) );
|
|
value = LittleShort(value);
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadChar
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadChar( char &value ) {
|
|
return Read( &value, sizeof( value ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadUnsignedChar
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadUnsignedChar( unsigned char &value ) {
|
|
return Read( &value, sizeof( value ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadFloat
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadFloat( float &value ) {
|
|
int result = Read( &value, sizeof( value ) );
|
|
value = LittleFloat(value);
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadBool
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadBool( bool &value ) {
|
|
unsigned char c;
|
|
int result = ReadUnsignedChar( c );
|
|
value = c ? true : false;
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadString
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadString( idStr &string ) {
|
|
int len;
|
|
int result = 0;
|
|
|
|
ReadInt( len );
|
|
if ( len >= 0 ) {
|
|
string.Fill( ' ', len );
|
|
result = Read( &string[ 0 ], len );
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadVec2
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadVec2( idVec2 &vec ) {
|
|
int result = Read( &vec, sizeof( vec ) );
|
|
LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadVec3
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadVec3( idVec3 &vec ) {
|
|
int result = Read( &vec, sizeof( vec ) );
|
|
LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadVec4
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadVec4( idVec4 &vec ) {
|
|
int result = Read( &vec, sizeof( vec ) );
|
|
LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
|
|
return result;
|
|
}
|
|
|
|
#ifdef QUAKE4
|
|
/*
|
|
=================
|
|
idFile_Common::ReadVec5
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadVec5( idVec5 &vec ) {
|
|
int result = Read( &vec, sizeof( vec ) );
|
|
LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadVec6
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadVec6( idVec6 &vec ) {
|
|
int result = Read( &vec, sizeof( vec ) );
|
|
LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::ReadMat3
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadMat3( idMat3 &mat ) {
|
|
int result = Read( &mat, sizeof( mat ) );
|
|
LittleRevBytes( &mat, sizeof(float), sizeof(mat)/sizeof(float) );
|
|
return result;
|
|
}
|
|
|
|
#ifdef QUAKE4
|
|
/*
|
|
=================
|
|
idFile_Common::ReadBounds
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::ReadBounds( idBounds &bounds ) {
|
|
int result = Read( &bounds, sizeof( bounds ) );
|
|
LittleRevBytes( &bounds, sizeof(float), sizeof(bounds)/sizeof(float) );
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteInt
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteInt( const int value ) {
|
|
int v = LittleLong(value);
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteUnsignedInt
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteUnsignedInt( const unsigned int value ) {
|
|
unsigned int v = LittleLong(value);
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteShort
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteShort( const short value ) {
|
|
short v = LittleShort(value);
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteUnsignedShort
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteUnsignedShort( const unsigned short value ) {
|
|
unsigned short v = LittleShort(value);
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteChar
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteChar( const char value ) {
|
|
return Write( &value, sizeof( value ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteUnsignedChar
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteUnsignedChar( const unsigned char value ) {
|
|
return Write( &value, sizeof( value ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteFloat
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteFloat( const float value ) {
|
|
float v = LittleFloat(value);
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteBool
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteBool( const bool value ) {
|
|
unsigned char c = value;
|
|
return WriteUnsignedChar( c );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteString
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteString( const char *value ) {
|
|
int len;
|
|
|
|
len = strlen( value );
|
|
WriteInt( len );
|
|
return Write( value, len );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteVec2
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteVec2( const idVec2 &vec ) {
|
|
idVec2 v = vec;
|
|
LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteVec3
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteVec3( const idVec3 &vec ) {
|
|
idVec3 v = vec;
|
|
LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteVec4
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteVec4( const idVec4 &vec ) {
|
|
idVec4 v = vec;
|
|
LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
#ifdef QUAKE4
|
|
/*
|
|
=================
|
|
idFile_Common::WriteVec5
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteVec5( const idVec5 &vec ) {
|
|
idVec5 v = vec;
|
|
LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteVec6
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteVec6( const idVec6 &vec ) {
|
|
idVec6 v = vec;
|
|
LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
IDFILE_COMMON::WriteMat3
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteMat3( const idMat3 &mat ) {
|
|
idMat3 v = mat;
|
|
LittleRevBytes(&v, sizeof(float), sizeof(v)/sizeof(float) );
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
#ifdef QUAKE4
|
|
/*
|
|
=================
|
|
idFile_Common::WriteBounds
|
|
=================
|
|
*/
|
|
int IDFILE_COMMON::WriteBounds( const idBounds &bounds ) {
|
|
idBounds v = bounds;
|
|
LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
|
|
return Write( &v, sizeof( v ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Common::WriteNumericStructArray
|
|
=================
|
|
*/
|
|
void IDFILE_COMMON::WriteNumericStructArray( int numStructElements, int tokenSubTypeStructElements[], int arrayCount, byte *arrayStorage, const char *prepend ) {
|
|
for ( int arrayIndex = 0; arrayIndex < arrayCount; arrayIndex++ ) {
|
|
WriteFloatString( prepend );
|
|
for ( int elementIndex = 0; elementIndex < numStructElements; elementIndex++, arrayStorage += sizeof( int ) ) {
|
|
if ( (signed char) tokenSubTypeStructElements[ elementIndex ] >= 0 ) {
|
|
WriteFloatString( "%u ", *(unsigned int *)arrayStorage );
|
|
} else {
|
|
WriteFloatString( "%f ", *(float *)arrayStorage );
|
|
}
|
|
}
|
|
WriteFloatString( "\n" );
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Common::WriteSyncId
|
|
=================
|
|
*/
|
|
void IDFILE_COMMON::WriteSyncId( void ) {
|
|
WriteInt( FILE_SYNC_ID );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Common::ReadSyncId
|
|
=================
|
|
*/
|
|
void IDFILE_COMMON::ReadSyncId( const char *detail, const char *classname ) {
|
|
int num;
|
|
|
|
ReadInt( num );
|
|
if ( num != FILE_SYNC_ID ) {
|
|
if ( classname ) {
|
|
common->Error( "File synchronisation problem: %s in class %s", detail, classname );
|
|
} else {
|
|
common->Error( "File synchronisation problem: %s", detail );
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
#undef IDFILE_COMMON
|
|
|
|
/*
|
|
=================================================================================
|
|
|
|
idFile_Memory
|
|
|
|
=================================================================================
|
|
*/
|
|
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::idFile_Memory
|
|
=================
|
|
*/
|
|
idFile_Memory::idFile_Memory( void ) {
|
|
name = "*unknown*";
|
|
maxSize = 0;
|
|
fileSize = 0;
|
|
allocated = 0;
|
|
granularity = 16384;
|
|
|
|
mode = ( 1 << FS_WRITE );
|
|
filePtr = NULL;
|
|
curPtr = NULL;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::idFile_Memory
|
|
=================
|
|
*/
|
|
idFile_Memory::idFile_Memory( const char *name ) {
|
|
this->name = name;
|
|
maxSize = 0;
|
|
fileSize = 0;
|
|
allocated = 0;
|
|
granularity = 16384;
|
|
|
|
mode = ( 1 << FS_WRITE );
|
|
filePtr = NULL;
|
|
curPtr = NULL;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::idFile_Memory
|
|
=================
|
|
*/
|
|
idFile_Memory::idFile_Memory( const char *name, char *data, int length ) {
|
|
this->name = name;
|
|
maxSize = length;
|
|
fileSize = 0;
|
|
allocated = length;
|
|
granularity = 16384;
|
|
|
|
mode = ( 1 << FS_WRITE );
|
|
filePtr = data;
|
|
curPtr = data;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::idFile_Memory
|
|
=================
|
|
*/
|
|
idFile_Memory::idFile_Memory( const char *name, const char *data, int length ) {
|
|
this->name = name;
|
|
maxSize = 0;
|
|
fileSize = length;
|
|
allocated = 0;
|
|
granularity = 16384;
|
|
|
|
mode = ( 1 << FS_READ );
|
|
filePtr = const_cast<char *>(data);
|
|
curPtr = const_cast<char *>(data);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::~idFile_Memory
|
|
=================
|
|
*/
|
|
idFile_Memory::~idFile_Memory( void ) {
|
|
if ( filePtr && allocated > 0 && maxSize == 0 ) {
|
|
Mem_Free( filePtr );
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::Read
|
|
=================
|
|
*/
|
|
int idFile_Memory::Read( void *buffer, int len ) {
|
|
|
|
if ( !( mode & ( 1 << FS_READ ) ) ) {
|
|
common->FatalError( "idFile_Memory::Read: %s not opened in read mode", name.c_str() );
|
|
return 0;
|
|
}
|
|
|
|
if ( curPtr + len > filePtr + fileSize ) {
|
|
len = filePtr + fileSize - curPtr;
|
|
}
|
|
#ifdef QUAKE4
|
|
SIMDProcessor->Memcpy( buffer, curPtr, len );
|
|
#else
|
|
memcpy( buffer, curPtr, len );
|
|
#endif
|
|
curPtr += len;
|
|
return len;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::Write
|
|
=================
|
|
*/
|
|
int idFile_Memory::Write( const void *buffer, int len ) {
|
|
|
|
if ( !( mode & ( 1 << FS_WRITE ) ) ) {
|
|
common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() );
|
|
return 0;
|
|
}
|
|
|
|
int alloc = curPtr + len + 1 - filePtr - allocated; // need room for len+1
|
|
if ( alloc > 0 ) {
|
|
if ( maxSize != 0 ) {
|
|
common->Error( "idFile_Memory::Write: exceeded maximum size %d", maxSize );
|
|
return 0;
|
|
}
|
|
int extra = granularity * ( 1 + alloc / granularity );
|
|
#ifdef QUAKE4
|
|
char *newPtr = (char *) Mem_Alloc( allocated + extra );
|
|
#else
|
|
char *newPtr = (char *) Mem_Alloc( allocated + extra );
|
|
#endif
|
|
if ( allocated ) {
|
|
#ifdef QUAKE4
|
|
SIMDProcessor->Memcpy( newPtr, filePtr, allocated );
|
|
#else
|
|
memcpy( newPtr, filePtr, allocated );
|
|
#endif
|
|
}
|
|
allocated += extra;
|
|
curPtr = newPtr + ( curPtr - filePtr );
|
|
if ( filePtr ) {
|
|
Mem_Free( filePtr );
|
|
}
|
|
filePtr = newPtr;
|
|
}
|
|
#ifdef QUAKE4
|
|
SIMDProcessor->Memcpy( curPtr, buffer, len );
|
|
#else
|
|
memcpy( curPtr, buffer, len );
|
|
#endif
|
|
curPtr += len;
|
|
fileSize += len;
|
|
filePtr[ fileSize ] = 0; // len + 1
|
|
return len;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::Length
|
|
=================
|
|
*/
|
|
int idFile_Memory::Length( void ) {
|
|
return fileSize;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::Timestamp
|
|
=================
|
|
*/
|
|
ID_FILE_TIMESTAMP_TYPE idFile_Memory::Timestamp( void ) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::Tell
|
|
=================
|
|
*/
|
|
int idFile_Memory::Tell( void ) {
|
|
return ( curPtr - filePtr );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::ForceFlush
|
|
=================
|
|
*/
|
|
void idFile_Memory::ForceFlush( void ) {
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::Flush
|
|
=================
|
|
*/
|
|
void idFile_Memory::Flush( void ) {
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::Seek
|
|
|
|
returns zero on success and -1 on failure
|
|
=================
|
|
*/
|
|
int idFile_Memory::Seek( long offset, fsOrigin_t origin ) {
|
|
|
|
switch( origin ) {
|
|
case FS_SEEK_CUR: {
|
|
curPtr += offset;
|
|
break;
|
|
}
|
|
case FS_SEEK_END: {
|
|
curPtr = filePtr + fileSize - offset;
|
|
break;
|
|
}
|
|
case FS_SEEK_SET: {
|
|
curPtr = filePtr + offset;
|
|
break;
|
|
}
|
|
default: {
|
|
common->FatalError( "idFile_Memory::Seek: bad origin for %s\n", name.c_str() );
|
|
return -1;
|
|
}
|
|
}
|
|
if ( curPtr < filePtr ) {
|
|
curPtr = filePtr;
|
|
return -1;
|
|
}
|
|
if ( curPtr > filePtr + fileSize ) {
|
|
curPtr = filePtr + fileSize;
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
#ifdef QUAKE4
|
|
/*
|
|
=================
|
|
idFile_Memory::Rewind
|
|
=================
|
|
*/
|
|
void idFile_Memory::Rewind( void ) {
|
|
mode = ( 1 << FS_READ );
|
|
Seek( 0, FS_SEEK_SET );
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::MakeReadOnly
|
|
=================
|
|
*/
|
|
void idFile_Memory::MakeReadOnly( void ) {
|
|
mode = ( 1 << FS_READ );
|
|
Rewind();
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::Clear
|
|
=================
|
|
*/
|
|
void idFile_Memory::Clear( bool freeMemory ) {
|
|
fileSize = 0;
|
|
granularity = 16384;
|
|
if ( freeMemory ) {
|
|
allocated = 0;
|
|
Mem_Free( filePtr );
|
|
filePtr = NULL;
|
|
curPtr = NULL;
|
|
} else {
|
|
curPtr = filePtr;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Memory::SetData
|
|
=================
|
|
*/
|
|
void idFile_Memory::SetData( const char *data, int length ) {
|
|
maxSize = 0;
|
|
fileSize = length;
|
|
allocated = 0;
|
|
granularity = 16384;
|
|
|
|
mode = ( 1 << FS_READ );
|
|
filePtr = const_cast<char *>(data);
|
|
curPtr = const_cast<char *>(data);
|
|
}
|
|
|
|
|
|
/*
|
|
=================================================================================
|
|
|
|
idFile_BitMsg
|
|
|
|
=================================================================================
|
|
*/
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::idFile_BitMsg
|
|
=================
|
|
*/
|
|
idFile_BitMsg::idFile_BitMsg( idBitMsg &msg ) {
|
|
name = "*unknown*";
|
|
mode = ( 1 << FS_WRITE );
|
|
this->msg = &msg;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::idFile_BitMsg
|
|
=================
|
|
*/
|
|
idFile_BitMsg::idFile_BitMsg( const idBitMsg &msg ) {
|
|
name = "*unknown*";
|
|
mode = ( 1 << FS_READ );
|
|
this->msg = const_cast<idBitMsg *>(&msg);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::~idFile_BitMsg
|
|
=================
|
|
*/
|
|
idFile_BitMsg::~idFile_BitMsg( void ) {
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::Read
|
|
=================
|
|
*/
|
|
int idFile_BitMsg::Read( void *buffer, int len ) {
|
|
|
|
if ( !( mode & ( 1 << FS_READ ) ) ) {
|
|
common->FatalError( "idFile_BitMsg::Read: %s not opened in read mode", name.c_str() );
|
|
return 0;
|
|
}
|
|
|
|
return msg->ReadData( buffer, len );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::Write
|
|
=================
|
|
*/
|
|
int idFile_BitMsg::Write( const void *buffer, int len ) {
|
|
|
|
if ( !( mode & ( 1 << FS_WRITE ) ) ) {
|
|
common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() );
|
|
return 0;
|
|
}
|
|
|
|
msg->WriteData( buffer, len );
|
|
return len;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::Length
|
|
=================
|
|
*/
|
|
int idFile_BitMsg::Length( void ) {
|
|
return msg->GetSize();
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::Timestamp
|
|
=================
|
|
*/
|
|
ID_FILE_TIMESTAMP_TYPE idFile_BitMsg::Timestamp( void ) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::Tell
|
|
=================
|
|
*/
|
|
int idFile_BitMsg::Tell( void ) {
|
|
#ifdef QUAKE4
|
|
if ( mode & ( 1 << FS_READ ) ) {
|
|
#else
|
|
if ( mode & FS_READ ) {
|
|
#endif
|
|
return msg->GetReadCount();
|
|
} else {
|
|
return msg->GetSize();
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::ForceFlush
|
|
=================
|
|
*/
|
|
void idFile_BitMsg::ForceFlush( void ) {
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::Flush
|
|
=================
|
|
*/
|
|
void idFile_BitMsg::Flush( void ) {
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_BitMsg::Seek
|
|
|
|
returns zero on success and -1 on failure
|
|
=================
|
|
*/
|
|
int idFile_BitMsg::Seek( long offset, fsOrigin_t origin ) {
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
=================================================================================
|
|
|
|
idFile_Permanent
|
|
|
|
=================================================================================
|
|
*/
|
|
|
|
/*
|
|
=================
|
|
idFile_Permanent::idFile_Permanent
|
|
=================
|
|
*/
|
|
idFile_Permanent::idFile_Permanent( void ) {
|
|
name = "invalid";
|
|
o = NULL;
|
|
mode = 0;
|
|
fileSize = 0;
|
|
handleSync = false;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Permanent::~idFile_Permanent
|
|
=================
|
|
*/
|
|
idFile_Permanent::~idFile_Permanent( void ) {
|
|
if ( o ) {
|
|
#ifdef QUAKE4
|
|
sys->FClose( o );
|
|
#else
|
|
fclose( o );
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Permanent::Read
|
|
|
|
Properly handles partial reads
|
|
=================
|
|
*/
|
|
int idFile_Permanent::Read( void *buffer, int len ) {
|
|
int block, remaining;
|
|
int read;
|
|
byte * buf;
|
|
int tries;
|
|
|
|
if ( !(mode & ( 1 << FS_READ ) ) ) {
|
|
common->FatalError( "idFile_Permanent::Read: %s not opened in read mode", name.c_str() );
|
|
return 0;
|
|
}
|
|
|
|
if ( !o ) {
|
|
return 0;
|
|
}
|
|
|
|
buf = (byte *)buffer;
|
|
|
|
remaining = len;
|
|
tries = 0;
|
|
while( remaining ) {
|
|
block = remaining;
|
|
#ifdef QUAKE4
|
|
read = sys->FRead( buf, 1, block, o );
|
|
#else
|
|
read = fread( buf, 1, block, o );
|
|
#endif
|
|
if ( read == 0 ) {
|
|
// we might have been trying to read from a CD, which
|
|
// sometimes returns a 0 read on windows
|
|
if ( !tries ) {
|
|
tries = 1;
|
|
}
|
|
else {
|
|
fileSystem->AddToReadCount( len - remaining );
|
|
return len-remaining;
|
|
}
|
|
}
|
|
|
|
if ( read == -1 ) {
|
|
common->FatalError( "idFile_Permanent::Read: -1 bytes read from %s", name.c_str() );
|
|
}
|
|
|
|
remaining -= read;
|
|
buf += read;
|
|
}
|
|
fileSystem->AddToReadCount( len );
|
|
return len;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Permanent::Write
|
|
|
|
Properly handles partial writes
|
|
=================
|
|
*/
|
|
int idFile_Permanent::Write( const void *buffer, int len ) {
|
|
int block, remaining;
|
|
int written;
|
|
byte * buf;
|
|
int tries;
|
|
|
|
if ( !( mode & ( 1 << FS_WRITE ) ) ) {
|
|
common->FatalError( "idFile_Permanent::Write: %s not opened in write mode", name.c_str() );
|
|
return 0;
|
|
}
|
|
|
|
if ( !o ) {
|
|
return 0;
|
|
}
|
|
|
|
buf = (byte *)buffer;
|
|
|
|
remaining = len;
|
|
tries = 0;
|
|
while( remaining ) {
|
|
block = remaining;
|
|
#ifdef QUAKE4
|
|
written = sys->FWrite( buf, 1, block, o );
|
|
#else
|
|
written = fwrite( buf, 1, block, o );
|
|
#endif
|
|
if ( written == 0 ) {
|
|
if ( !tries ) {
|
|
tries = 1;
|
|
}
|
|
else {
|
|
common->Printf( "idFile_Permanent::Write: 0 bytes written to %s\n", name.c_str() );
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if ( written == -1 ) {
|
|
common->Printf( "idFile_Permanent::Write: -1 bytes written to %s\n", name.c_str() );
|
|
return 0;
|
|
}
|
|
|
|
remaining -= written;
|
|
buf += written;
|
|
fileSize += written;
|
|
}
|
|
if ( handleSync ) {
|
|
#ifdef QUAKE4
|
|
sys->FFlush( o );
|
|
#else
|
|
fflush( o );
|
|
#endif
|
|
}
|
|
return len;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Permanent::ForceFlush
|
|
=================
|
|
*/
|
|
void idFile_Permanent::ForceFlush( void ) {
|
|
#ifdef QUAKE4
|
|
sys->SetVBuf( o, NULL, _IONBF, 0 );
|
|
#else
|
|
setvbuf( o, NULL, _IONBF, 0 );
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Permanent::Flush
|
|
=================
|
|
*/
|
|
void idFile_Permanent::Flush( void ) {
|
|
#ifdef QUAKE4
|
|
sys->FFlush( o );
|
|
#else
|
|
fflush( o );
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Permanent::Tell
|
|
=================
|
|
*/
|
|
int idFile_Permanent::Tell( void ) {
|
|
#ifdef QUAKE4
|
|
return sys->FTell( o );
|
|
#else
|
|
return ftell( o );
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
================
|
|
idFile_Permanent::Length
|
|
================
|
|
*/
|
|
int idFile_Permanent::Length( void ) {
|
|
return fileSize;
|
|
}
|
|
|
|
/*
|
|
================
|
|
idFile_Permanent::Timestamp
|
|
================
|
|
*/
|
|
ID_FILE_TIMESTAMP_TYPE idFile_Permanent::Timestamp( void ) {
|
|
#ifdef QUAKE4
|
|
return sys->FileTimeStamp( o );
|
|
#else
|
|
return Sys_FileTimeStamp( o );
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_Permanent::Seek
|
|
|
|
returns zero on success and -1 on failure
|
|
=================
|
|
*/
|
|
int idFile_Permanent::Seek( long offset, fsOrigin_t origin ) {
|
|
int _origin;
|
|
|
|
switch( origin ) {
|
|
case FS_SEEK_CUR: {
|
|
_origin = SEEK_CUR;
|
|
break;
|
|
}
|
|
case FS_SEEK_END: {
|
|
_origin = SEEK_END;
|
|
break;
|
|
}
|
|
case FS_SEEK_SET: {
|
|
_origin = SEEK_SET;
|
|
break;
|
|
}
|
|
default: {
|
|
_origin = SEEK_CUR;
|
|
common->FatalError( "idFile_Permanent::Seek: bad origin for %s\n", name.c_str() );
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifdef QUAKE4
|
|
return sys->FSeek( o, offset, _origin );
|
|
#else
|
|
return fseek( o, offset, _origin );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
#ifdef QUAKE4
|
|
|
|
/*
|
|
=================================================================================
|
|
|
|
idFile_ASCII
|
|
|
|
=================================================================================
|
|
*/
|
|
|
|
/*
|
|
=================
|
|
idFile_ASCII::idFile_ASCII
|
|
=================
|
|
*/
|
|
idFile_ASCII::idFile_ASCII( void ) {
|
|
inside = 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_ASCII::Read
|
|
=================
|
|
*/
|
|
int idFile_ASCII::Read( void *buffer, int len ) {
|
|
return idFile_Permanent::Read( buffer, len );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_ASCII::Write
|
|
=================
|
|
*/
|
|
int idFile_ASCII::Write( const void *buffer, int len ) {
|
|
const byte *buf;
|
|
|
|
if ( inside ) {
|
|
return idFile_Permanent::Write( buffer, len );
|
|
}
|
|
|
|
buf = (const byte *) buffer;
|
|
inside = 1;
|
|
WriteFloatString( "len=%d ", len );
|
|
for ( int i = 0; i < len; i++ ) {
|
|
WriteFloatString( "%02x", buf[ i ] );
|
|
}
|
|
WriteFloatString( "\r\n" );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::ReadInt( int &value ) {
|
|
return idFile_Common::ReadInt( value );
|
|
}
|
|
|
|
int idFile_ASCII::ReadUnsignedInt( unsigned int &value ) {
|
|
return idFile_Common::ReadUnsignedInt( value );
|
|
}
|
|
|
|
int idFile_ASCII::ReadShort( short &value ) {
|
|
return idFile_Common::ReadShort( value );
|
|
}
|
|
|
|
int idFile_ASCII::ReadUnsignedShort( unsigned short &value ) {
|
|
return idFile_Common::ReadUnsignedShort( value );
|
|
}
|
|
|
|
int idFile_ASCII::ReadChar( char &value ) {
|
|
return idFile_Common::ReadChar( value );
|
|
}
|
|
|
|
int idFile_ASCII::ReadUnsignedChar( unsigned char &value ) {
|
|
return idFile_Common::ReadUnsignedChar( value );
|
|
}
|
|
|
|
int idFile_ASCII::ReadFloat( float &value ) {
|
|
return idFile_Common::ReadFloat( value );
|
|
}
|
|
|
|
int idFile_ASCII::ReadBool( bool &value ) {
|
|
return idFile_Common::ReadBool( value );
|
|
}
|
|
|
|
int idFile_ASCII::ReadString( idStr &string ) {
|
|
return idFile_Common::ReadString( string );
|
|
}
|
|
|
|
int idFile_ASCII::ReadVec2( idVec2 &vec ) {
|
|
return idFile_Common::ReadVec2( vec );
|
|
}
|
|
|
|
int idFile_ASCII::ReadVec3( idVec3 &vec ) {
|
|
return idFile_Common::ReadVec3( vec );
|
|
}
|
|
|
|
int idFile_ASCII::ReadVec4( idVec4 &vec ) {
|
|
return idFile_Common::ReadVec4( vec );
|
|
}
|
|
|
|
int idFile_ASCII::ReadVec5( idVec5 &vec ) {
|
|
return idFile_Common::ReadVec5( vec );
|
|
}
|
|
|
|
int idFile_ASCII::ReadVec6( idVec6 &vec ) {
|
|
return idFile_Common::ReadVec6( vec );
|
|
}
|
|
|
|
int idFile_ASCII::ReadMat3( idMat3 &mat ) {
|
|
return idFile_Common::ReadMat3( mat );
|
|
}
|
|
|
|
int idFile_ASCII::WriteInt( const int value ) {
|
|
inside++;
|
|
WriteFloatString( "Integer: %d\r\n", value );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteUnsignedInt( const unsigned int value ) {
|
|
inside++;
|
|
WriteFloatString( "Unsigned: %u\r\n", value );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteShort( const short value ) {
|
|
inside++;
|
|
WriteFloatString( "Short: %d\r\n", value );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteUnsignedShort( unsigned short value ) {
|
|
inside++;
|
|
WriteFloatString( "Unsigned Short: %u\r\n", value );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteChar( const char value ) {
|
|
inside++;
|
|
WriteFloatString( "Char: %d\r\n", value );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteUnsignedChar( const unsigned char value ) {
|
|
inside++;
|
|
WriteFloatString( "Byte: %u\r\n", value );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteFloat( const float value ) {
|
|
inside++;
|
|
WriteFloatString( "Float: %f\r\n", value );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteBool( const bool value ) {
|
|
inside++;
|
|
WriteFloatString( "Bool: %s\r\n", value ? "true" : "false" );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteString( const char *string ) {
|
|
inside++;
|
|
WriteFloatString( "String: len=%d %s\r\n", (int) strlen( string ), string );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteVec2( const idVec2 &vec ) {
|
|
inside++;
|
|
WriteFloatString( "Vec2: %f %f\r\n", vec.x, vec.y );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteVec3( const idVec3 &vec ) {
|
|
inside++;
|
|
WriteFloatString( "Vec3: %f %f %f\r\n", vec.x, vec.y, vec.z );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteVec4( const idVec4 &vec ) {
|
|
inside++;
|
|
WriteFloatString( "Vec4: %f %f %f %f\r\n", vec.x, vec.y, vec.z, vec.w );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteVec5( const idVec5 &vec ) {
|
|
inside++;
|
|
WriteFloatString( "Vec5: %f %f %f %f %f\r\n", vec.x, vec.y, vec.z, vec.s, vec.t );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteVec6( const idVec6 &vec ) {
|
|
inside++;
|
|
WriteFloatString( "Vec6: %f %f %f %f %f %f\r\n", vec[0], vec[1], vec[2], vec[3], vec[4], vec[5] );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
int idFile_ASCII::WriteMat3( const idMat3 &mat ) {
|
|
inside++;
|
|
WriteFloatString( "Mat3: ( %f %f %f ) ( %f %f %f ) ( %f %f %f )\r\n",
|
|
mat[0].x, mat[0].y, mat[0].z,
|
|
mat[1].x, mat[1].y, mat[1].z,
|
|
mat[2].x, mat[2].y, mat[2].z );
|
|
inside--;
|
|
return 0;
|
|
}
|
|
|
|
void idFile_ASCII::WriteNumericStructArray( int numStructElements, int tokenSubTypeStructElements[], int arrayCount, byte *arrayStorage, const char *prepend ) {
|
|
}
|
|
|
|
void idFile_ASCII::WriteSyncId( void ) {
|
|
inside++;
|
|
WriteFloatString( "==========\r\n" );
|
|
inside--;
|
|
}
|
|
|
|
void idFile_ASCII::ReadSyncId( const char *detail, const char *classname ) {
|
|
idFile_Common::ReadSyncId( detail, classname );
|
|
}
|
|
|
|
#endif /* QUAKE4 */
|
|
|
|
/*
|
|
=================================================================================
|
|
|
|
idFile_InZip
|
|
|
|
=================================================================================
|
|
*/
|
|
|
|
/*
|
|
=================
|
|
idFile_InZip::idFile_InZip
|
|
=================
|
|
*/
|
|
idFile_InZip::idFile_InZip( void ) {
|
|
name = "invalid";
|
|
zipFilePos = 0;
|
|
fileSize = 0;
|
|
memset( &z, 0, sizeof( z ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_InZip::~idFile_InZip
|
|
=================
|
|
*/
|
|
idFile_InZip::~idFile_InZip( void ) {
|
|
unzCloseCurrentFile( z );
|
|
unzClose( z );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_InZip::Read
|
|
|
|
Properly handles partial reads
|
|
=================
|
|
*/
|
|
int idFile_InZip::Read( void *buffer, int len ) {
|
|
int l = unzReadCurrentFile( z, buffer, len );
|
|
fileSystem->AddToReadCount( l );
|
|
return l;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_InZip::Write
|
|
=================
|
|
*/
|
|
int idFile_InZip::Write( const void *buffer, int len ) {
|
|
common->FatalError( "idFile_InZip::Write: cannot write to the zipped file %s", name.c_str() );
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_InZip::ForceFlush
|
|
=================
|
|
*/
|
|
void idFile_InZip::ForceFlush( void ) {
|
|
common->FatalError( "idFile_InZip::ForceFlush: cannot flush the zipped file %s", name.c_str() );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_InZip::Flush
|
|
=================
|
|
*/
|
|
void idFile_InZip::Flush( void ) {
|
|
common->FatalError( "idFile_InZip::Flush: cannot flush the zipped file %s", name.c_str() );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_InZip::Tell
|
|
=================
|
|
*/
|
|
int idFile_InZip::Tell( void ) {
|
|
return unztell( z );
|
|
}
|
|
|
|
/*
|
|
================
|
|
idFile_InZip::Length
|
|
================
|
|
*/
|
|
int idFile_InZip::Length( void ) {
|
|
return fileSize;
|
|
}
|
|
|
|
/*
|
|
================
|
|
idFile_InZip::Timestamp
|
|
================
|
|
*/
|
|
ID_FILE_TIMESTAMP_TYPE idFile_InZip::Timestamp( void ) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
idFile_InZip::Seek
|
|
|
|
returns zero on success and -1 on failure
|
|
=================
|
|
*/
|
|
#define ZIP_SEEK_BUF_SIZE (1<<15)
|
|
|
|
int idFile_InZip::Seek( long offset, fsOrigin_t origin ) {
|
|
int res, i;
|
|
char *buf;
|
|
|
|
switch( origin ) {
|
|
case FS_SEEK_END: {
|
|
offset = fileSize - offset;
|
|
}
|
|
case FS_SEEK_SET: {
|
|
// set the file position in the zip file (also sets the current file info)
|
|
unzSetCurrentFileInfoPosition( z, zipFilePos );
|
|
unzOpenCurrentFile( z );
|
|
if ( offset <= 0 ) {
|
|
return 0;
|
|
}
|
|
}
|
|
case FS_SEEK_CUR: {
|
|
buf = (char *) _alloca16( ZIP_SEEK_BUF_SIZE );
|
|
for ( i = 0; i < ( offset - ZIP_SEEK_BUF_SIZE ); i += ZIP_SEEK_BUF_SIZE ) {
|
|
res = unzReadCurrentFile( z, buf, ZIP_SEEK_BUF_SIZE );
|
|
if ( res < ZIP_SEEK_BUF_SIZE ) {
|
|
return -1;
|
|
}
|
|
}
|
|
res = i + unzReadCurrentFile( z, buf, offset - i );
|
|
return ( res == offset ) ? 0 : -1;
|
|
}
|
|
default: {
|
|
common->FatalError( "idFile_InZip::Seek: bad origin for %s\n", name.c_str() );
|
|
break;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
#undef ID_FILE_TIMESTAMP_TYPE
|
|
#ifdef QUAKE4
|
|
#undef FILE_SYNC_ID
|
|
#endif
|