Files
firestorm/Gameleap/code/mw4/Tools/TCTb/TCTc.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

538 lines
12 KiB
C++

// TCTc.cpp : Defines the class behaviors for the application.
//
#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\MLR.hpp>
#include <MLR\MLRHeaders.hpp>
#include "ImageLib\image.h"
#include "HFslim.hpp"
HFSlim *theTerrain;
char theName[1024];
char texturePath[1024];
char outputPath[1024];
DetailLevelInfo detailLevelInfo;
void FileExport(const char *fname);
void ImportMegabasetexture(NotationFile *mega_file);
FILE *analyzeFile;
void InitializeGameEngine()
{
//
//---------------------
// Initialize libraries
//---------------------
//
Stuff::InitializeClasses();
MidLevelRenderer::InitializeClasses(32768*16);
ElementRenderer::InitializeClasses();
analyzeFile = fopen("analyze.txt", "wt");
Verify(analyzeFile);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void DoGameLogic()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void UpdateDisplay()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void TerminateGameEngine()
{
fclose(analyzeFile);
//
//-------------------
// Turn off libraries
//-------------------
//
ElementRenderer::TerminateClasses();
MidLevelRenderer::TerminateClasses();
Stuff::TerminateClasses();
}
void
DumpScene(const char* name)
{}
//
// Setup the GameOS structure
//
void __stdcall GetGameOSEnvironment( char* CommandLine )
{
CommandLine=CommandLine;
Environment.applicationName = "TCT";
Environment.screenWidth = 640;
Environment.screenHeight = 480;
Environment.fullScreen = FALSE;
Environment.bitDepth = 16;
Environment.debugLog = ""; //"DebugLog.txt";
Environment.spew = ""; //"GameOS*";
Environment.UpdateRenderers = UpdateDisplay;
Environment.DoGameLogic = DoGameLogic;
Environment.InitializeGameEngine = InitializeGameEngine;
Environment.TerminateGameEngine = TerminateGameEngine;
Environment.SceneDump = DumpScene;
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
main()
{
InitGameOS(NULL, NULL, '\0');
InitializeGameEngine();
FileStream *temp_output = Stuff::FileStream::MakeFileStream();
Register_Object(temp_output);
temp_output->Open("TCTc.ini", FileStream::ReadOnly);
NotationFile *config_file = new NotationFile(temp_output);
Register_Object(config_file);
Check_Object(config_file);
const char *texPath;
if(!config_file->GetEntry("Miscellaneous", "Texturepath", &texPath))
{
return -1;
}
strncpy(texturePath, texPath, 1024);
fprintf(stdout, "Texturepath: %s\n", texturePath);
const char *default_path = "\\";
const char *output_path;
if(!config_file->GetEntry("Miscellaneous", "OutputPath", &output_path))
{
output_path = default_path;
}
strncpy(outputPath, output_path, 1024);
fprintf(stdout, "Outputpath: %s\n", outputPath);
MidLevelRenderer::TGAFilePool *pool = new MidLevelRenderer::TGAFilePool(texturePath);
Register_Object(pool);
MidLevelRenderer::MLRTexturePool::Instance =
new MidLevelRenderer::MLRTexturePool(pool);
Register_Object(MidLevelRenderer::MLRTexturePool::Instance);
if(!config_file->GetEntry("Miscellaneous", "OutputName", &texPath))
{
return -1;
}
strncpy(theName, texPath, 1024);
fprintf(stdout, "Output: %s\n", theName);
float dX, dY, dZ;
if(!config_file->GetEntry("HeightField", "DeltaX", &dX))
{
dX = 5.0f;
}
if(!config_file->GetEntry("HeightField", "DeltaY", &dY))
{
dY = 5.0f;
}
if(!config_file->GetEntry("HeightField", "DeltaZ", &dZ))
{
dZ = 5.0f;
}
fprintf(stdout, "Heighfield size: %f %f %f\n", dX, dY, dZ);
theTerrain = new HFSlim;
Register_Object(theTerrain);
theTerrain->SetScale(dX, dY, dZ);
theTerrain->SetOffset(0.0f, 0.0f);
fprintf(stdout, "Start importing the mega texture.\n");
ImportMegabasetexture(config_file);
Unregister_Object(config_file);
delete config_file;
temp_output->Close();
Unregister_Object(temp_output);
delete temp_output;
Unregister_Object(theTerrain);
delete theTerrain;
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);
}
theTerrain->FillFromImage(timg, smooth);
fprintf(stdout, "Heightfield image loaded.\n");
Verify((optPolys > 0) && (bucketSize > 0));
theTerrain->OptimizeHField(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(NotationFile *mega_file)
{
char buf[MAX_PATH];
GetCurrentDirectory(MAX_PATH, buf);
Check_Object(mega_file);
const char *hf_name;
if(!mega_file->GetEntry("HeightField", "HeightField", &hf_name))
{
SetCurrentDirectory(buf);
return;
}
int polyCount;
if(!mega_file->GetEntry("HeightField", "PolyCount", &polyCount))
{
polyCount = 0;
}
int bucketSize;
if(!mega_file->GetEntry("HeightField", "BucketSize", &bucketSize))
{
polyCount = 0;
}
int smoothPass;
if(!mega_file->GetEntry("HeightField", "SmoothingPasses", &smoothPass))
{
polyCount = 0;
}
if(false==ImportBitmap(hf_name, 4, polyCount, bucketSize, smoothPass))
{
return;
}
int borderPix;
if(!mega_file->GetEntry("BaseTexture", "BorderPixels", &borderPix))
{
borderPix = 0;
}
int nrOfLevels;
if(!mega_file->GetEntry("BaseTexture", "NumberOfLevels", &nrOfLevels))
{
nrOfLevels = 1;
}
fprintf(stdout, "HF: %s pc: %d bs: %d l: %d\n", hf_name, polyCount, bucketSize, nrOfLevels);
theTerrain->SetAllDepth(nrOfLevels);
const char *mega_base_name;
if(!mega_file->GetEntry("BaseTexture", "BaseName", &mega_base_name))
{
SetCurrentDirectory(buf);
return;
}
const char *detailLevelFileName;
if(mega_file->GetEntry("BaseTexture", "LevelInfo", &detailLevelFileName))
{
char name[1024];
strcpy(name, texturePath);
strcat(name, detailLevelFileName);
FILE *hd;
hd = fopen(name, "rb");
fread(&detailLevelInfo.width, sizeof(unsigned short), 1, hd);
fread(&detailLevelInfo.height, sizeof(unsigned short), 1, hd);
detailLevelInfo.array = new unsigned char [detailLevelInfo.width*detailLevelInfo.height];
size_t how_many = fread(detailLevelInfo.array, 1, detailLevelInfo.width*detailLevelInfo.height, hd);
if(how_many==detailLevelInfo.width*detailLevelInfo.height)
{
for(int i=0;i<detailLevelInfo.width*detailLevelInfo.height;i++)
{
if(detailLevelInfo.array[i] < 256/3)
{
detailLevelInfo.array[i] = 0;
}
else if(detailLevelInfo.array[i] < 512/3)
{
detailLevelInfo.array[i] = 1;
}
else
{
detailLevelInfo.array[i] = 2;
}
}
}
else
{
delete [] detailLevelInfo.array;
detailLevelInfo.width = 0;
detailLevelInfo.height = 0;
}
fclose(hd);
}
else
{
detailLevelInfo.width = 0;
detailLevelInfo.height = 0;
}
const char *mega_detail_name;
if(!mega_file->GetEntry("DetailTexture", "DetailTexture", &mega_detail_name))
{
SetCurrentDirectory(buf);
return;
}
Scalar ratio;
if(!mega_file->GetEntry("DetailTexture", "DetailRatio", &ratio))
{
ratio = 16.0f;
}
Scalar dStart;
if(!mega_file->GetEntry("DetailTexture", "DetailFadeBegin", &dStart))
{
dStart = 32.0f;
}
Scalar dEnd;
if(!mega_file->GetEntry("DetailTexture", "DetailFadeEnd", &dEnd))
{
dEnd = 64.0f;
}
const char *mega_alpha_name;
MLRState::AlphaMode alpha;
if(mega_file->GetEntry("DetailTexture", "DetailAlphaMode", &mega_alpha_name))
{
if(!strncmp(mega_alpha_name, "OneOne", sizeof("OneOne")))
{
alpha = MLRState::OneOneMode;
} else
if(!strncmp(mega_alpha_name, "AlphaOne", sizeof("AlphaOne")))
{
alpha = MLRState::AlphaOneMode;
} else
if(!strncmp(mega_alpha_name, "OneAlpha", sizeof("OneAlpha")))
{
alpha = MLRState::OneAlphaMode;
} 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;
}
fprintf(stdout, "BaseTexture: %s (with %d border pixels, Detail: %s\n",
mega_base_name,
borderPix,
mega_detail_name
);
theTerrain->SetDetailTextureInfo(
mega_detail_name,
0.0f,
0.0f,
ratio,
ratio,
dStart,
dEnd,
alpha
);
theTerrain->SetBorderPixels(borderPix);
char lowestLevelTextureName[1024];
sprintf(lowestLevelTextureName, "%s_0_0000", mega_base_name);
MidLevelRenderer::MLRTexturePool::Instance->Add(lowestLevelTextureName);
if(true == theTerrain->SetMegaTexture(nrOfLevels, bucketSize, mega_base_name, &detailLevelInfo))
{
FileExport(outputPath);
}
SetCurrentDirectory(buf);
}
void
FileExport(const char *output_path)
{
Check_Object(theTerrain->GetGroup());
//
//---------------------------------------------------
// Analyze the set file and extract the useful pieces
//---------------------------------------------------
//
Stuff::MString erf_name(theName);
Stuff::MString path(output_path);
erf_name += "_jm.erf";
ElementRenderer::Element *terrain;
bool terrainVisible;
terrain = theTerrain->GetOptTerrain();
terrainVisible = theTerrain->IsOptDisplayed();
theTerrain->DisplayOpt(false);
unsigned cullMode = terrain->GetCullMode();
terrain->SetRootMode();
Stuff::FileStream *element_stream =
Stuff::FileStream::MakeFileStream();
Register_Object(element_stream);
Stuff::MString contents_name = path;
contents_name += erf_name;
element_stream->Open(contents_name, Stuff::FileStream::WriteOnly);
ElementRenderer::WriteERFVersion(element_stream);
terrain->Save(element_stream);
Unregister_Object(element_stream);
delete element_stream;
switch(cullMode)
{
case ElementRenderer::Element::RootMode:
terrain->SetRootMode();
break;
case ElementRenderer::Element::VolumeCullMode:
terrain->SetVolumeCullMode();
break;
case ElementRenderer::Element::NeverCullMode:
terrain->SetNeverCullMode();
break;
case ElementRenderer::Element::AlwaysCullMode:
terrain->SetAlwaysCullMode();
break;
}
} // end of export