Files
firestorm/Gameleap/code/mw4/Tools/TCTb/TCTd0p3.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
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.
2026-06-24 21:28:16 -05:00

574 lines
14 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 <MLR\MLRHeaders.hpp>
#include <gosFX\gosFX.hpp>
#include "ImageLib\image.h"
#include "HFslimMZ0p3.hpp"
//#define NON_DEBUG_BUG 1
HFSlimMZ0p3 *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(HFSlimMZ0p3*, const char *fname);
void FileExportMaster(int, int, Scalar, Scalar, const char *fname);
void ImportMegabasetexture(Page *map_to_convert);
FILE *analyzeFile;
void __stdcall InitializeGameEngine()
{
//
//---------------------
// Initialize libraries
//---------------------
//
Stuff::InitializeClasses();
MidLevelRenderer::InitializeClasses(32768*16);
gosFX::InitializeClasses();
ElementRenderer::InitializeClasses();
theTerrain = new HFSlimMZ0p3;
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()
{
InitGameOS(NULL, NULL, "blabla");
InitializeGameEngine();
//
//--------------------------------------------------------------
// Open up the .ini file, and figure out how many map to convert
//--------------------------------------------------------------
//
{
NotationFile config_file("TCTd.ini");
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::Heap);
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);
fprintf(stdout, "Start importing the mega texture.\n");
ImportMegabasetexture(map_to_convert);
}
}
TerminateGameEngine();
ExitGameOS();
return 0;
}
bool
ImportBitmap(Image &timg, int iRBX, int optPolys, int bucketSize, int smooth)
{
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);
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);
fprintf(stdout, "Terrain optimized.\n");
}
return true;
}
bool
ImportBitmap(const char *fname, int iRBX, int optPolys, int bucketSize, int smooth)
{
Image timg;
char tfn[MAX_PATH];
strcpy(tfn, fname);
timg.Load(tfn);
return ImportBitmap(timg, iRBX, optPolys, bucketSize, smooth);
}
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);
int smoothPass = 2;
map_to_convert->GetEntry("SmoothingPasses", &smoothPass);
int xDim, zDim;
char hf_path[1024];
strcpy(hf_path, inputPath);
strcat(hf_path, hf_name);
if(false==ImportBitmap(hf_path, 4, polyCount, bucketSize, smoothPass))
{
SetCurrentDirectory(buf);
return;
}
int borderPix = 0;
map_to_convert->GetEntry("BorderPixels", &borderPix);
int nrOfLevels = 1;
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);
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::AlphaOneMode;
}
theTerrain->SetDetailTextureInfo(
detailName,
0.0f,
0.0f,
ratio,
ratio,
dStart,
dEnd,
alpha
);
theTerrain->SetBorderPixels(borderPix);
#ifdef NON_DEBUG_BUG
fprintf(stdout, "\nCalling SetMegaTexture (2)");
#endif
if(true == theTerrain->SetMegaTexture(
nrOfLevels,
bucketSize,
theName)
)
{
#ifdef NON_DEBUG_BUG
fprintf(stdout, "\nCalling SetMegaTexture (tctd0p3) (returned TRUE)");
#endif
FileExport(theTerrain, outputPath);
}
#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->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];
Unregister_Object(tile_streams[t]);
delete tile_streams[t];
}
}
void
FileExport(HFSlimMZ0p3 *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*zDim+i];
Check_Object(terrain);
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);
sprintf(outputPath, "%sMaps\\%s\\%c%c.erf", contentPath, theName, 'A'+j, 'A'+i);
Stuff::FileStream element_stream(output_path, Stuff::FileStream::WriteOnly);
ElementRenderer::WriteERFVersion(&element_stream);
for (int row=0; row<8; ++row)
{
for (int col=0; col<8; ++col)
{
ElementRenderer::GroupElement *group =
Cast_Object(
ElementRenderer::GroupElement*,
terrain->GetIndexedElement(row, col)
);
Stuff::ChainIteratorOf<Element*>* iterator = group->MakeIterator();
Check_Object(iterator);
Element *element = iterator->GetCurrent();
Check_Object(element);
Verify(element->GetLocalToWorld() == Stuff::LinearMatrix4D::Identity);
ElementRenderer::StateChange *state = new ElementRenderer::StateChange;
state->SetLightingMode(ElementRenderer::StateChange::TerrainMode);
element->AdoptStateChange(state);
element->Save(&element_stream);
Unregister_Object(iterator);
delete iterator;
}
}
}
}
}
void
FileExportMaster(int xDim, int zDim, Scalar xGrid, Scalar zGrid, const char *output_path)
{
gos_PushCurrentHeap(ElementRenderer::Heap);
ElementRenderer::GridElement *terrain = new ElementRenderer::GridElement(xDim, zDim, 0.0f, 0.0f, xDim*256*xGrid, zDim*256*zGrid);
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