FBIagent
Erfahrenes Mitglied
Guten Abend,
ich schreibe gerade, wie im Betreff schon erwähnt, ein Programm, welches Höhendaten
von Landschaften etwas effizienter speichert. Was ich mit effizienter meine?
Ich habe eine Spielewelt, die ich in 32*32 Regionen unterteile. Jede Region beinhaltet
256*256 Zellen und jede dieser Zellen ist noch einmal unterteilt in 8*8 Blöcke. Die
Blöcke sollen hierbei beliebig viele Höheninfomationen beinhalten können. Eine
Höheninformation eines Blocks ist ein 2 byte shot. Weiterhin wird für jede
Höheninformation ein 1 byte char benötigt(NSWE), um überprüfen zu können ob der
Spieler einen Block auf dieser Höhe aus einr bestimten Richtung betreten kann oder nicht.
Eine Höheninfomationsdatei ist eine Region.
Um effizienter ohne jeklichen Datenverlust zu spiechern versuche ich folgendes:
1. Falls alle Blöcke in einer Zelle garkeine Höheninformationen beinhalten, schreibe ich eine 0 in die Datei.
2. Falls alle Blöcke in einer Zelle genau eine Höheninfomation beinhalten, wird eine 1 geschrieben und eine Höheninformation.
3. Wenn Blöcke der Zelle 0 und 1 Höheninfomationen beinhalten und mindestens ein Block 1 Höheninfomation hat wird eine 2 geschrieben, und 8*8 Zelleninformationen. Falls ein Block keine Höheninfomationen enthält wird als block typ 0 geschrieben, falls doch wird eine 1 als block typ geschrieben und danach die höhen und NSWE Werte.
4. Blöcke in Zellen haben 0 und mehr Höheninfomationen, wobei mindestens ein Block
mehr als 1 Höheninformationen beinhaltet. Es wird als Zellen typ 3 geschrieben, falls ein Block keine info beinhaltet 0 für den block typ, falls informationen vorhanden 1 für block typ und höheninformationen*(Z,NSWE)
Soweit dachte ich auch das ich das Komprimieren hinbekommen habe, nur beim lesen
der Höheninformations Dateien bekomme ich nicht erwartete Werte. Ich wäre sehr
dankbar wenn jemand helfen könnte und sich das anschauen könnte.
Das einlesen von den reinen Höheninformationen ist hier nicht das Problem, da ich von
diesen Problemlos Bitmaps mit Akuraten Höheninformtionen erstellen kann.
Programm für die convertierung der reinen Höheninformationsdaten:
BuildZoneConv.h
BuildZoneConv.cpp
Programm zum auslesen des CellOptimized outputs:
GeoEngine.h
GeoEngine.cpp
Hier noch der shared Header:
geoshared.h
Das wäre alles an SourceCode. Ich verzweifle solangsam daran, da ich den Code
dutzende male überprüft habe, aber aufs Verrecken keinen Fehler finden kann.
GeoEngine_Region() resultiert RLE_FORMAT, und sagt mir das ich ein unbekanten Block Typ habe.
Eine Testdatei lae ich gerade bei rapidshare rauf.
EDIT:
Test Landschaftsinfos: http://rapidshare.com/files/137829157/25_15.zip.html
.txt Datei in den Ordner von BuildZoneConv legen und einen Ordner bmp anlegen. Nun BuildZoneConv mit parameter
25_15 starten.
Best wishes
FBIagent
ich schreibe gerade, wie im Betreff schon erwähnt, ein Programm, welches Höhendaten
von Landschaften etwas effizienter speichert. Was ich mit effizienter meine?
Ich habe eine Spielewelt, die ich in 32*32 Regionen unterteile. Jede Region beinhaltet
256*256 Zellen und jede dieser Zellen ist noch einmal unterteilt in 8*8 Blöcke. Die
Blöcke sollen hierbei beliebig viele Höheninfomationen beinhalten können. Eine
Höheninformation eines Blocks ist ein 2 byte shot. Weiterhin wird für jede
Höheninformation ein 1 byte char benötigt(NSWE), um überprüfen zu können ob der
Spieler einen Block auf dieser Höhe aus einr bestimten Richtung betreten kann oder nicht.
Eine Höheninfomationsdatei ist eine Region.
Um effizienter ohne jeklichen Datenverlust zu spiechern versuche ich folgendes:
1. Falls alle Blöcke in einer Zelle garkeine Höheninformationen beinhalten, schreibe ich eine 0 in die Datei.
2. Falls alle Blöcke in einer Zelle genau eine Höheninfomation beinhalten, wird eine 1 geschrieben und eine Höheninformation.
3. Wenn Blöcke der Zelle 0 und 1 Höheninfomationen beinhalten und mindestens ein Block 1 Höheninfomation hat wird eine 2 geschrieben, und 8*8 Zelleninformationen. Falls ein Block keine Höheninfomationen enthält wird als block typ 0 geschrieben, falls doch wird eine 1 als block typ geschrieben und danach die höhen und NSWE Werte.
4. Blöcke in Zellen haben 0 und mehr Höheninfomationen, wobei mindestens ein Block
mehr als 1 Höheninformationen beinhaltet. Es wird als Zellen typ 3 geschrieben, falls ein Block keine info beinhaltet 0 für den block typ, falls informationen vorhanden 1 für block typ und höheninformationen*(Z,NSWE)
Soweit dachte ich auch das ich das Komprimieren hinbekommen habe, nur beim lesen
der Höheninformations Dateien bekomme ich nicht erwartete Werte. Ich wäre sehr
dankbar wenn jemand helfen könnte und sich das anschauen könnte.
Das einlesen von den reinen Höheninformationen ist hier nicht das Problem, da ich von
diesen Problemlos Bitmaps mit Akuraten Höheninformtionen erstellen kann.
Programm für die convertierung der reinen Höheninformationsdaten:
BuildZoneConv.h
C++:
#ifndef __BUILDZONECONV_H__
#define __BUILDZONECONV_H__
#include <fstream>
int main( int argc, char **argv );
bool ParseDump();
void NonOptimized();
void CellOptimized();
void RepeatOptimized();
void ReleaseMemory();
void BinWrite( std::ofstream &Out, char *Data, int Bytes );
#endif
BuildZoneConv.cpp
C++:
#include "BuildZoneConv.h"
#include "..\..\Utils\Graphic\bitmap_Image.h"
#include "..\geoshared.h"
#include <iostream>
#include <string>
#include <windows.h>
/*
* CellOptimized:
* One geo region has 256x256 cells, each cell got 8x8 blocks in it
*
* CELL_NULL:
* All cell blocks have 0 layers, no data needed at all
*
* CELL_FLAT:
* All cell blocks have 1 layer and all Z values are the same, one Z value required to save
*
* CELL_MULTI:
* Cell blocks have either 0 layers or 1 layer, at least 1 block with 1 layer, all 1 layer cell blocks have it's own Z value, each 1 layer block needs Z and NSWE saved
*
* CELL_LAYER:
* Cell blocks have either 0 layers or more, at least 1 block with more than 1 layer, all cell blocks with layers greater 0 needs Layers*(Z,NSWE) saved
*
*/
Block *g_Blocks[ REGION_BLOCKS ];
std::string g_Region;
int g_MaxLayers = 0;
int main( int argc, char **argv ) {
if ( argc < 2 ) {
std::cout << "Usage: " << argv[ 0 ] << " <REGION>" << std::endl;
getchar();
return 1;
}
g_Region = argv[ 1 ];
// initialize array with 0 values so cleanup goes well
memset( g_Blocks, 0, REGION_BLOCKS );
// parse the client geometry data into g_Blocks and generate bmp's for each layer
if ( !ParseDump() ) {
ReleaseMemory();
return 1;
}
// generate geodata in non optimized format
NonOptimized();
// generate geodata in cell optimized format
CellOptimized();
// TODO: Implement generation of repeat optimization
RepeatOptimized();
std::cout << "Press [ENTER] to quit..." << std::endl;
getchar();
}
bool ParseDump() {
std::cout << "-= Parse dump =-" << std::endl;
std::string GeoTextName = g_Region;
std::ifstream GeoText;
GeoTextName += ".txt";
std::cout << "FILE: " << GeoTextName << "..." << std::endl;
GeoText.open( GeoTextName.c_str() );
if ( !GeoText.is_open() ) {
std::cout << "ERROR: couldn't open file for reading!" << std::endl;
return false;
}
std::string GeoLine = "";
//Format: [x,y]layers(layer0_z:layer0_NSWE)....(layerN_z:layerN_NSWE)
int Empty = 0;
int X = 0;
int Y = 0;
int Offset = 0;
while ( std::getline( GeoText, GeoLine ) ) {
// Data in the dumped client files are lines starting with [
if ( GeoLine.length() > 0 && GeoLine[ 0 ] == '[' ) {
std::string::size_type Pos = 1;
// X
for ( std::string::size_type i = Pos;i < GeoLine.length();++ i ) {
if ( GeoLine[ i ] == ',' ) {
X = atoi( GeoLine.substr( Pos, i - Pos ).c_str() );
Pos = i + 1;
break;
}
}
// Y
for ( std::string::size_type i = Pos;i < GeoLine.length();++ i ) {
if ( GeoLine[ i ] == ']' ) {
Y = atoi( GeoLine.substr( Pos, i - Pos ).c_str() );
Pos = i + 1;
break;
}
}
Offset = Y + X * REGION_BLOCKS_Y;
// Layers, if 0 it's a null block
if ( GeoLine[ Pos ] == '0' ) {
++ Empty;
g_Blocks[ Offset ] = 0;
continue;
}
// More than one layer, create a new block
g_Blocks[ Offset ] = new Block;
// Layers
for ( std::string::size_type i = Pos;i < GeoLine.length();++ i ) {
if ( GeoLine[ i ] == '(' ) {
g_Blocks[ Offset ]->Layers = atoi( GeoLine.substr( Pos, i - Pos ).c_str() );
if ( g_Blocks[ Offset ]->Layers > g_MaxLayers ) {
g_MaxLayers = g_Blocks[ Offset ]->Layers;
}
g_Blocks[ Offset ]->Z = new short[ g_Blocks[ Offset ]->Layers ];
g_Blocks[ Offset ]->NSWE = new char[ g_Blocks[ Offset ]->Layers ];
Pos = i + 1;
break;
}
}
// Z and movement data Layers times
for ( char c = 0;c < g_Blocks[ Offset ]->Layers;++ c ) {
// Z
for ( std::string::size_type i = Pos;i < GeoLine.length();++ i ) {
if ( GeoLine[ i ] == ':' ) {
g_Blocks[ Offset ]->Z[ c ] = atoi( GeoLine.substr( Pos, i - Pos ).c_str() );
Pos = i + 1;
break;
}
}
// Movement
for ( std::string::size_type i = Pos;i < GeoLine.length();++ i ) {
if ( GeoLine[ i ] == ')' ) {
g_Blocks[ Offset ]->NSWE[ c ] = 0;
std::string NSWE = GeoLine.substr( Pos, i - Pos ).c_str();
// It's possible to come into this block from north
if ( NSWE[ 0 ] == '1' ) {
g_Blocks[ Offset ]->NSWE[ c ] |= NORTH;
}
// It's possible to come into this block from south
if ( NSWE[ 1 ] == '1' ) {
g_Blocks[ Offset ]->NSWE[ c ] |= SOUTH;
}
// It's possible to come into this block from west
if ( NSWE[ 2 ] == '1' ) {
g_Blocks[ Offset ]->NSWE[ c ] |= WEST;
}
// It's possible to come into this block from east
if ( NSWE[ 3 ] == '1' ) {
g_Blocks[ Offset ]->NSWE[ c ] |= EAST;
}
Pos = i + 2;
break;
}
}
}
}
}
for ( int Layer = 0;Layer < g_MaxLayers;++ Layer ) {
std::string FileName = "bmp\\(";
FileName += g_Region;
FileName += ")_";
FileName += itoa( Layer, new char[ 11 ], 10 );
std::string FileNameGray = FileName;
FileNameGray += "_gray.bmp";
FileName += ".bmp";
bitmapImage b( REGION_BLOCKS_X, REGION_BLOCKS_Y ); // create a bitmap
bitmapImage b_gray( REGION_BLOCKS_X, REGION_BLOCKS_Y ); // create a bitmap
// loop through all of its pixels
for (int BlockX=0;BlockX<REGION_BLOCKS_X;BlockX++) {
for (int BlockY=0;BlockY<REGION_BLOCKS_Y;BlockY++) {
Offset = BlockY + BlockX * REGION_BLOCKS_Y;
if ( g_Blocks[ Offset ] == 0 || Layer > g_Blocks[ Offset ]->Layers - 1 ) {
b.setPixel( BlockX, BlockY, 0 );
b_gray.setPixel( BlockX, BlockY, 0 );
} else {
int Val = ( g_Blocks[ Offset ]->Z[ Layer ] + 32768 ) / 256;
b_gray.setPixelRGB( BlockX, BlockY, Val, Val, Val );
b.setPixel( BlockX, BlockY, g_Blocks[ Offset ]->Z[ Layer ] + 32768 );
}
}
}
// save the bitmap to a file using a bit depth of 16
b_gray.saveToBitmapFile( FileNameGray.c_str(), 16 );
b.saveToBitmapFile( FileName.c_str(), 16 );
}
std::cout << "MaxLayers: " << g_MaxLayers << std::endl;
std::cout << "Empty blocks: " << Empty << std::endl;
return true;
}
void NonOptimized() {
std::cout << "-= Non optimized output =-" << std::endl;
std::string GeoName = g_Region;
std::ofstream Geo;
GeoName += "(NO).geo";
std::cout << "FILE: " << GeoName << "..." << std::endl;
Geo.open( GeoName.c_str() );
if ( !Geo.is_open() ) {
std::cout << "ERROR: couldn't open file for writing!" << std::endl;
return;
}
// write geodata format byte at the start of the file
BinWrite( Geo, ( char* )&GEOTYPE_NONOPTIMIZED, sizeof ( GEOTYPE_NONOPTIMIZED ) );
// Write geodata
for ( int i = 0;i < REGION_BLOCKS;++ i ) {
if ( g_Blocks[ i ] == 0 ) {
char b = 0;
BinWrite( Geo, ( char* )&b, 1 );
continue;
}
BinWrite( Geo, ( char* )&g_Blocks[ i ]->Layers, sizeof ( g_Blocks[ i ]->Layers ) );
for ( char c = 0;c < g_Blocks[ i ]->Layers;++ c ) {
BinWrite( Geo, ( char* )&g_Blocks[ i ]->Z[ c ], sizeof ( g_Blocks[ i ]->Z[ c ] ) );
BinWrite( Geo, ( char* )&g_Blocks[ i ]->NSWE[ c ], sizeof( g_Blocks[ i ]->NSWE[ c ] ) );
}
}
}
// used for CellOptimized
Block *Cells[ REGION_CELLS ][ CELL_BLOCKS ];
char CellTypes[ REGION_CELLS ];
void CellOptimized() {
std::cout << "-= Cell optimized output =-" << std::endl;
std::cout << "OPTIMIZE: blocks into cells..." << std::endl;
// Pack blocks into cells
for ( int xC = 0;xC < REGION_CELLS_X;++ xC ) {
for ( int yC = 0;yC < REGION_CELLS_Y;++ yC ) {
// Cell offset
int OffsetC = xC + yC * REGION_CELLS_X;
for ( int xB = 0;xB < CELL_BLOCKS_X;++ xB ) {
for ( int yB = 0;yB < CELL_BLOCKS_Y;++ yB ) {
// Block offset in cell
int OffsetB = xB + yB * CELL_BLOCKS_X;
// Region coordinates
int xR = xB + xC * CELL_BLOCKS_X;
int yR = yB + yC * CELL_BLOCKS_Y;
// Block offset in region
int OffsetR = xR + yR * REGION_BLOCKS_X;
Cells[ OffsetC ][ OffsetB ] = g_Blocks[ OffsetR ];
}
}
}
}
int NullCells = 0;
int FlatCells = 0;
int MultiCells = 0;
int LayerCells = 0;
std::cout << "OPTIMIZE: Determine cell types..." << std::endl;
// Determine cell types
for ( int OffsetC = 0;OffsetC < REGION_CELLS;++ OffsetC ) {
int Layers = 0;
int Z = 0;
bool CanBeFlat = true;
for ( int OffsetB = 0;OffsetB < CELL_BLOCKS;++ OffsetB ) {
if ( Cells[ OffsetC ][ OffsetB ] == 0 ) {
// can't be flat anymore
CanBeFlat = false;
continue;
}
if ( Cells[ OffsetC ][ OffsetB ]->Layers > Layers ) {
Layers = Cells[ OffsetC ][ OffsetB ]->Layers;
if ( Layers > 1 ) {
// more than one layer can't be flat
CanBeFlat = false;
}
}
if ( CanBeFlat && Cells[ OffsetC ][ OffsetB ]->Z[ 0 ] > Z && OffsetB > 0 ) {
// cell with different Z values can't be flat
CanBeFlat = false;
}
}
if ( Layers == 0 ) {
++ NullCells;
CellTypes[ OffsetC ] = CELL_NULL;
} else if ( Layers == 1 && CanBeFlat ) {
++ FlatCells;
CellTypes[ OffsetC ] = CELL_FLAT;
} else if ( Layers == 1 ) {
++ MultiCells;
CellTypes[ OffsetC ] = CELL_MULTI;
} else {
++ LayerCells;
CellTypes[ OffsetC ] = CELL_LAYER;
}
}
std::cout << "OPTIMIZE: NullCells " << NullCells << std::endl;
std::cout << "OPTIMIZE: FlatCells " << FlatCells << std::endl;
std::cout << "OPTIMIZE: MultiCells " << MultiCells << std::endl;
std::cout << "OPTIMIZE: LayerCells " << LayerCells << std::endl;
std::string GeoName = g_Region;
std::ofstream Geo;
GeoName += "(CO).geo";
std::cout << "FILE: " << GeoName << "..." << std::endl;
Geo.open( GeoName.c_str() );
if ( !Geo.is_open() ) {
std::cout << "ERROR: couldn't open file for writing!" << std::endl;
}
// write geodata format byte at the start of the file
BinWrite( Geo, ( char* )&GEOTYPE_CELLOPTIMIZED, sizeof ( GEOTYPE_CELLOPTIMIZED ) );
for ( int OffsetC = 0;OffsetC < REGION_CELLS;++ OffsetC ) {
BinWrite( Geo, ( char* )&CellTypes[ OffsetC ], sizeof ( CellTypes[ OffsetC ] ) );
if ( CellTypes[ OffsetC ] == CELL_FLAT ) {
// flat don't need NSWE data
BinWrite( Geo, ( char* )&Cells[ OffsetC ][ 0 ]->Z[ 0 ], sizeof ( Cells[ OffsetC ][ 0 ]->Z[ 0 ] ) );
// BinWrite( Geo, ( char* )&Cells[ OffsetC ][ 0 ]->NSWE[ 0 ], sizeof ( Cells[ OffsetC ][ 0 ]->NSWE[ 0 ] ) );
} else if ( CellTypes[ OffsetC ] == CELL_MULTI ) {
for ( int OffsetB = 0;OffsetB < CELL_BLOCKS;++ OffsetB ) {
if ( Cells[ OffsetC ][ OffsetB ] == 0 ) {
BinWrite( Geo, ( char* )&BLOCK_NULL, sizeof ( BLOCK_NULL ) );
continue;
}
BinWrite( Geo, ( char* )&BLOCK_DATA, sizeof ( BLOCK_DATA ) );
BinWrite( Geo, ( char* )&Cells[ OffsetC ][ OffsetB ]->Z[ 0 ], sizeof ( Cells[ OffsetC ][ OffsetB ]->Z[ 0 ] ) );
BinWrite( Geo, ( char* )&Cells[ OffsetC ][ OffsetB ]->NSWE[ 0 ], sizeof ( Cells[ OffsetC ][ OffsetB ]->NSWE[ 0 ] ) );
}
} else if ( CellTypes[ OffsetC ] == CELL_LAYER ) {
for ( int OffsetB = 0;OffsetB < CELL_BLOCKS;++ OffsetB ) {
if ( Cells[ OffsetC ][ OffsetB ] == 0 ) {
BinWrite( Geo, ( char* )&BLOCK_NULL, sizeof ( BLOCK_NULL ) );
continue;
}
BinWrite( Geo, ( char* )&BLOCK_DATA, sizeof ( BLOCK_DATA ) );
BinWrite( Geo, ( char* )&Cells[ OffsetC ][ OffsetB ]->Layers, sizeof ( Cells[ OffsetC ][ OffsetB ]->Layers ) );
for ( int Layer = 0;Layer < Cells[ OffsetC ][ OffsetB ]->Layers;++ Layer ) {
BinWrite( Geo, ( char* )&Cells[ OffsetC ][ OffsetB ]->Z[ Layer ], sizeof ( Cells[ OffsetC ][ OffsetB ]->Z[ Layer ] ) );
BinWrite( Geo, ( char* )&Cells[ OffsetC ][ OffsetB ]->NSWE[ Layer ], sizeof ( Cells[ OffsetC ][ OffsetB ]->NSWE[ Layer ] ) );
}
}
}
}
}
void RepeatOptimized() {
}
void ReleaseMemory() {
for ( int i = 0;i < REGION_BLOCKS;++ i ) {
if ( g_Blocks[ i ] != NULL ) {
delete[] g_Blocks[ i ]->Z;
delete[] g_Blocks[ i ]->NSWE;
delete g_Blocks[ i ];
}
}
}
void BinWrite( std::ofstream &Out, char *Data, int Bytes ) {
Out.write( Data, Bytes );
}
Programm zum auslesen des CellOptimized outputs:
GeoEngine.h
C++:
#ifndef __GEOENGINE_H__
#define __GEOENGINE_H__
#include "..\geoshared.h"
#if !defined(WIN32) && !defined(__linux__)
#endif
#ifdef __cplusplus
# define EXTERN_C extern "C"
#else
# define EXTERN_C
#endif
#ifdef WIN32
# ifdef GEOENGINE_EXPORTS
# define GEOENGINE_API __declspec ( dllexport )
# else
# define GEOENGINE_API __declspec ( dllimport )
# endif
#else
# define GEOENGINE_API
#endif
#define RLE_OK 0
#define RLE_OPEN_FILE 1
#define RLE_MAP 2
#define RLE_FORMAT 3
#define RLE_MEMORY 4
EXTERN_C GEOENGINE_API void GeoEngine_Init();
EXTERN_C GEOENGINE_API void GeoEngine_DeInit();
EXTERN_C GEOENGINE_API long GeoEngine_Region( const char *RegionFile, char RegionX, char RegionY );
#endif
GeoEngine.cpp
C++:
#include "GeoEngine.h"
#include <sys/stat.h>
#include <iostream>
#ifdef WIN32
# include <windows.h>
#else
#endif
typedef struct {
Block *Blocks[ 64 ];
} Cell;
Cell *g_Cells[ WORLD_CELLS ];
#ifdef WIN32
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) {
return TRUE;
}
#endif
void GeoEngine_Init() {
memset( g_Cells, 0, WORLD_CELLS );
}
void GeoEngine_DeInit() {
}
void BinRead( char *Dest, const char *&DataPtr, int Bytes );
long GeoEngine_Region( const char *RegionFile, char RegionX, char RegionY ) {
#ifdef WIN32
HANDLE hFile = CreateFileA( RegionFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if ( hFile == INVALID_HANDLE_VALUE ) {
return RLE_OPEN_FILE;
}
#else
int fd = open( RegionFile, O_RDONLY );
if ( fd == -1 ) {
return RLE_OPEN_FILE;
}
#endif
struct stat fstat;
stat( RegionFile, &fstat );
#ifdef WIN32
HANDLE hMapFile = CreateFileMappingA( hFile, NULL, PAGE_READONLY, 0, fstat.st_size, RegionFile );
if ( hMapFile == 0 ) {
CloseHandle( hFile );
return RLE_MAP;
}
const char *MapPtr = ( const char* )MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, fstat.st_size );
#else
const char *MapPtr = mmap( 0, fstat.st_size, PROT_READ, MAP_SHARED, fd, 0 );
#endif
if ( MapPtr == 0 ) {
#ifdef WIN32
CloseHandle( hMapFile );
CloseHandle( hFile );
#else
close( fd );
#endif
return RLE_MAP;
}
const char *DataPtr = MapPtr;
char GeoType = 0;
BinRead( &GeoType, DataPtr, 1 );
if ( GeoType != GEOTYPE_CELLOPTIMIZED ) {
#ifdef WIN32
UnmapViewOfFile( MapPtr );
CloseHandle( hMapFile );
CloseHandle( hFile );
#else
close( fd );
#endif
return RLE_FORMAT;
}
short RegionOffset = RegionX + RegionY * WORLD_REGIONS_X;
for ( long i = 0;i < REGION_CELLS;++ i ) {
std::cout << "CellOffset: " << i << std::endl;
char CellType = 0;
BinRead( &CellType, DataPtr, 1 );
unsigned long CellX = i % REGION_CELLS_X;
unsigned long CellY = ( i - CellX ) / REGION_CELLS_X;
unsigned long WorldCellX = CellX + RegionX * REGION_CELLS_X;
unsigned long WorldCellY = CellY + RegionY * REGION_CELLS_Y;
unsigned long WorldCellOffset = WorldCellX + WorldCellY * WORLD_CELLS_X;
Block *B = NULL;
switch ( CellType ) {
case CELL_NULL:
break;
case CELL_FLAT:
g_Cells[ WorldCellOffset ] = new Cell;
B = new Block;
B->Layers = 1;
B->Z = new short[ 1 ];
BinRead( ( char* )&B->Z[ 0 ], DataPtr, sizeof ( B->Z[ 0 ] ) );
B->NSWE = new char[ 1 ];
B->NSWE[ 0 ] = NORTH | SOUTH | WEST | EAST;
//B->NSWE[ 0 ] = *DataPtr;
//DataPtr += 1;
for ( unsigned char c = 0;c < CELL_BLOCKS;++ c ) {
g_Cells[ WorldCellOffset ]->Blocks[ c ] = B;
}
break;
case CELL_MULTI:
g_Cells[ WorldCellOffset ] = new Cell;
for ( unsigned char c = 0;c < CELL_BLOCKS;++ c ) {
char BlockType = 0;
BinRead( &BlockType, DataPtr, 1 );
switch ( BlockType ) {
case BLOCK_NULL:
g_Cells[ WorldCellOffset ]->Blocks[ c ] = 0;
break;
case BLOCK_DATA:
g_Cells[ WorldCellOffset ]->Blocks[ c ] = new Block;
g_Cells[ WorldCellOffset ]->Blocks[ c ]->Layers = 1;
g_Cells[ WorldCellOffset ]->Blocks[ c ]->Z = new short[ 1 ];
g_Cells[ WorldCellOffset ]->Blocks[ c ]->NSWE = new char[ 1 ];
BinRead( ( char* )&g_Cells[ WorldCellOffset ]->Blocks[ c ]->Z[ 0 ], DataPtr, sizeof ( g_Cells[ WorldCellOffset ]->Blocks[ c ]->Z[ 0 ] ) );
BinRead( &g_Cells[ WorldCellOffset ]->Blocks[ c ]->NSWE[ 0 ], DataPtr, sizeof ( g_Cells[ WorldCellOffset ]->Blocks[ c ]->NSWE[ 0 ] ) );
break;
default:
std::cout << "Layered cell, unknown block type: " << ( int )BlockType << std::endl;
#ifdef WIN32
UnmapViewOfFile( MapPtr );
CloseHandle( hMapFile );
CloseHandle( hFile );
#else
close( fd );
#endif
return RLE_FORMAT;
break;
}
}
break;
case CELL_LAYER:
g_Cells[ WorldCellOffset ] = new Cell;
for ( unsigned char c = 0;c < CELL_BLOCKS;++ c ) {
char BlockType = 0;
BinRead( &BlockType, DataPtr, 1 );
switch ( BlockType ) {
case BLOCK_NULL:
g_Cells[ WorldCellOffset ]->Blocks[ c ] = 0;
break;
case BLOCK_DATA:
g_Cells[ WorldCellOffset ]->Blocks[ c ] = new Block;
BinRead( &g_Cells[ WorldCellOffset ]->Blocks[ c ]->Layers, DataPtr, sizeof ( g_Cells[ WorldCellOffset ]->Blocks[ c ]->Layers ) );
g_Cells[ WorldCellOffset ]->Blocks[ c ]->Z = new short[ g_Cells[ WorldCellOffset ]->Blocks[ c ]->Layers ];
g_Cells[ WorldCellOffset ]->Blocks[ c ]->NSWE = new char[ g_Cells[ WorldCellOffset ]->Blocks[ c ]->Layers ];
for ( unsigned char Layer = 0;Layer < g_Cells[ WorldCellOffset ]->Blocks[ c ]->Layers;++ Layer ) {
BinRead( ( char* )&g_Cells[ WorldCellOffset ]->Blocks[ c ]->Z[ Layer ], DataPtr, sizeof ( g_Cells[ WorldCellOffset ]->Blocks[ c ]->Z[ Layer ] ) );
BinRead( &g_Cells[ WorldCellOffset ]->Blocks[ c ]->NSWE[ Layer ], DataPtr, sizeof ( g_Cells[ WorldCellOffset ]->Blocks[ c ]->NSWE[ Layer ] ) );
}
break;
default:
std::cout << "Layered cell, unknown block type: " << ( int )BlockType << std::endl;
#ifdef WIN32
UnmapViewOfFile( MapPtr );
CloseHandle( hMapFile );
CloseHandle( hFile );
#else
close( fd );
#endif
return RLE_FORMAT;
}
}
break;
default:
std::cout << "Unknown cell type: " << ( int )CellType << std::endl;
#ifdef WIN32
UnmapViewOfFile( MapPtr );
CloseHandle( hMapFile );
CloseHandle( hFile );
#else
close( fd );
#endif
return RLE_FORMAT;
}
}
#ifdef WIN32
UnmapViewOfFile( MapPtr );
CloseHandle( hMapFile );
CloseHandle( hFile );
#else
close( fd );
#endif
return RLE_OK;
}
void BinRead( char *Dest, const char *&DataPtr, int Bytes ) {
memcpy( Dest, DataPtr, Bytes );
DataPtr += Bytes;
}
Hier noch der shared Header:
geoshared.h
C++:
#ifndef __GEOSHARED_H__
#define __GEOSHARED_H__
/******************************
* CELL
*/
const unsigned long CELL_BLOCKS_X = 8;
const unsigned long CELL_BLOCKS_Y = 8;
const unsigned long CELL_BLOCKS = CELL_BLOCKS_X * CELL_BLOCKS_Y;
/******************************/
/******************************
* REGION
*/
const unsigned long REGION_CELLS_X = 256;
const unsigned long REGION_CELLS_Y = 256;
const unsigned long REGION_CELLS = REGION_CELLS_X * REGION_CELLS_Y;
const unsigned long REGION_BLOCKS_X = REGION_CELLS_X * CELL_BLOCKS_X;
const unsigned long REGION_BLOCKS_Y = REGION_CELLS_Y * CELL_BLOCKS_Y;
const unsigned long REGION_BLOCKS = REGION_BLOCKS_X * REGION_BLOCKS_Y;
/******************************/
/******************************
* WORLD
*/
const unsigned long WORLD_REGIONS_X = 32;
const unsigned long WORLD_REGIONS_Y = 32;
const unsigned long WORLD_REGIONS = WORLD_REGIONS_X * WORLD_REGIONS_Y;
const unsigned long WORLD_CELLS_X = WORLD_REGIONS_X * REGION_CELLS_X;
const unsigned long WORLD_CELLS_Y = WORLD_REGIONS_Y * REGION_CELLS_Y;
const unsigned long WORLD_CELLS = WORLD_CELLS_X * WORLD_CELLS_Y;
const unsigned long WORLD_BLOCKS_X = WORLD_REGIONS_X * REGION_BLOCKS_X;
const unsigned long WORLD_BLOCKS_Y = WORLD_REGIONS_Y * REGION_BLOCKS_Y;
//const unsigned long WORLD_BLOCKS = WORLD_BLOCKS_X * WORLD_BLOCKS_Y;
/******************************/
typedef struct {
char Layers;
short *Z;
char *NSWE;
} Block;
/******************************
* NSWE
*/
const char NORTH = 1;
const char SOUTH = 1 << 1;
const char WEST = 1 << 2;
const char EAST = 1 << 3;
/******************************/
/******************************
* CELL TYPES
*/
const char CELL_NULL = 0;
const char CELL_FLAT = 1;
const char CELL_MULTI = 2;
const char CELL_LAYER = 3;
/******************************/
/******************************
* BLOCK TYPE
*/
const char BLOCK_NULL = 0;
const char BLOCK_DATA = 1;
/******************************/
/******************************
* GEODATA FORMAT
*/
const char GEOTYPE_NONOPTIMIZED = 0;
const char GEOTYPE_CELLOPTIMIZED = 1;
const char GEOTYPE_REPEATOPTIMIZED = 2;
/******************************/
#endif
Das wäre alles an SourceCode. Ich verzweifle solangsam daran, da ich den Code
dutzende male überprüft habe, aber aufs Verrecken keinen Fehler finden kann.
GeoEngine_Region() resultiert RLE_FORMAT, und sagt mir das ich ein unbekanten Block Typ habe.
Eine Testdatei lae ich gerade bei rapidshare rauf.
EDIT:
Test Landschaftsinfos: http://rapidshare.com/files/137829157/25_15.zip.html
.txt Datei in den Ordner von BuildZoneConv legen und einen Ordner bmp anlegen. Nun BuildZoneConv mit parameter
25_15 starten.
Best wishes
FBIagent
Zuletzt bearbeitet von einem Moderator: