#include <acknex.h>
// -----------------------------------------------------------------------------------------------------
STRING *strFilename = NULL;
STRING *strOptions = "";
// -----------------------------------------------------------------------------------------------------
// Levels
TEXT *txtLevels =
{
string = (
"level00.$$M",
"level01.$$M"
);
}
// Compilation configurations for each level
// They can be copied from 'buildlog.txt' file created by WED compilation process
TEXT *txtConfigs =
{
string = (
" -pal palette.pcx -az 0 -el 60 -sunrgb 58 58 58 -ambrgb 19 19 19 -fog1 100 100 100 -fog2 19 39 100 -fog3 100 19 19 -noportals -hiprec -litmapsonly -writelog -mesh -mergeacross -terralit -tesselate -close -solidsky -nodetail -quiet -supsam -threads 4 -gamma 2.25 -phongangle 120 -lmambient 50 -sizeshaded 236 -litres 0.37 -litcomp 0.20 -litmax 255 -litscale 0.68 -radsubdiv 64 -radbounce 3 -bound 56000 -fat 64 48 8 -narrow 32 32 0"
" -pal palette.pcx -az 0 -el 60 -sunrgb 58 58 58 -ambrgb 19 19 19 -fog1 100 100 100 -fog2 19 39 100 -fog3 100 19 19 -noportals -hiprec -litmapsonly -writelog -mesh -mergeacross -terralit -tesselate -close -solidsky -nodetail -quiet -supsam -threads 4 -gamma 2.25 -phongangle 120 -lmambient 50 -sizeshaded 236 -litres 0.37 -litcomp 0.20 -litmax 255 -litscale 0.68 -radsubdiv 64 -radbounce 3 -bound 56000 -fat 64 48 8 -narrow 32 32 0"
);
}
// -----------------------------------------------------------------------------------------------------
// A buffer and a position and size control in order to hold all the entity related data
typedef struct
{
char buffer[6000];
char *chr;
long size;
} ENT_BUFFER;
ENT_BUFFER entBuffer;
void entBuffer_startup ()
{
entBuffer.chr = entBuffer.buffer;
entBuffer.size = 0;
}
// Add a string to the entities buffer
void entBufferAddString ( STRING *_str )
{
long _size = str_len ( _str );
memcpy ( entBuffer.chr, _str->chars, _size );
entBuffer.chr += _size;
*entBuffer.chr = 13; // [Enter]
entBuffer.chr ++;
*entBuffer.chr = 10; // Linebreak
entBuffer.chr ++;
entBuffer.size += _size + 2;
}
// Add a char buffer to the entities buffer
void entBufferAdd ( char *_chr, long _size )
{
memcpy ( entBuffer.chr, _chr, _size );
entBuffer.chr += _size;
entBuffer.size += _size;
}
// -----------------------------------------------------------------------------------------------------
void main ()
{
wait(1);
var levelIndex = 0;
// Loop through all levels
for ( ; levelIndex<txtLevels->strings; levelIndex+=1 )
{
// Get the pointer to the level name string
strFilename = (txtLevels->pstring)[levelIndex];
// Check the existence of the level file
if ( !file_exists ( strFilename ) )
{
str_cpy ( strFilename, " file not found!" );
error ( strFilename );
break;
}
// Add level name to entities buffer
entBufferAddString ( strFilename );
// A variable will contain the size of the file buffer
long sizeFile;
// Load the file into a buffer allocated by the engine
char *bufferStart = file_load ( strFilename, NULL, &sizeFile );
// Make a copy of the file buffer in order to restore the file after compiling
char *bufferBackup = sys_malloc ( sizeFile );
memcpy ( bufferBackup, bufferStart, sizeFile );
// A pointer to hold the starting byte of a detected entity
char *entityBlock = NULL;
// A variable will contain the size of the modified file buffer. It is same as the original file buffer size at the beginning
long sizeResult = sizeFile;
// A pointer to go through the buffer
char *buffer = bufferStart;
// Go through the buffer byte by byte
for ( ; buffer<bufferStart+sizeResult; buffer++ )
{
// If a description of a model has been previously detected
if ( entityBlock )
{
// If the pointed byte is a closing bracket
if ( *buffer == 125 ) // }
{
// Compute the size of the entity description block
long sizeBlock = 3 + (long)buffer - (long)entityBlock;
// Add the entity block to the entities buffer
entBufferAdd ( entityBlock, sizeBlock );
// Compute the size of the remaining buffer
long sizeRemaining = sizeResult - ( (long)buffer - (long)bufferStart );
// Move the remaining buffer to the starting byte of the entity, so the entity is completelly removed from the file buffer
memcpy ( entityBlock, buffer+3, sizeRemaining );
// Reduce the size of the file buffer by the size of the entity block
sizeResult -= sizeBlock;
// Move the buffer cheking pointer to the start of the remaining buffer, as it has been moved
buffer = entityBlock - 1;
// Remove previously saved starting byte
entityBlock = NULL;
}
}
else // If a description of a model has not been previously detected
{
// If the pointed byte is an opening bracket
if ( *buffer == 123 ) // {
{
// Look for the word 'model' into the remaining buffer
var pos = str_stri ( buffer, "model" );
// If it exists
if ( pos )
{
// If it exists near the opening bracket
if ( pos < 10 )
{
// Save the the actual byte as the starting byte of the description of a model
entityBlock = buffer;
}
}
else // If it does not exists
{
// There is no reason to continue looking into the buffer
// Break the loop
break;
}
}
}
}
// Save the modified buffer, with no models, in order to compile the empty level
file_save ( strFilename, bufferStart, sizeResult );
// Build the configuration for compiling process
str_cpy ( strOptions, strFilename );
str_cat ( strOptions, (txtConfigs->pstring)[levelIndex] );
// Compile the level
exec_wait ( "wwmp2wmb.exe", strOptions );
// Restore the level file to its initial state
file_save ( strFilename, bufferBackup, sizeFile );
// Remove the level buffer
file_load ( NULL, bufferStart, &sizeFile );
// Remove the level buffer copy
sys_free ( bufferBackup );
}
// If everything went fine
if ( levelIndex == txtLevels->strings )
{
// Save the entities buffer
file_save ( "level_entities.txt", entBuffer.buffer, entBuffer.size );
}
// Exit the program ;)
sys_exit ( NULL );
}