Initial cFile implementation (using stdio FILE) and test in cChunkMap
git-svn-id: http://mc-server.googlecode.com/svn/trunk@192 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
96da48401b
commit
7e743398a9
@ -1442,6 +1442,14 @@
|
|||||||
RelativePath="..\source\cEvent.h"
|
RelativePath="..\source\cEvent.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\source\cFile.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\source\cFile.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\source\cSemaphore.cpp"
|
RelativePath="..\source\cSemaphore.cpp"
|
||||||
>
|
>
|
||||||
|
@ -318,6 +318,7 @@
|
|||||||
<ClCompile Include="..\source\cCuboid.cpp" />
|
<ClCompile Include="..\source\cCuboid.cpp" />
|
||||||
<ClCompile Include="..\source\cEnderman.cpp" />
|
<ClCompile Include="..\source\cEnderman.cpp" />
|
||||||
<ClCompile Include="..\source\cEvent.cpp" />
|
<ClCompile Include="..\source\cEvent.cpp" />
|
||||||
|
<ClCompile Include="..\source\cFile.cpp" />
|
||||||
<ClCompile Include="..\source\cFileFormatUpdater.cpp" />
|
<ClCompile Include="..\source\cFileFormatUpdater.cpp" />
|
||||||
<ClCompile Include="..\source\cFireSimulator.cpp" />
|
<ClCompile Include="..\source\cFireSimulator.cpp" />
|
||||||
<ClCompile Include="..\source\cFluidSimulator.cpp" />
|
<ClCompile Include="..\source\cFluidSimulator.cpp" />
|
||||||
@ -483,6 +484,7 @@
|
|||||||
<ClInclude Include="..\Source\cCriticalSection.h" />
|
<ClInclude Include="..\Source\cCriticalSection.h" />
|
||||||
<ClInclude Include="..\source\cEnderman.h" />
|
<ClInclude Include="..\source\cEnderman.h" />
|
||||||
<ClInclude Include="..\source\cEvent.h" />
|
<ClInclude Include="..\source\cEvent.h" />
|
||||||
|
<ClInclude Include="..\source\cFile.h" />
|
||||||
<ClInclude Include="..\source\cFileFormatUpdater.h" />
|
<ClInclude Include="..\source\cFileFormatUpdater.h" />
|
||||||
<ClInclude Include="..\source\cFireSimulator.h" />
|
<ClInclude Include="..\source\cFireSimulator.h" />
|
||||||
<ClInclude Include="..\source\cFluidSimulator.h" />
|
<ClInclude Include="..\source\cFluidSimulator.h" />
|
||||||
|
@ -908,6 +908,7 @@
|
|||||||
<Filter>cWebAdmin\cWebPlugin\cWebPlugin</Filter>
|
<Filter>cWebAdmin\cWebPlugin\cWebPlugin</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\source\Globals.cpp" />
|
<ClCompile Include="..\source\Globals.cpp" />
|
||||||
|
<ClCompile Include="..\source\cFile.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\source\cServer.h">
|
<ClInclude Include="..\source\cServer.h">
|
||||||
@ -1397,6 +1398,7 @@
|
|||||||
<Filter>cWebAdmin\cWebPlugin\cWebPlugin</Filter>
|
<Filter>cWebAdmin\cWebPlugin\cWebPlugin</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\source\Globals.h" />
|
<ClInclude Include="..\source\Globals.h" />
|
||||||
|
<ClInclude Include="..\source\cFile.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\source\AllToLua.pkg">
|
<None Include="..\source\AllToLua.pkg">
|
||||||
|
4
makefile
4
makefile
@ -84,6 +84,7 @@ MCServer : \
|
|||||||
build/cEntity.o\
|
build/cEntity.o\
|
||||||
build/cEvent.o\
|
build/cEvent.o\
|
||||||
build/cEvents.o\
|
build/cEvents.o\
|
||||||
|
build/cFile.o\
|
||||||
build/cFurnaceEntity.o\
|
build/cFurnaceEntity.o\
|
||||||
build/cFurnaceRecipe.o\
|
build/cFurnaceRecipe.o\
|
||||||
build/cFurnaceWindow.o\
|
build/cFurnaceWindow.o\
|
||||||
@ -293,6 +294,7 @@ MCServer : \
|
|||||||
build/cEntity.o\
|
build/cEntity.o\
|
||||||
build/cEvent.o\
|
build/cEvent.o\
|
||||||
build/cEvents.o\
|
build/cEvents.o\
|
||||||
|
build/cFile.o\
|
||||||
build/cFurnaceEntity.o\
|
build/cFurnaceEntity.o\
|
||||||
build/cFurnaceRecipe.o\
|
build/cFurnaceRecipe.o\
|
||||||
build/cFurnaceWindow.o\
|
build/cFurnaceWindow.o\
|
||||||
@ -1522,5 +1524,7 @@ build/cWebPlugin_Lua.o : source/cWebPlugin_Lua.cpp
|
|||||||
build/cEvents.o : webserver/cEvents.cpp
|
build/cEvents.o : webserver/cEvents.cpp
|
||||||
$(CC) $(CC_OPTIONS) webserver/cEvents.cpp -c $(INCLUDE) -o build/cEvents.o
|
$(CC) $(CC_OPTIONS) webserver/cEvents.cpp -c $(INCLUDE) -o build/cEvents.o
|
||||||
|
|
||||||
|
build/cFile.o : source/cFile.cpp
|
||||||
|
$(CC) $(CC_OPTIONS) source/cFile.cpp -c $(INCLUDE) -o build/cFile.o
|
||||||
|
|
||||||
##### END RUN ####
|
##### END RUN ####
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Move this into Globals.h after cFile has been finalized
|
||||||
|
#include "cFile.h"
|
||||||
|
|
||||||
|
|
||||||
#define USE_MEMCPY
|
#define USE_MEMCPY
|
||||||
|
|
||||||
#define LAYER_SIZE (32)
|
#define LAYER_SIZE (32)
|
||||||
@ -24,6 +29,28 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cChunkMap::cChunkLayer:
|
||||||
|
|
||||||
|
cChunkMap::cChunkData* cChunkMap::cChunkLayer::GetChunk( int a_X, int a_Z )
|
||||||
|
{
|
||||||
|
const int LocalX = a_X - m_X * LAYER_SIZE;
|
||||||
|
const int LocalZ = a_Z - m_Z * LAYER_SIZE;
|
||||||
|
//LOG("LocalX:%i LocalZ:%i", LocalX, LocalZ );
|
||||||
|
if ((LocalX < LAYER_SIZE) && (LocalZ < LAYER_SIZE) && (LocalX > -1) && (LocalZ > -1))
|
||||||
|
{
|
||||||
|
return &m_Chunks[ LocalX + LocalZ * LAYER_SIZE ];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cChunkMap:
|
||||||
|
|
||||||
cChunkMap::cChunkMap(cWorld* a_World )
|
cChunkMap::cChunkMap(cWorld* a_World )
|
||||||
: m_Layers( 0 )
|
: m_Layers( 0 )
|
||||||
, m_NumLayers( 0 )
|
, m_NumLayers( 0 )
|
||||||
@ -43,20 +70,6 @@ cChunkMap::~cChunkMap()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
cChunkMap::cChunkData* cChunkMap::cChunkLayer::GetChunk( int a_X, int a_Z )
|
|
||||||
{
|
|
||||||
const int LocalX = a_X - m_X * LAYER_SIZE;
|
|
||||||
const int LocalZ = a_Z - m_Z * LAYER_SIZE;
|
|
||||||
//LOG("LocalX:%i LocalZ:%i", LocalX, LocalZ );
|
|
||||||
if( LocalX < LAYER_SIZE && LocalZ < LAYER_SIZE && LocalX > -1 && LocalZ > -1 )
|
|
||||||
return &m_Chunks[ LocalX + LocalZ * LAYER_SIZE ];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cChunkMap::RemoveLayer( cChunkLayer* a_Layer )
|
bool cChunkMap::RemoveLayer( cChunkLayer* a_Layer )
|
||||||
{
|
{
|
||||||
cChunkLayer* NewLayers = 0;
|
cChunkLayer* NewLayers = 0;
|
||||||
@ -449,14 +462,10 @@ void cChunkMap::SaveLayer( cChunkLayer* a_Layer )
|
|||||||
|
|
||||||
char SourceFile[128];
|
char SourceFile[128];
|
||||||
|
|
||||||
sprintf_s(SourceFile, 128, ( WorldName + "/X%i_Z%i.pak").c_str(), a_Layer->m_X, a_Layer->m_Z );
|
sprintf_s(SourceFile, ARRAYCOUNT(SourceFile), ( WorldName + "/X%i_Z%i.pak").c_str(), a_Layer->m_X, a_Layer->m_Z );
|
||||||
|
|
||||||
FILE* f = 0;
|
cFile f;
|
||||||
#ifdef _WIN32
|
if (!f.Open(SourceFile, cFile::fmWrite))
|
||||||
if (fopen_s(&f, SourceFile, "wb" ) != 0 ) // no error
|
|
||||||
#else
|
|
||||||
if( (f = fopen(SourceFile, "wb" )) == 0 ) // no error
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR: Could not write to file %s", SourceFile );
|
LOGERROR("ERROR: Could not write to file %s", SourceFile );
|
||||||
return;
|
return;
|
||||||
@ -466,8 +475,8 @@ void cChunkMap::SaveLayer( cChunkLayer* a_Layer )
|
|||||||
// Header
|
// Header
|
||||||
char PakVersion = 1;
|
char PakVersion = 1;
|
||||||
char ChunkVersion = 1;
|
char ChunkVersion = 1;
|
||||||
fwrite( &PakVersion, sizeof(PakVersion), 1, f ); // pak version
|
f.Write(&PakVersion, sizeof(PakVersion)); // pak version
|
||||||
fwrite( &ChunkVersion, sizeof(ChunkVersion), 1, f ); // chunk version
|
f.Write(&ChunkVersion, sizeof(ChunkVersion)); // chunk version
|
||||||
|
|
||||||
// Count number of chunks in layer
|
// Count number of chunks in layer
|
||||||
short NumChunks = 0;
|
short NumChunks = 0;
|
||||||
@ -479,120 +488,118 @@ void cChunkMap::SaveLayer( cChunkLayer* a_Layer )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite( &NumChunks, sizeof( NumChunks ), 1, f );
|
f.Write(&NumChunks, sizeof(NumChunks));
|
||||||
LOG("Num Chunks in layer: %i", NumChunks );
|
LOG("Num Chunks in layer [%d, %d]: %i", a_Layer->m_X, a_Layer->m_Z, NumChunks);
|
||||||
|
|
||||||
//---------------
|
|
||||||
// Chunk headers
|
// Chunk headers
|
||||||
for( int z = 0; z < LAYER_SIZE; ++z )
|
for (int z = 0; z < LAYER_SIZE; ++z)
|
||||||
{
|
{
|
||||||
for( int x = 0; x < LAYER_SIZE; ++x )
|
for (int x = 0; x < LAYER_SIZE; ++x)
|
||||||
{
|
{
|
||||||
cChunkData & Data = a_Layer->m_Chunks[x + z*LAYER_SIZE];
|
cChunkData & Data = a_Layer->m_Chunks[x + z * LAYER_SIZE];
|
||||||
CompressChunk( &Data );
|
CompressChunk(&Data);
|
||||||
if( Data.m_Compressed || Data.m_LiveChunk )
|
if (Data.m_Compressed != NULL)
|
||||||
{
|
{
|
||||||
int ChunkX = a_Layer->m_X*LAYER_SIZE + x;
|
int ChunkX = a_Layer->m_X * LAYER_SIZE + x;
|
||||||
int ChunkZ = a_Layer->m_Z*LAYER_SIZE + z;
|
int ChunkZ = a_Layer->m_Z * LAYER_SIZE + z;
|
||||||
unsigned int Size = Data.m_CompressedSize; // Needs to be size of compressed data
|
unsigned int Size = Data.m_CompressedSize; // Needs to be size of compressed data
|
||||||
unsigned int USize = Data.m_UncompressedSize; // Uncompressed size
|
unsigned int USize = Data.m_UncompressedSize; // Uncompressed size
|
||||||
fwrite( &ChunkX, sizeof( ChunkX ), 1, f );
|
f.Write(&ChunkX, sizeof(ChunkX));
|
||||||
fwrite( &ChunkZ, sizeof( ChunkZ ), 1, f );
|
f.Write(&ChunkZ, sizeof(ChunkZ));
|
||||||
fwrite( &Size, sizeof( Size ), 1, f );
|
f.Write(&Size, sizeof(Size));
|
||||||
fwrite( &USize, sizeof( USize ), 1, f );
|
f.Write(&USize, sizeof(USize));
|
||||||
}
|
}
|
||||||
}
|
} // for x - a_Layer->mChunks[x]
|
||||||
}
|
} // for z - a_Layer->m_Chunks[z]
|
||||||
|
|
||||||
//----------------
|
|
||||||
// Chunk data
|
// Chunk data
|
||||||
for( int i = 0; i < LAYER_SIZE*LAYER_SIZE; ++i )
|
for (int i = 0; i < LAYER_SIZE*LAYER_SIZE; ++i)
|
||||||
{
|
{
|
||||||
char* Compressed = a_Layer->m_Chunks[i].m_Compressed;
|
char * Compressed = a_Layer->m_Chunks[i].m_Compressed;
|
||||||
if( Compressed )
|
if (Compressed != NULL)
|
||||||
{
|
{
|
||||||
fwrite( Compressed, a_Layer->m_Chunks[i].m_CompressedSize, 1, f );
|
f.Write(Compressed, a_Layer->m_Chunks[i].m_CompressedSize);
|
||||||
if(a_Layer->m_Chunks[i].m_LiveChunk) // If there's a live chunk we have no need for compressed data
|
if (a_Layer->m_Chunks[i].m_LiveChunk != NULL) // If there's a live chunk we have no need for compressed data
|
||||||
{
|
{
|
||||||
delete [] a_Layer->m_Chunks[i].m_Compressed;
|
delete [] a_Layer->m_Chunks[i].m_Compressed;
|
||||||
a_Layer->m_Chunks[i].m_Compressed = 0;
|
a_Layer->m_Chunks[i].m_Compressed = 0;
|
||||||
a_Layer->m_Chunks[i].m_CompressedSize = 0;
|
a_Layer->m_Chunks[i].m_CompressedSize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // for i - a_Layer->m_Chunks[]
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define READ(File, Var) \
|
||||||
|
if (File.Read(&Var, sizeof(Var)) != sizeof(Var)) \
|
||||||
|
{ \
|
||||||
|
LOGERROR("ERROR READING %s FROM FILE %s (line %d)", #Var, SourceFile, __LINE__); \
|
||||||
|
return NULL; \
|
||||||
|
}
|
||||||
|
|
||||||
cChunkMap::cChunkLayer* cChunkMap::LoadLayer(int a_LayerX, int a_LayerZ )
|
cChunkMap::cChunkLayer* cChunkMap::LoadLayer(int a_LayerX, int a_LayerZ )
|
||||||
{
|
{
|
||||||
std::string WorldName = m_World->GetName();
|
std::string WorldName = m_World->GetName();
|
||||||
char SourceFile[128];
|
char SourceFile[128];
|
||||||
|
|
||||||
sprintf_s(SourceFile, 128, (WorldName + "/X%i_Z%i.pak").c_str(), a_LayerX, a_LayerZ );
|
sprintf_s(SourceFile, ARRAYCOUNT(SourceFile), (WorldName + "/X%i_Z%i.pak").c_str(), a_LayerX, a_LayerZ );
|
||||||
|
|
||||||
FILE* f = 0;
|
cFile f(SourceFile, cFile::fmRead);
|
||||||
#ifdef _WIN32
|
if (!f.IsOpen())
|
||||||
if (fopen_s(&f, SourceFile, "rb" ) != 0 ) // no error
|
|
||||||
#else
|
|
||||||
if ((f = fopen(SourceFile, "rb" )) == 0 ) // no error
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char PakVersion = 0;
|
char PakVersion = 0;
|
||||||
char ChunkVersion = 0;
|
char ChunkVersion = 0;
|
||||||
if( fread( &PakVersion, sizeof(PakVersion), 1, f) != 1 ) { LOGERROR("ERROR 1 READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
|
||||||
if( PakVersion != 1 ) { LOGERROR("WRONG PAK VERSION!"); fclose(f); return 0; }
|
READ(f, PakVersion);
|
||||||
if( fread( &ChunkVersion, sizeof(ChunkVersion), 1, f) != 1 ) { LOGERROR("ERROR 2 READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
if (PakVersion != 1)
|
||||||
if( ChunkVersion != 1 )
|
|
||||||
{
|
{
|
||||||
LOGERROR("WRONG CHUNK VERSION!");
|
LOGERROR("WRONG PAK VERSION in file \"%s\"!", SourceFile);
|
||||||
fclose(f);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
READ(f, ChunkVersion);
|
||||||
|
if (ChunkVersion != 1 )
|
||||||
|
{
|
||||||
|
LOGERROR("WRONG CHUNK VERSION in file \"%s\"!", SourceFile);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
short NumChunks = 0;
|
short NumChunks = 0;
|
||||||
if( fread( &NumChunks, sizeof(NumChunks), 1, f) != 1 )
|
READ(f, NumChunks);
|
||||||
{
|
|
||||||
LOGERROR("ERROR 3 READING FROM FILE %s", SourceFile);
|
|
||||||
fclose(f);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG("Num chunks: %i", NumChunks );
|
LOG("Num chunks in file \"%s\": %i", SourceFile, NumChunks);
|
||||||
LOG("Source File: %s", SourceFile );
|
|
||||||
|
|
||||||
cChunkLayer* Layer = new cChunkLayer( LAYER_SIZE*LAYER_SIZE );
|
std::auto_ptr<cChunkLayer> Layer(new cChunkLayer(LAYER_SIZE * LAYER_SIZE)); // The auto_ptr deletes the Layer if we exit with an error
|
||||||
Layer->m_X = a_LayerX;
|
Layer->m_X = a_LayerX;
|
||||||
Layer->m_Z = a_LayerZ;
|
Layer->m_Z = a_LayerZ;
|
||||||
cChunkData** OrderedData = new cChunkData*[ NumChunks ]; // So we can loop over the chunks in the order they were loaded
|
|
||||||
|
cChunkData * OrderedData[LAYER_SIZE * LAYER_SIZE]; // So we can loop over the chunks in the order they were loaded
|
||||||
|
|
||||||
// Loop over all chunk headers
|
// Loop over all chunk headers
|
||||||
for( short i = 0; i < NumChunks; ++i )
|
for( short i = 0; i < NumChunks; ++i )
|
||||||
{
|
{
|
||||||
int ChunkX = 0;
|
int ChunkX = 0;
|
||||||
int ChunkZ = 0;
|
int ChunkZ = 0;
|
||||||
if( fread( &ChunkX, sizeof(ChunkX), 1, f) != 1 ) { LOGERROR("ERROR 4 READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
READ(f, ChunkX);
|
||||||
if( fread( &ChunkZ, sizeof(ChunkZ), 1, f) != 1 ) { LOGERROR("ERROR 5 READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
READ(f, ChunkZ);
|
||||||
cChunkData* Data = Layer->GetChunk( ChunkX, ChunkZ );
|
cChunkData* Data = Layer->GetChunk( ChunkX, ChunkZ );
|
||||||
if( Data )
|
|
||||||
|
if (Data == NULL)
|
||||||
{
|
{
|
||||||
if( fread( &Data->m_CompressedSize, sizeof(Data->m_CompressedSize), 1, f) != 1 ) { LOGERROR("ERROR 6 READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
LOGERROR("Chunk with wrong coordinates in pak file! %i %i", ChunkX, ChunkZ );
|
||||||
if( fread( &Data->m_UncompressedSize, sizeof(Data->m_UncompressedSize), 1, f) != 1 ) { LOGERROR("ERROR 7 READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOGERROR("Chunk with wrong coordinates in pak file! %i %i", ChunkX, ChunkZ );
|
READ(f, Data->m_CompressedSize);
|
||||||
fclose(f);
|
READ(f, Data->m_UncompressedSize);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OrderedData[i] = Data;
|
OrderedData[i] = Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,18 +608,13 @@ cChunkMap::cChunkLayer* cChunkMap::LoadLayer(int a_LayerX, int a_LayerZ )
|
|||||||
{
|
{
|
||||||
cChunkData* Data = OrderedData[i];
|
cChunkData* Data = OrderedData[i];
|
||||||
Data->m_Compressed = new char[ Data->m_CompressedSize ];
|
Data->m_Compressed = new char[ Data->m_CompressedSize ];
|
||||||
//printf("Compressed chunk size: %i\n",Data->m_CompressedSize);
|
if (f.Read(Data->m_Compressed, Data->m_CompressedSize) != Data->m_CompressedSize)
|
||||||
if( fread( Data->m_Compressed, Data->m_CompressedSize, 1, f) != 1 )
|
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR 8 READING FROM FILE %s", SourceFile);
|
LOGERROR("ERROR 8 READING FROM FILE %s", SourceFile);
|
||||||
fclose(f);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete [] OrderedData;
|
return Layer.release();
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return Layer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,8 +55,9 @@ private:
|
|||||||
, m_Z( 0 )
|
, m_Z( 0 )
|
||||||
, m_NumChunksLoaded( 0 )
|
, m_NumChunksLoaded( 0 )
|
||||||
{}
|
{}
|
||||||
cChunkData* GetChunk( int a_X, int a_Z );
|
cChunkData * GetChunk( int a_X, int a_Z );
|
||||||
cChunkData* m_Chunks;
|
|
||||||
|
cChunkData * m_Chunks;
|
||||||
int m_X, m_Z;
|
int m_X, m_Z;
|
||||||
int m_NumChunksLoaded;
|
int m_NumChunksLoaded;
|
||||||
};
|
};
|
||||||
|
200
source/cFile.cpp
Normal file
200
source/cFile.cpp
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
|
||||||
|
// cFile.cpp
|
||||||
|
|
||||||
|
// Implements the cFile class providing an OS-independent abstraction of a file.
|
||||||
|
|
||||||
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||||
|
|
||||||
|
#include "cFile.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Simple constructor - creates an unopened file object, use Open() to open / create a real file
|
||||||
|
cFile::cFile(void) :
|
||||||
|
#ifdef USE_STDIO_FILE
|
||||||
|
m_File(NULL)
|
||||||
|
#else
|
||||||
|
m_File(INVALID_HANDLE_VALUE)
|
||||||
|
#endif // USE_STDIO_FILE
|
||||||
|
{
|
||||||
|
// Nothing needed yet
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Constructs and opens / creates the file specified, use IsOpen() to check for success
|
||||||
|
cFile::cFile(const char * iFileName, EMode iMode) :
|
||||||
|
#ifdef USE_STDIO_FILE
|
||||||
|
m_File(NULL)
|
||||||
|
#else
|
||||||
|
m_File(INVALID_HANDLE_VALUE)
|
||||||
|
#endif // USE_STDIO_FILE
|
||||||
|
{
|
||||||
|
Open(iFileName, iMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Auto-closes the file, if open
|
||||||
|
cFile::~cFile()
|
||||||
|
{
|
||||||
|
if (IsOpen())
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cFile::Open(const char * iFileName, EMode iMode)
|
||||||
|
{
|
||||||
|
assert(!IsOpen()); // You should close the file before opening another one
|
||||||
|
|
||||||
|
if (IsOpen())
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * Mode = NULL;
|
||||||
|
switch (iMode)
|
||||||
|
{
|
||||||
|
case fmRead: Mode = "rb"; break;
|
||||||
|
case fmWrite: Mode = "wb"; break;
|
||||||
|
case fmReadWrite: Mode = "ab+"; break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
assert(!"Unhandled file mode");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_File = fopen(iFileName, Mode);
|
||||||
|
return (m_File != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cFile::Close(void)
|
||||||
|
{
|
||||||
|
assert(IsOpen()); // You should not close file objects that don't have an open file.
|
||||||
|
|
||||||
|
if (!IsOpen())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(m_File);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cFile::IsOpen(void) const
|
||||||
|
{
|
||||||
|
return (m_File != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cFile::IsEOF(void) const
|
||||||
|
{
|
||||||
|
assert(IsOpen());
|
||||||
|
|
||||||
|
if (!IsOpen())
|
||||||
|
{
|
||||||
|
// Unopened files behave as at EOF
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (feof(m_File) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open
|
||||||
|
int cFile::Read (void * iBuffer, int iNumBytes)
|
||||||
|
{
|
||||||
|
assert(IsOpen());
|
||||||
|
|
||||||
|
if (!IsOpen())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fread(iBuffer, 1, iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open
|
||||||
|
int cFile::Write(const void * iBuffer, int iNumBytes)
|
||||||
|
{
|
||||||
|
assert(IsOpen());
|
||||||
|
|
||||||
|
if (!IsOpen())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fwrite(iBuffer, 1, iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Seeks to iPosition bytes from file start, returns old position or -1 for failure
|
||||||
|
int cFile::Seek (int iPosition)
|
||||||
|
{
|
||||||
|
assert(IsOpen());
|
||||||
|
|
||||||
|
if (!IsOpen())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fseek(m_File, iPosition, SEEK_SET) != 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ftell(m_File);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns the current position (bytes from file start)
|
||||||
|
int cFile::Tell (void) const
|
||||||
|
{
|
||||||
|
assert(IsOpen());
|
||||||
|
|
||||||
|
if (!IsOpen())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ftell(m_File);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
99
source/cFile.h
Normal file
99
source/cFile.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
// cFile.h
|
||||||
|
|
||||||
|
// Interfaces to the cFile class providing an OS-independent abstraction of a file.
|
||||||
|
|
||||||
|
/*
|
||||||
|
The object is optimized towards binary reads.
|
||||||
|
The object has no multithreading locks, don't use from multiple threads!
|
||||||
|
Usage:
|
||||||
|
1, Construct a cFile instance (no-param constructor)
|
||||||
|
2, Open a file using Open(), check return value for success
|
||||||
|
3, Read / write
|
||||||
|
4, Destroy the instance
|
||||||
|
|
||||||
|
-- OR --
|
||||||
|
|
||||||
|
1, Construct a cFile instance opening the file (filename-param constructor)
|
||||||
|
2, Check if the file was opened using IsOpen()
|
||||||
|
3, Read / write
|
||||||
|
4, Destroy the instance
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef CFILE_H_INCLUDED
|
||||||
|
#define CFILE_H_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define USE_STDIO_FILE
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// DEBUG:
|
||||||
|
#define USE_STDIO_FILE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// The mode in which to open the file
|
||||||
|
enum EMode
|
||||||
|
{
|
||||||
|
fmRead, // Read-only. If the file doesn't exist, object will not be valid
|
||||||
|
fmWrite, // Write-only. If the file already exists, it will be overwritten
|
||||||
|
fmReadWrite, // Read/write. If the file already exists, it will be left intact
|
||||||
|
} ;
|
||||||
|
|
||||||
|
/// Simple constructor - creates an unopened file object, use Open() to open / create a real file
|
||||||
|
cFile(void);
|
||||||
|
|
||||||
|
/// Constructs and opens / creates the file specified, use IsOpen() to check for success
|
||||||
|
cFile(const char * iFileName, EMode iMode);
|
||||||
|
|
||||||
|
/// Auto-closes the file, if open
|
||||||
|
~cFile();
|
||||||
|
|
||||||
|
bool Open(const char * iFileName, EMode iMode);
|
||||||
|
void Close(void);
|
||||||
|
bool IsOpen(void) const;
|
||||||
|
bool IsEOF(void) const;
|
||||||
|
|
||||||
|
/// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open
|
||||||
|
int Read (void * iBuffer, int iNumBytes);
|
||||||
|
|
||||||
|
/// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open
|
||||||
|
int Write(const void * iBuffer, int iNumBytes);
|
||||||
|
|
||||||
|
/// Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open
|
||||||
|
int Seek (int iPosition);
|
||||||
|
|
||||||
|
/// Returns the current position (bytes from file start) or -1 for failure; asserts if not open
|
||||||
|
int Tell (void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef USE_STDIO_FILE
|
||||||
|
FILE * m_File;
|
||||||
|
#else
|
||||||
|
HANDLE m_File;
|
||||||
|
#endif
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CFILE_H_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user