Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
1364 lines
33 KiB
C++
1364 lines
33 KiB
C++
// TCTd.cpp : super multizone tool !
|
|
//
|
|
|
|
|
|
#include <Stuff\StuffHeaders.hpp>
|
|
#include <MLR\MLRTexturePool.hpp>
|
|
#include <DLLPlatform\DLLPlatform.hpp>
|
|
|
|
#include <ElementRenderer\ElementRenderer.hpp>
|
|
#include <ElementRenderer\GroupElement.hpp>
|
|
#include <ElementRenderer\ListElement.hpp>
|
|
#include <ElementRenderer\SwitchElement.hpp>
|
|
#include <ElementRenderer\ShapeElement.hpp>
|
|
#include <ElementRenderer\GridElement.hpp>
|
|
#include <ElementRenderer\StateChange.hpp>
|
|
#include <MLR\MLRHeaders.hpp>
|
|
#include <gosFX\gosFX.hpp>
|
|
|
|
#include "ImageLib\image.h"
|
|
|
|
#include "HFslimMZ.hpp"
|
|
#include <GameOS\ToolOS.hpp>
|
|
|
|
//#define NON_DEBUG_BUG 1
|
|
|
|
HFSlimMZ *theTerrain;
|
|
|
|
void
|
|
MakeBSP(
|
|
Stuff::DynamicArrayOf<Stuff::Plane> *planes,
|
|
WORD *plane_count,
|
|
ElementRenderer::GroupElement *tile,
|
|
MemoryStream *stream
|
|
);
|
|
|
|
char theName[1024];
|
|
|
|
char contentPath[1024];
|
|
char inputPath[1024];
|
|
|
|
char texturePath[1024];
|
|
char outputPath[1024];
|
|
|
|
void FileExport(HFSlimMZ*, const char *fname);
|
|
void FileExportMaster(int, int, Scalar, Scalar, Scalar, Scalar, const char
|
|
*fname);
|
|
void ImportMegabasetexture(Page *page);
|
|
void ImportExportCulturalMeshs(Page *map_to_convert, const char*, const
|
|
char*, Scalar, Scalar, Scalar, Scalar);
|
|
|
|
FILE *analyzeFile;
|
|
|
|
bool doCulturalsOnly = false;
|
|
const int culturalLocationMax = 64*1024; // this is INSANE
|
|
CulturalLoc culturalLoc[culturalLocationMax];
|
|
int culturalLocCount = 0;
|
|
bool culturalBillboarding[9];
|
|
|
|
|
|
void __stdcall InitializeGameEngine()
|
|
{
|
|
//
|
|
//---------------------
|
|
// Initialize libraries
|
|
//---------------------
|
|
//
|
|
Stuff::InitializeClasses();
|
|
MidLevelRenderer::InitializeClasses(NULL, 32768*16);
|
|
gosFX::InitializeClasses();
|
|
ElementRenderer::InitializeClasses();
|
|
|
|
Stuff::ArmorLevel=1;
|
|
|
|
theTerrain = new HFSlimMZ;
|
|
Register_Pointer(theTerrain);
|
|
|
|
analyzeFile = fopen("analyze.txt", "wt");
|
|
Verify(analyzeFile);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void __stdcall DoGameLogic()
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void __stdcall UpdateDisplay()
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void __stdcall TerminateGameEngine()
|
|
{
|
|
Unregister_Pointer(theTerrain);
|
|
delete theTerrain;
|
|
|
|
fclose(analyzeFile);
|
|
|
|
//
|
|
//-------------------
|
|
// Turn off libraries
|
|
//-------------------
|
|
//
|
|
ElementRenderer::TerminateClasses();
|
|
gosFX::TerminateClasses();
|
|
MidLevelRenderer::TerminateClasses();
|
|
Stuff::TerminateClasses();
|
|
}
|
|
|
|
//
|
|
// Setup the GameOS structure
|
|
//
|
|
void __stdcall GetGameOSEnvironment( char* CommandLine )
|
|
{
|
|
CommandLine = CommandLine;
|
|
Environment.applicationName = "TCT";
|
|
Environment.directoryPath = "\\Tools\\TCTb";
|
|
Environment.screenWidth = 640;
|
|
Environment.screenHeight = 480;
|
|
Environment.fullScreen = FALSE;
|
|
Environment.bitDepth = 16;
|
|
Environment.debugLog = "TCTLog.txt";
|
|
Environment.spew = ""; //"GameOS*";
|
|
|
|
Environment.UpdateRenderers = UpdateDisplay;
|
|
Environment.DoGameLogic = DoGameLogic;
|
|
Environment.InitializeGameEngine = InitializeGameEngine;
|
|
Environment.TerminateGameEngine = TerminateGameEngine;
|
|
|
|
Environment.Renderer = 0;
|
|
Environment.FullScreenDevice = 0;
|
|
|
|
Environment.AntiAlias = 0; // true/false - Enable full screen antialiasing
|
|
|
|
//
|
|
// Texture infomation
|
|
//
|
|
Environment.Texture_S_256 = 13;
|
|
Environment.Texture_S_128 = 12;
|
|
Environment.Texture_S_64 = 1;
|
|
Environment.Texture_S_32 = 1;
|
|
Environment.Texture_S_16 = 1;
|
|
|
|
Environment.Texture_K_256 = 1;
|
|
Environment.Texture_K_128 = 1;
|
|
Environment.Texture_K_64 = 1;
|
|
Environment.Texture_K_32 = 1;
|
|
Environment.Texture_K_16 = 1;
|
|
|
|
Environment.Texture_A_256 = 1;
|
|
Environment.Texture_A_128 = 1;
|
|
Environment.Texture_A_64 = 1;
|
|
Environment.Texture_A_32 = 1;
|
|
Environment.Texture_A_16 = 1;
|
|
}
|
|
|
|
int
|
|
__cdecl main(int argc, char *argv[])
|
|
{
|
|
InitGameOS(NULL, NULL, "blabla");
|
|
InitializeGameEngine();
|
|
|
|
const char *notation_file_name;
|
|
char default_notation_file_name[] = "TCTd.ini";
|
|
|
|
notation_file_name = default_notation_file_name;
|
|
|
|
for(int i=1;i<argc;i++)
|
|
{
|
|
if(NULL!=strstr(argv[i], "-h") || NULL!=strstr(argv[i], "/h"))
|
|
{
|
|
fprintf(stdout, "%s - Terrain Creation Tool\n", argv[0]);
|
|
fprintf(stdout, "If no commandline options are specified TCT is looking for a TCTd.ini in\n");
|
|
fprintf(stdout, "the working directory and none of the options below are true.\n\n");
|
|
fprintf(stdout, "Commandline options:\n");
|
|
fprintf(stdout, "/h - show this help\n");
|
|
fprintf(stdout, "/c - stops after creating Cultural.mlr\n");
|
|
fprintf(stdout, "/p - create a precise, seamless terrain (takes much longer!)\n");
|
|
fprintf(stdout, "/uid - use interest data, height field must be 24-bit\n\tred channel - height info\n\tgreen channel - interest data\n");
|
|
fprintf(stdout, "/bsp - create bsp-files\n");
|
|
fprintf(stdout, "/f filename - use specified file as TCTd.ini file\n");
|
|
fprintf(stdout, "/s - cap the number of points on a per tile base \n");
|
|
fprintf(stdout, "/y - cap the number of points on a per tile base including the surrounding tiles \n");
|
|
fprintf(stdout, "/m - saves density map\n\tred channel - tile density\n\t green channel - order of insertion\n\tblue chanel - number of neighbors \n");
|
|
fprintf(stdout, "/i - sIlent mode - no more PAUSEs \n");
|
|
exit(0);
|
|
}
|
|
|
|
if(NULL!=strstr(argv[i], "-p") || NULL!=strstr(argv[i], "/p"))
|
|
{
|
|
fprintf(stdout, "Precise Mode requested.\n");
|
|
doPrecise = true;
|
|
}
|
|
|
|
if(NULL!=strstr(argv[i], "-uid") || NULL!=strstr(argv[i], "/uid"))
|
|
{
|
|
fprintf(stdout, "Use interest data Mode requested.\n");
|
|
doInterest = true;
|
|
}
|
|
|
|
if(NULL!=strstr(argv[i], "-s") || NULL!=strstr(argv[i], "/s"))
|
|
{
|
|
fprintf(stdout, "Cap triangle count Mode requested.\n");
|
|
doTileCap = true;
|
|
}
|
|
|
|
if(NULL!=strstr(argv[i], "-c") || NULL!=strstr(argv[i], "/c"))
|
|
{
|
|
fprintf(stdout, "Stops executing after creation of Cultural.mlr.\n");
|
|
doCulturalsOnly = true;
|
|
}
|
|
|
|
if(NULL!=strstr(argv[i], "-y") || NULL!=strstr(argv[i], "/y"))
|
|
{
|
|
fprintf(stdout, "Cap triangle count Mode 2 requested.\n");
|
|
doTileCapYovin = true;
|
|
}
|
|
|
|
if(NULL!=strstr(argv[i], "-m") || NULL!=strstr(argv[i], "/m"))
|
|
{
|
|
fprintf(stdout, "Create density map requested. Programm will exit after bitmap creation.\n");
|
|
doDensityMap = true;
|
|
}
|
|
|
|
if(NULL!=strstr(argv[i], "-i") || NULL!=strstr(argv[i], "/i"))
|
|
{
|
|
fprintf(stdout, "Silent mode requested. Program won't be pausing anymore.\n");
|
|
silentMode = true;
|
|
}
|
|
|
|
if(NULL!=strstr(argv[i], "-bsp") || NULL!=strstr(argv[i], "/bsp"))
|
|
{
|
|
fprintf(stdout, "Bsp-file creation requested.\n");
|
|
doBSP = true;
|
|
}
|
|
|
|
if(NULL!=strstr(argv[i], "-f") || NULL!=strstr(argv[i], "/f"))
|
|
{
|
|
notation_file_name = argv[++i];
|
|
fprintf(stdout, "TCTd will use following file as ini-file: %s.\n", notation_file_name);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
//--------------------------------------------------------------
|
|
// Open up the .ini file, and figure out how many map to convert
|
|
//--------------------------------------------------------------
|
|
//
|
|
{
|
|
NotationFile config_file(notation_file_name);
|
|
NotationFile::PageIterator *maps = config_file.MakePageIterator();
|
|
Check_Object(maps);
|
|
|
|
//
|
|
//----------------------------
|
|
// Convert the maps one by one
|
|
//----------------------------
|
|
//
|
|
Page *map_to_convert;
|
|
while ((map_to_convert = maps->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(map_to_convert);
|
|
const char* map = map_to_convert->GetName();
|
|
Check_Pointer(map);
|
|
|
|
const char *path;
|
|
strcpy(contentPath, "Content\\");
|
|
strcpy(texturePath, "Textures\\");
|
|
|
|
const char *default_path = "\\";
|
|
if(!map_to_convert->GetEntry("InputPath", &path))
|
|
{
|
|
path = default_path;
|
|
}
|
|
strncpy(inputPath, path, 1024);
|
|
|
|
fprintf(stdout, "Inputpath: %s\n", inputPath);
|
|
|
|
gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap);
|
|
MidLevelRenderer::TGAFilePool *pool = new MidLevelRenderer::TGAFilePool(texturePath);
|
|
Check_Object(pool);
|
|
MidLevelRenderer::MLRTexturePool::Instance =
|
|
new MidLevelRenderer::MLRTexturePool(pool);
|
|
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
gos_PopCurrentHeap();
|
|
|
|
path = map;
|
|
strncpy(theName, path, 1024);
|
|
fprintf(stdout, "Mapname: %s\n", theName);
|
|
|
|
float dX, dY, dZ;
|
|
if(!map_to_convert->GetEntry("DeltaX", &dX))
|
|
{
|
|
dX = 5.0f;
|
|
}
|
|
if(!map_to_convert->GetEntry("DeltaY", &dY))
|
|
{
|
|
dY = 5.0f;
|
|
}
|
|
if(!map_to_convert->GetEntry("DeltaZ", &dZ))
|
|
{
|
|
dZ = 5.0f;
|
|
}
|
|
fprintf(stdout, "Heighfield size: %f %f %f\n", dX, dY, dZ);
|
|
|
|
theTerrain->SetScale(dX, dY, dZ);
|
|
|
|
const char *map_center;
|
|
Stuff::Scalar map_center_x, map_center_z;
|
|
map_center_x = 0.0f;
|
|
map_center_z = 0.0f;
|
|
if(map_to_convert->GetEntry("MapCenter", &map_center))
|
|
{
|
|
sscanf(map_center, "%f %f", &map_center_x, &map_center_z);
|
|
theTerrain->SetCenter(map_center_x, map_center_z);
|
|
}
|
|
else
|
|
{
|
|
theTerrain->SetCenter(0.0f, 0.0f);
|
|
}
|
|
|
|
ImportExportCulturalMeshs(map_to_convert, inputPath, theName, dX, dZ, map_center_x, map_center_z);
|
|
|
|
if(doCulturalsOnly==false)
|
|
{
|
|
fprintf(stdout, "Start importing the mega texture.\n");
|
|
|
|
if(doBSP==false)
|
|
{
|
|
if(!map_to_convert->GetEntry("WaterLevel", &waterLevel))
|
|
{
|
|
doWater = false;
|
|
}
|
|
else
|
|
{
|
|
doWater = true;
|
|
fprintf(stdout, "Waterlevel found at: %f.\n", waterLevel);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
doWater = false;
|
|
}
|
|
|
|
ImportMegabasetexture(map_to_convert);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stdout,"Culturals done I am going home.");
|
|
}
|
|
}
|
|
}
|
|
|
|
TerminateGameEngine();
|
|
ExitGameOS();
|
|
return 0;
|
|
}
|
|
|
|
bool
|
|
ImportBitmap(Image &timg, int iRBX, int optPolys, int bucketSize, int
|
|
smooth, const char *density_map_name)
|
|
{
|
|
if(timg.GetBpp()<8)
|
|
{
|
|
STOP(("Bitmap Must Be At Least 8 bit - Depth Error\n"));
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if(timg.GetBpp()>8) //Not a Bitmapped Image Resolve
|
|
{
|
|
if(doInterest==true)
|
|
{
|
|
theTerrain->FillInterestDataFromImage(timg);
|
|
iRBX = 0;
|
|
}
|
|
|
|
RMETHOD rmd;
|
|
|
|
switch(iRBX)
|
|
{
|
|
case 0:
|
|
rmd=RMD_REDC;
|
|
break;
|
|
case 1:
|
|
rmd=RMD_GREENC;
|
|
break;
|
|
case 2:
|
|
rmd=RMD_BLUEC;
|
|
break;
|
|
case 3:
|
|
rmd=RMD_ALPHAC;
|
|
break;
|
|
case 4:
|
|
rmd=RMD_MAX;
|
|
break;
|
|
case 5:
|
|
rmd=RMD_BHT;
|
|
break;
|
|
default:
|
|
rmd=RMD_MAX;
|
|
}
|
|
|
|
timg.ReduceTo8Bit(rmd);
|
|
}
|
|
else
|
|
{
|
|
doInterest = false;
|
|
}
|
|
|
|
Verify(timg.GetWidth() % 256 == 0);
|
|
Verify(timg.GetHeight() % 256 == 0);
|
|
|
|
theTerrain->FillFromImage(timg, smooth);
|
|
fprintf(stdout, "Heightfield image loaded.\n");
|
|
|
|
int xDim, zDim;
|
|
theTerrain->GetZoneDimensions(&xDim, &zDim);
|
|
Verify((optPolys > 0) && (bucketSize > 0));
|
|
theTerrain->OptimizeHField(xDim*zDim*optPolys/2, bucketSize, density_map_name);
|
|
|
|
|
|
fprintf(stdout, "Terrain optimized.\n");
|
|
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
ImportCulturalLocationBitmap(Image &timg, int iRBX, Scalar dX, Scalar dZ,
|
|
Scalar xOffset, Scalar zOffset, int max, int min)
|
|
{
|
|
if(timg.GetWidth()!=timg.GetHeight())
|
|
{
|
|
fprintf(stdout, "Bitmap Must Be Square - Dimension Error\n");
|
|
return false;
|
|
}
|
|
|
|
if(timg.GetBpp()<8)
|
|
{
|
|
fprintf(stdout, "Bitmap Must Be At Least 8 bit - Depth Error\n");
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
if(timg.GetBpp()>8) //Not a Bitmapped Image Resolve
|
|
{
|
|
RMETHOD rmd;
|
|
|
|
switch(iRBX)
|
|
{
|
|
case 0:
|
|
rmd=RMD_REDC;
|
|
break;
|
|
case 1:
|
|
rmd=RMD_GREENC;
|
|
break;
|
|
case 2:
|
|
rmd=RMD_BLUEC;
|
|
break;
|
|
case 3:
|
|
rmd=RMD_ALPHAC;
|
|
break;
|
|
case 4:
|
|
rmd=RMD_MAX;
|
|
break;
|
|
case 5:
|
|
rmd=RMD_BHT;
|
|
break;
|
|
default:
|
|
rmd=RMD_MAX;
|
|
}
|
|
|
|
timg.ReduceTo8Bit(rmd);
|
|
}
|
|
|
|
Verify(timg.GetWidth() % 256 == 0);
|
|
Verify(timg.GetHeight() % 256 == 0);
|
|
}
|
|
|
|
BYTE *img = timg.Lock();
|
|
int w = timg.GetHeight();
|
|
int h = timg.GetWidth();
|
|
|
|
for(int j=0;j<w;j++)
|
|
{
|
|
for(int i=0;i<h;i++)
|
|
{
|
|
if(img[j*timg.GetPitch() + i] > 0x80)
|
|
{
|
|
if(culturalLocCount>=culturalLocationMax)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
culturalLoc[culturalLocCount].loc.x = (w-i-1)*dX +
|
|
4.0f*(Random::GetFraction() - 0.5f) - xOffset;
|
|
culturalLoc[culturalLocCount].loc.y = 0.0f;
|
|
culturalLoc[culturalLocCount].loc.z = (h-j-1)*dZ +
|
|
4.0f*(Random::GetFraction() - 0.5f) - zOffset;
|
|
|
|
culturalLoc[culturalLocCount].nr = min + Random::GetLessThan(max);
|
|
|
|
culturalLoc[culturalLocCount].yaw =
|
|
culturalBillboarding[culturalLoc[culturalLocCount].nr] ? 0xff :
|
|
Random::GetLessThan(180);
|
|
|
|
culturalLocCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
MLRShape*
|
|
TraversErfBranch(ElementRenderer::Element *elmt)
|
|
{
|
|
if(elmt->GetClassID() == ElementRenderer::CameraElementClassID)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
switch(elmt->GetClassID())
|
|
{
|
|
case ElementRenderer::GroupElementClassID:
|
|
{
|
|
ElementRenderer::GroupElement *group =
|
|
Cast_Pointer(ElementRenderer::GroupElement *, elmt);
|
|
|
|
Stuff::ChainIteratorOf<ElementRenderer::Element*> *children =
|
|
group->MakeIterator();
|
|
Register_Object(children);
|
|
|
|
ElementRenderer::Element *child = NULL;
|
|
while ((child = children->ReadAndNext()) != NULL)
|
|
{
|
|
TraversErfBranch(child);
|
|
}
|
|
Unregister_Object(children);
|
|
delete children;
|
|
}
|
|
break;
|
|
|
|
case ElementRenderer::ListElementClassID:
|
|
{
|
|
ElementRenderer::ListElement *group =
|
|
Cast_Pointer(ElementRenderer::ListElement *, elmt);
|
|
|
|
for(int i=0;i<group->GetActiveCount();i++)
|
|
{
|
|
TraversErfBranch(group->GetIndexedElement(i));
|
|
}
|
|
}
|
|
break;
|
|
case ElementRenderer::GridElementClassID:
|
|
{
|
|
ElementRenderer::GridElement *group =
|
|
Cast_Pointer(ElementRenderer::GridElement *, elmt);
|
|
|
|
BYTE xSize, zSize;
|
|
group->GetSize(&xSize, &zSize);
|
|
for(BYTE i=0;i<zSize;i++)
|
|
for(BYTE j=0;j<xSize;j++)
|
|
{
|
|
TraversErfBranch( group->GetIndexedElement(i, j));
|
|
}
|
|
}
|
|
break;
|
|
case ElementRenderer::LODElementClassID:
|
|
{
|
|
ElementRenderer::ListElement *group =
|
|
Cast_Pointer(ElementRenderer::ListElement *, elmt);
|
|
|
|
for(int i=0;i<group->GetActiveCount();i++)
|
|
{
|
|
TraversErfBranch(group->GetIndexedElement(i));
|
|
}
|
|
}
|
|
break;
|
|
case ElementRenderer::PointCloudElementClassID:
|
|
{
|
|
}
|
|
break;
|
|
case ElementRenderer::ScalableShapeElementClassID:
|
|
{
|
|
ElementRenderer::ShapeElement *group =
|
|
Cast_Pointer(ElementRenderer::ShapeElement *, elmt);
|
|
return group->GetMLRShape();
|
|
}
|
|
break;
|
|
case ElementRenderer::ScreenQuadsElementClassID:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case ElementRenderer::ShapeElementClassID:
|
|
{
|
|
ElementRenderer::ShapeElement *group =
|
|
Cast_Pointer(ElementRenderer::ShapeElement *, elmt);
|
|
return group->GetMLRShape();
|
|
}
|
|
break;
|
|
case ElementRenderer::SwitchElementClassID:
|
|
{
|
|
ElementRenderer::ListElement *group =
|
|
Cast_Pointer(ElementRenderer::ListElement *, elmt);
|
|
|
|
for(int i=0;i<group->GetActiveCount();i++)
|
|
{
|
|
TraversErfBranch(group->GetIndexedElement(i));
|
|
}
|
|
}
|
|
break;
|
|
case ElementRenderer::TriangleCloudElementClassID:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
ImportExportCulturalMeshs(
|
|
Page *map_to_convert,
|
|
const char *dir,
|
|
const char *missionName,
|
|
Scalar dX, Scalar dZ,
|
|
Scalar xOffset, Scalar zOffset
|
|
)
|
|
{
|
|
gos_PushCurrentHeap(MidLevelRenderer::ShapeHeap);
|
|
MLRShape *outShape = new MLRShape(9);
|
|
gos_PopCurrentHeap();
|
|
ElementRenderer::Element *elm[3] = {NULL, NULL, NULL};
|
|
FileStream fs[3];
|
|
|
|
int count=0, primCount=0, primCounts[3];
|
|
char name[1024];
|
|
|
|
const char *fadeValues;
|
|
if(map_to_convert->GetEntry("CulturalFadeValues", &fadeValues))
|
|
{
|
|
Scalar fadeIn = 50.0f, fadeOut = 80.0f;
|
|
sscanf(fadeValues, "%f %f", &fadeIn, &fadeOut);
|
|
theTerrain->SetCulturalFadeValues(fadeIn, fadeOut);
|
|
}
|
|
|
|
const char *culAname;
|
|
if(map_to_convert->GetEntry("CulturalALocations", &culAname))
|
|
{
|
|
ChainOf<Note*> *nc = map_to_convert->MakeNoteChain("CulturalAObject");
|
|
|
|
ChainIteratorOf<Note*> nci(nc);
|
|
Note *innote;
|
|
while (innote = nci.ReadAndNext())
|
|
{
|
|
const char *value;
|
|
innote->GetEntry(&value);
|
|
|
|
int billboarded;
|
|
|
|
sscanf(value, "%s %d", name, &billboarded);
|
|
MString fname(dir);
|
|
|
|
fname += "Culturals\\";
|
|
fname += name;
|
|
|
|
fs[0].Open(fname);
|
|
|
|
if(fs[0].IsFileOpened()==true)
|
|
{
|
|
gos_PushCurrentHeap(ElementRenderer::g_Heap);
|
|
elm[0] = ElementRenderer::Element::Create(&fs[0], ElementRenderer::ReadERFVersion(&fs[0]));
|
|
gos_PopCurrentHeap();
|
|
|
|
MLRShape *shape = TraversErfBranch(elm[0]);
|
|
|
|
if(shape!=NULL)
|
|
{
|
|
MLRPrimitiveBase *prim = shape->Find(0);
|
|
|
|
MLRState state = prim->GetReferenceState();
|
|
|
|
state.SetFogMode(0);
|
|
|
|
prim->SetReferenceState(state);
|
|
|
|
outShape->Add(prim);
|
|
culturalBillboarding[count++] = billboarded>0 ? true : false;
|
|
}
|
|
}
|
|
}
|
|
delete nc;
|
|
|
|
primCounts[0] = outShape->GetNum() - primCount;
|
|
|
|
if(primCounts[0]>0)
|
|
{
|
|
MString fname(dir);
|
|
fname += "Culturals\\";
|
|
fname += culAname;
|
|
|
|
Image timg;
|
|
timg.Load(fname);
|
|
|
|
if(false==ImportCulturalLocationBitmap(timg, 4, dX, dZ, xOffset, zOffset, primCounts[0], primCount))
|
|
{
|
|
STOP(("Cannot find %s!", fname));
|
|
}
|
|
}
|
|
|
|
primCount = primCounts[0];
|
|
}
|
|
|
|
const char *culBname;
|
|
if(map_to_convert->GetEntry("CulturalBLocations", &culBname))
|
|
{
|
|
ChainOf<Note*> *nc = map_to_convert->MakeNoteChain("CulturalBObject");
|
|
|
|
ChainIteratorOf<Note*> nci(nc);
|
|
Note *innote;
|
|
while (innote = nci.ReadAndNext())
|
|
{
|
|
MString fname(dir);
|
|
fname += "Culturals\\";
|
|
|
|
const char *value;
|
|
innote->GetEntry(&value);
|
|
|
|
int billboarded;
|
|
|
|
sscanf(value, "%s %d", name, &billboarded);
|
|
|
|
fname += name;
|
|
|
|
fs[1].Open(fname);
|
|
|
|
if(fs[1].IsFileOpened()==true)
|
|
{
|
|
gos_PushCurrentHeap(ElementRenderer::g_Heap);
|
|
elm[1] = ElementRenderer::Element::Create(&fs[1], ElementRenderer::ReadERFVersion(&fs[1]));
|
|
gos_PopCurrentHeap();
|
|
|
|
MLRShape *shape = TraversErfBranch(elm[1]);
|
|
|
|
if(shape!=NULL)
|
|
{
|
|
MLRPrimitiveBase *prim = shape->Find(0);
|
|
|
|
MLRState state = prim->GetReferenceState();
|
|
|
|
state.SetFogMode(0);
|
|
|
|
prim->SetReferenceState(state);
|
|
|
|
outShape->Add(prim);
|
|
culturalBillboarding[count++] = billboarded>0 ? true : false;
|
|
}
|
|
}
|
|
}
|
|
delete nc;
|
|
|
|
primCounts[1] = outShape->GetNum() - primCount;
|
|
|
|
if(primCounts[1]>0)
|
|
{
|
|
MString fname(dir);
|
|
fname += "Culturals\\";
|
|
fname += culBname;
|
|
|
|
Image timg;
|
|
timg.Load(fname);
|
|
|
|
if(false==ImportCulturalLocationBitmap(timg, 4, dX, dZ, xOffset, zOffset, primCounts[1], primCount))
|
|
{
|
|
STOP(("Cannot find %s!", fname));
|
|
}
|
|
}
|
|
primCount += primCounts[1];
|
|
}
|
|
|
|
const char *culCname;
|
|
if(map_to_convert->GetEntry("CulturalCLocations", &culCname))
|
|
{
|
|
ChainOf<Note*> *nc = map_to_convert->MakeNoteChain("CulturalCObject");
|
|
|
|
ChainIteratorOf<Note*> nci(nc);
|
|
Note *innote;
|
|
while (innote = nci.ReadAndNext())
|
|
{
|
|
const char *value;
|
|
innote->GetEntry(&value);
|
|
|
|
int billboarded;
|
|
|
|
sscanf(value, "%s %d", name, &billboarded);
|
|
MString fname(dir);
|
|
|
|
fname += "Culturals\\";
|
|
fname += name;
|
|
|
|
fs[2].Open(fname);
|
|
|
|
if(fs[2].IsFileOpened()==true)
|
|
{
|
|
gos_PushCurrentHeap(ElementRenderer::g_Heap);
|
|
elm[2] = ElementRenderer::Element::Create(&fs[2], ElementRenderer::ReadERFVersion(&fs[2]));
|
|
gos_PopCurrentHeap();
|
|
|
|
MLRShape *shape = TraversErfBranch(elm[2]);
|
|
|
|
if(shape!=NULL)
|
|
{
|
|
MLRPrimitiveBase *prim = shape->Find(0);
|
|
|
|
MLRState state = prim->GetReferenceState();
|
|
|
|
state.SetFogMode(0);
|
|
|
|
prim->SetReferenceState(state);
|
|
|
|
outShape->Add(prim);
|
|
culturalBillboarding[count++] = billboarded>0 ? true : false;
|
|
}
|
|
}
|
|
}
|
|
delete nc;
|
|
|
|
primCounts[2] = outShape->GetNum() - primCount;
|
|
|
|
if(primCounts[2]>0)
|
|
{
|
|
MString fname(dir);
|
|
fname += "Culturals\\";
|
|
fname += culCname;
|
|
|
|
Image timg;
|
|
timg.Load(fname);
|
|
|
|
if(false==ImportCulturalLocationBitmap(timg, 4, dX, dZ, xOffset, zOffset, primCounts[2], primCount))
|
|
{
|
|
STOP(("Cannot find %s!", fname));
|
|
}
|
|
}
|
|
|
|
primCount += primCounts[2];
|
|
}
|
|
|
|
if(primCount>0)
|
|
{
|
|
MString fname(dir);
|
|
|
|
fname += missionName;
|
|
fname += "Culturals.mlr";
|
|
|
|
if(gos_FileReadOnly(fname)==false)
|
|
{
|
|
FileStream fs(fname, FileStream::WriteOnly);
|
|
|
|
if(fs.IsFileOpened()==true)
|
|
{
|
|
WriteMLRVersion(&fs);
|
|
|
|
OBB obb;
|
|
obb = OBB::Identity;
|
|
obb.sphereRadius = 5.0f;
|
|
|
|
fs << obb;
|
|
|
|
fs << outShape->GetClassID();
|
|
fs << (BYTE)outShape->GetNum();
|
|
|
|
int i;
|
|
MLRPrimitiveBase *prim;
|
|
// MLR_I_TMesh *tmesh;
|
|
|
|
for(i=0;i<outShape->GetNum();i++)
|
|
{
|
|
prim = outShape->Find(i);
|
|
prim->Save(&fs);
|
|
// tmesh = Cast_Object(MLR_I_TMesh*, prim);
|
|
// tmesh->MLR_I_TMesh::Save(&fs);
|
|
}
|
|
|
|
char mapDataFileName[1024];
|
|
sprintf(mapDataFileName, "Content\\Maps\\%s\\%s.data", theName, theName);
|
|
NotationFile mapData(mapDataFileName);
|
|
|
|
Page *page = mapData.FindPage("GameData");
|
|
|
|
if(page!=NULL)
|
|
{
|
|
sprintf(mapDataFileName, "Content\\Maps\\%s\\%sCulturals.mlr", missionName, missionName);
|
|
page->SetEntry("CulturalData", mapDataFileName);
|
|
|
|
mapData.Save();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
STOP(("File %s is read-only!", fname));
|
|
}
|
|
}
|
|
|
|
if(elm[0]!=NULL)
|
|
{
|
|
delete elm[0];
|
|
}
|
|
|
|
if(elm[1]!=NULL)
|
|
{
|
|
delete elm[1];
|
|
}
|
|
|
|
if(elm[2]!=NULL)
|
|
{
|
|
delete elm[2];
|
|
}
|
|
}
|
|
|
|
bool
|
|
ImportBitmap(const char *fname, int iRBX, int optPolys, int bucketSize, int smooth, const char *density_map_name)
|
|
{
|
|
Image timg;
|
|
char tfn[MAX_PATH];
|
|
|
|
strcpy(tfn, fname);
|
|
timg.Load(tfn);
|
|
return ImportBitmap(timg, iRBX, optPolys, bucketSize, smooth, density_map_name);
|
|
}
|
|
|
|
void
|
|
ImportMegabasetexture(
|
|
Page *map_to_convert
|
|
)
|
|
{
|
|
char buf[MAX_PATH];
|
|
|
|
GetCurrentDirectory(MAX_PATH, buf);
|
|
|
|
Check_Object(map_to_convert);
|
|
|
|
const char *hf_name;
|
|
if(!map_to_convert->GetEntry("HeightField", &hf_name))
|
|
{
|
|
SetCurrentDirectory(buf);
|
|
return;
|
|
}
|
|
|
|
int polyCount = 5000;
|
|
map_to_convert->GetEntry("PolyCount", &polyCount);
|
|
int bucketSize = 64;
|
|
map_to_convert->GetEntry("BucketSize", &bucketSize);
|
|
|
|
if(bucketSize>Limits::Max_Number_Vertices_Per_Mesh/2)
|
|
{
|
|
bucketSize = Limits::Max_Number_Vertices_Per_Mesh/2;
|
|
}
|
|
|
|
int smoothPass = 2;
|
|
map_to_convert->GetEntry("SmoothingPasses", &smoothPass);
|
|
|
|
int xDim, zDim;
|
|
char hf_path[1024], density_map_name[1024];
|
|
strcpy(hf_path, inputPath);
|
|
strcat(hf_path, hf_name);
|
|
|
|
sprintf(density_map_name, "%sdensity_%s", inputPath, hf_name);
|
|
|
|
if(false==ImportBitmap(hf_path, 0, polyCount, bucketSize, smoothPass, density_map_name))
|
|
{
|
|
SetCurrentDirectory(buf);
|
|
return;
|
|
}
|
|
|
|
int borderPix = 0;
|
|
map_to_convert->GetEntry("BorderPixels", &borderPix);
|
|
int nrOfLevels = 3;
|
|
map_to_convert->GetEntry("NumberOfLevels", &nrOfLevels);
|
|
fprintf(stdout, "HF: %s pc: %d bs: %d l: %d\n", hf_name, polyCount, bucketSize, nrOfLevels);
|
|
|
|
theTerrain->SetAllDepth(nrOfLevels);
|
|
|
|
theTerrain->GetZoneDimensions(&xDim, &zDim);
|
|
|
|
const char *mega_detail_name;
|
|
if(!map_to_convert->GetEntry("DetailTexture", &mega_detail_name))
|
|
{
|
|
SetCurrentDirectory(buf);
|
|
return;
|
|
}
|
|
char detailName[1024];
|
|
// sprintf(detailName, "Maps\\%s\\%s", theName, mega_detail_name);
|
|
strncpy(detailName, mega_detail_name, 1023);
|
|
|
|
char underWaterDetailName[1024];
|
|
char waterTextureName[1024];
|
|
char waterDetailName[1024];
|
|
|
|
const char *under_water_detail_name = NULL;
|
|
const char *water_texture_name = NULL;
|
|
const char *water_detail_texture_name = NULL;
|
|
|
|
Scalar waterTextureRatio = 4.0f;
|
|
Scalar waterDetailTextureRatio = 4.0f;
|
|
int waterMovieFrames = 1;
|
|
int waterDetailMovieFrames = 1;
|
|
|
|
if(doWater==true)
|
|
{
|
|
|
|
if(map_to_convert->GetEntry("UnderwaterdetailTexture", &under_water_detail_name))
|
|
{
|
|
// sprintf(underWaterDetailName, "Maps\\%s\\%s", theName, under_water_detail_name);
|
|
strncpy(underWaterDetailName, under_water_detail_name, 1023);
|
|
under_water_detail_name = underWaterDetailName;
|
|
}
|
|
else
|
|
{
|
|
under_water_detail_name = NULL;
|
|
}
|
|
|
|
|
|
if(map_to_convert->GetEntry("WaterTexture", &water_texture_name))
|
|
{
|
|
// sprintf(waterTextureName, "Maps\\%s\\%s", theName, water_texture_name);
|
|
strncpy(waterTextureName, water_texture_name, 1023);
|
|
water_texture_name = waterTextureName;
|
|
}
|
|
else
|
|
{
|
|
water_texture_name = NULL;
|
|
}
|
|
|
|
map_to_convert->GetEntry("WaterTextureMovieFrames", &waterMovieFrames);
|
|
|
|
if(map_to_convert->GetEntry("WaterDetailTexture", &water_detail_texture_name))
|
|
{
|
|
// sprintf(waterDetailName, "Maps\\%s\\%s", theName, water_detail_texture_name);
|
|
strncpy(waterDetailName, water_detail_texture_name, 1023);
|
|
water_detail_texture_name = waterDetailName;
|
|
}
|
|
else
|
|
{
|
|
water_detail_texture_name = NULL;
|
|
}
|
|
|
|
map_to_convert->GetEntry("WaterDetailTextureMovieFrames", &waterDetailMovieFrames);
|
|
|
|
char mapDataFileName[1024];
|
|
sprintf(mapDataFileName, "Content\\Maps\\%s\\%s.data", theName, theName);
|
|
NotationFile mapData(mapDataFileName);
|
|
|
|
Page *page = mapData.FindPage("GameData");
|
|
|
|
if(page!=NULL)
|
|
{
|
|
page->SetEntry("WaterLevel", waterLevel);
|
|
if(under_water_detail_name!=NULL)
|
|
{
|
|
page->SetEntry("UnderWaterTexture", under_water_detail_name);
|
|
}
|
|
|
|
if(water_texture_name!=NULL)
|
|
{
|
|
page->SetEntry("WaterTexture", water_texture_name);
|
|
}
|
|
|
|
if(water_detail_texture_name!=NULL)
|
|
{
|
|
page->SetEntry("WaterDetailTexture", water_detail_texture_name);
|
|
}
|
|
|
|
mapData.Save();
|
|
}
|
|
|
|
map_to_convert->GetEntry("WaterTextureRatio", &waterTextureRatio);
|
|
map_to_convert->GetEntry("WaterDetailRatio", &waterDetailTextureRatio);
|
|
|
|
theTerrain->SetWaterInfo(water_texture_name, waterTextureRatio, waterMovieFrames);
|
|
}
|
|
|
|
|
|
Scalar ratio = 16.0f;
|
|
map_to_convert->GetEntry("DetailRatio", &ratio);
|
|
Scalar dStart = 32.0f;
|
|
map_to_convert->GetEntry("DetailFadeBegin", &dStart);
|
|
Scalar dEnd = 64.0f;
|
|
map_to_convert->GetEntry("DetailFadeEnd", &dEnd);
|
|
|
|
const char *mega_alpha_name;
|
|
MLRState::AlphaMode alpha;
|
|
|
|
if(map_to_convert->GetEntry("DetailAlphaMode", &mega_alpha_name))
|
|
{
|
|
if(!strncmp(mega_alpha_name, "oneone", sizeof("oneone")))
|
|
{
|
|
alpha = MLRState::OneOneMode;
|
|
} else
|
|
if(!strncmp(mega_alpha_name, "alphainvalpha", sizeof("alphainvalpha")))
|
|
{
|
|
alpha = MLRState::AlphaInvAlphaMode;
|
|
} else
|
|
if(!strncmp(mega_alpha_name, "oneinvalpha", sizeof("oneinvalpha")))
|
|
{
|
|
alpha = MLRState::OneInvAlphaMode;
|
|
} else {
|
|
alpha = MLRState::AlphaOneMode;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
alpha = MLRState::AlphaInvAlphaMode;
|
|
}
|
|
|
|
theTerrain->SetWaterDetailTextureInfo(
|
|
water_detail_texture_name,
|
|
0.0f,
|
|
0.0f,
|
|
waterDetailTextureRatio,
|
|
waterDetailTextureRatio,
|
|
dStart,
|
|
dEnd,
|
|
alpha,
|
|
waterDetailMovieFrames
|
|
);
|
|
|
|
|
|
theTerrain->SetBorderPixels(borderPix);
|
|
|
|
theTerrain->SetDetailTextureInfo(
|
|
detailName,
|
|
under_water_detail_name,
|
|
0.0f,
|
|
0.0f,
|
|
ratio,
|
|
ratio,
|
|
dStart,
|
|
dEnd,
|
|
alpha
|
|
);
|
|
|
|
#ifdef NON_DEBUG_BUG
|
|
fprintf(stdout, "\nCalling SetMegaTexture");
|
|
#endif
|
|
|
|
if(true == theTerrain->SetMegaTexture(
|
|
nrOfLevels,
|
|
bucketSize,
|
|
theName,
|
|
outputPath)
|
|
)
|
|
{
|
|
#ifdef NON_DEBUG_BUG
|
|
fprintf(stdout, "\nCalling SetMegaTexture (tctd) (returned TRUE)");
|
|
#endif
|
|
theTerrain->SetCulturals(culturalLoc, culturalLocCount);
|
|
#ifdef NON_DEBUG_BUG
|
|
fprintf(stdout, "\nCalling SetMegaTexture (SetCulturals)");
|
|
#endif
|
|
FileExport(theTerrain, outputPath);
|
|
#ifdef NON_DEBUG_BUG
|
|
fprintf(stdout, "\nCalling SetMegaTexture (FileExport)");
|
|
#endif
|
|
}
|
|
#ifdef NON_DEBUG_BUG
|
|
fprintf(stdout, "\nCalling SetMegaTexture (done)");
|
|
#endif
|
|
|
|
sprintf(outputPath, "%sMaps\\%s\\%s.erf", contentPath, theName, theName);
|
|
#ifdef NON_DEBUG_BUG
|
|
fprintf(stdout, "\n%s", outputPath);
|
|
#endif
|
|
FileExportMaster(
|
|
xDim, zDim,
|
|
theTerrain->GetCenterX(), theTerrain->GetCenterZ(),
|
|
theTerrain->GetXScale(), theTerrain->GetZScale(),
|
|
outputPath
|
|
);
|
|
|
|
SetCurrentDirectory(buf);
|
|
}
|
|
|
|
bool Debug_Tile=false;
|
|
bool Debug_Zone=false;
|
|
|
|
void
|
|
ZoneExport(
|
|
ElementRenderer::GridElement *terrain,
|
|
const char* zone_filename
|
|
)
|
|
{
|
|
Check_Object(terrain);
|
|
Check_Pointer(zone_filename);
|
|
|
|
//
|
|
//--------------------------------------------------------
|
|
// Make a memory stream array to avoid reallocating memory
|
|
//--------------------------------------------------------
|
|
//
|
|
DynamicArrayOf<DynamicMemoryStream *> tile_streams(64);
|
|
int triangle_count = terrain->CountTriangles();
|
|
Verify(triangle_count < 32768);
|
|
DynamicArrayOf<Plane> planes(triangle_count*2);
|
|
WORD plane_count = 0;
|
|
|
|
//
|
|
//---------------------------
|
|
// Step through all the tiles
|
|
//---------------------------
|
|
//
|
|
int t;
|
|
for (t=0; t<64; ++t)
|
|
{
|
|
tile_streams[t] = new DynamicMemoryStream;
|
|
Check_Object(tile_streams[t]);
|
|
ElementRenderer::GroupElement *tile =
|
|
Cast_Object(
|
|
ElementRenderer::GroupElement*,
|
|
terrain->GetIndexedElement(t)
|
|
);
|
|
Check_Object(tile);
|
|
|
|
//
|
|
//-----------------------------------------------
|
|
// For each tile, run the collision process on it
|
|
//-----------------------------------------------
|
|
//
|
|
fprintf(stdout, "\r Working on tile %d", t);
|
|
MakeBSP(&planes, &plane_count, tile, tile_streams[t]);
|
|
}
|
|
fprintf(stdout, "\r Used %d planes \n", plane_count);
|
|
|
|
//
|
|
//------------------------------------------
|
|
// Copy the stream info into the output file
|
|
//------------------------------------------
|
|
//
|
|
Stuff::FileStream zone_stream(zone_filename, Stuff::FileStream::WriteOnly);
|
|
zone_stream << plane_count;
|
|
zone_stream.WriteBytes(planes.GetData(), plane_count * sizeof(Plane));
|
|
for (t=0; t<64; ++t)
|
|
{
|
|
Check_Object(tile_streams[t]);
|
|
tile_streams[t]->Rewind();
|
|
zone_stream << tile_streams[t]->GetSize() << *tile_streams[t];
|
|
Check_Object(tile_streams[t]);
|
|
delete tile_streams[t];
|
|
}
|
|
}
|
|
|
|
void
|
|
FileExport(HFSlimMZ *tT, const char *output_path)
|
|
{
|
|
//
|
|
//---------------------------------------------------
|
|
// Analyze the set file and extract the useful pieces
|
|
//---------------------------------------------------
|
|
//
|
|
|
|
int i, j, xDim, zDim;
|
|
tT->GetZoneDimensions(&xDim, &zDim);
|
|
|
|
Stuff::DynamicArrayOf<ElementRenderer::GridElement*> *terrainArray;
|
|
|
|
terrainArray = tT->GetTerrainArray();
|
|
|
|
ElementRenderer::GridElement *terrain;
|
|
|
|
for(j=0;j<zDim;j++)
|
|
{
|
|
for(i=0;i<xDim;i++)
|
|
{
|
|
terrain = (*terrainArray)[j*xDim+i];
|
|
Check_Object(terrain);
|
|
|
|
if(doBSP==true)
|
|
{
|
|
fprintf(stdout, "Processing zone %c%c\n", 'A'+j, 'A'+i);
|
|
sprintf(outputPath, "%sMaps\\%s\\%c%c.bsp", contentPath, theName, 'A'+j, 'A'+i);
|
|
ZoneExport(terrain, outputPath);
|
|
}
|
|
else
|
|
{
|
|
sprintf(outputPath, "%sMaps\\%s\\%c%c.erf", contentPath, theName, 'A'+j, 'A'+i);
|
|
|
|
Stuff::FileStream element_stream(output_path, Stuff::FileStream::WriteOnly);
|
|
|
|
if(element_stream.IsFileOpened()==true)
|
|
{
|
|
fprintf(stdout, "Saving file %s.\n", outputPath);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stdout, "Couldn't open file %s.\n", outputPath);
|
|
}
|
|
|
|
ElementRenderer::WriteERFVersion(&element_stream);
|
|
|
|
int row, col;
|
|
for (row=0; row<8; ++row)
|
|
{
|
|
for (col=0; col<8; ++col)
|
|
{
|
|
ElementRenderer::GroupElement *group =
|
|
Cast_Object(
|
|
ElementRenderer::GroupElement*,
|
|
terrain->GetIndexedElement(row, col)
|
|
);
|
|
Stuff::ChainIteratorOf<ElementRenderer::Element*>* iterator = group->MakeIterator();
|
|
Check_Object(iterator);
|
|
ElementRenderer::Element *element = iterator->GetCurrent();
|
|
Check_Object(element);
|
|
Verify(element->GetLocalToWorld() == Stuff::LinearMatrix4D::Identity);
|
|
ElementRenderer::StateChange *state = new ElementRenderer::StateChange;
|
|
state->SetLightingMode(MidLevelRenderer::MLRState::TerrainLightingMode);
|
|
element->AdoptStateChange(state);
|
|
element->Save(&element_stream);
|
|
Check_Object(iterator);
|
|
delete iterator;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
FileExportMaster(int xDim, int zDim, Scalar mapCenterX, Scalar mapCenterZ, Scalar xGrid, Scalar zGrid, const char *output_path)
|
|
{
|
|
gos_PushCurrentHeap(ElementRenderer::GridElement::s_Heap);
|
|
ElementRenderer::GridElement *terrain =
|
|
new ElementRenderer::GridElement(
|
|
zDim, xDim,
|
|
-mapCenterZ, -mapCenterX,
|
|
zDim*256*zGrid, xDim*256*xGrid
|
|
);
|
|
|
|
terrain->SetSize(0);
|
|
gos_PopCurrentHeap();
|
|
|
|
//
|
|
//---------------------------------------------------
|
|
// Analyze the set file and extract the useful pieces
|
|
//---------------------------------------------------
|
|
//
|
|
|
|
terrain->SetRootMode();
|
|
|
|
Stuff::FileStream element_stream(output_path,
|
|
Stuff::FileStream::WriteOnly);
|
|
ElementRenderer::WriteERFVersion(&element_stream);
|
|
terrain->Save(&element_stream);
|
|
} // end of export
|
|
|