// TCTc.cpp : Defines the class behaviors for the application. // #include #include #include #include #include #include #include #include #include #include #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;iGetEntry("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