// TCTd.cpp : super multizone tool ! // #include #include #include #include #include #include #include #include #include #include #include "ImageLib\image.h" #include "HFslimMZ.hpp" HFSlimMZ *theTerrain; void MakeBSP( Stuff::DynamicArrayOf *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, const char *fname); void ImportMegabasetexture(Page *page); FILE *analyzeFile; void __stdcall InitializeGameEngine() { // //--------------------- // Initialize libraries //--------------------- // Stuff::InitializeClasses(); MidLevelRenderer::InitializeClasses(32768*16); gosFX::InitializeClasses(); ElementRenderer::InitializeClasses(); 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(); for(int i=1;iReadAndNext()) != 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"); 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); } } 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); char underWaterDetailName[1024]; char waterTextureName[1024]; char waterDetailName[1024]; const char *under_water_detail_name; const char *water_texture_name; const char *water_detail_texture_name; Scalar waterTextureRatio = 4.0f; Scalar waterDetailTextureRatio = 4.0f; if(doWater==true) { if(map_to_convert->GetEntry("UnderwaterdetailTexture", &under_water_detail_name)) { sprintf(underWaterDetailName, "Maps\\%s\\%s", theName, under_water_detail_name); 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); water_texture_name = waterTextureName; } else { water_texture_name = NULL; } if(map_to_convert->GetEntry("WaterDetailTexture", &water_detail_texture_name)) { sprintf(waterDetailName, "Maps\\%s\\%s", theName, water_detail_texture_name); water_detail_texture_name = waterDetailName; } else { water_detail_texture_name = NULL; } map_to_convert->GetEntry("WaterTextureRatio", &waterTextureRatio); map_to_convert->GetEntry("WaterDetailRatio", &waterDetailTextureRatio); theTerrain->SetWaterInfo(water_texture_name, waterTextureRatio); } 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, under_water_detail_name, 0.0f, 0.0f, waterDetailTextureRatio, waterDetailTextureRatio, dStart, dEnd, alpha ); theTerrain->SetBorderPixels(borderPix); theTerrain->SetWaterDetailTextureInfo( water_detail_texture_name, 0.0f, 0.0f, ratio, ratio, dStart, dEnd, alpha ); if(true == theTerrain->SetMegaTexture( nrOfLevels, bucketSize, theName, outputPath) ) { FileExport(theTerrain, outputPath); } sprintf(outputPath, "%sMaps\\%s\\%s.erf", contentPath, theName, theName); 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 tile_streams(64); int triangle_count = terrain->CountTriangles(); Verify(triangle_count < 32768); DynamicArrayOf 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 *waterArray; waterArray = tT->GetWaterArray(); Stuff::DynamicArrayOf *terrainArray; terrainArray = tT->GetTerrainArray(); ElementRenderer::GridElement *terrain; for(j=0;jGetIndexedElement(row, col) ); Stuff::ChainIteratorOf* 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); Check_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