/*********************/ /*** MkLevel Class ***/ /*********************/ #include "stdio.h" #include #include #include #include #include #include #include "MkLevel.h" #include "Layers\MkLevelLayer.h" #include "Layers\MkLevelLayerTile.h" #include "Layers\MkLevelLayer3d.h" #include "Layers\MkLevelLayerShade.h" #include "Layers\MkLevelLayerCollision.h" #include "Layers\MkLevelLayerActor.h" #include "Layers\MkLevelLayerItem.h" #include "Layers\MkLevelLayerPlatform.h" #include "Layers\MkLevelLayerFX.h" #include "Layers\MkLevelLayerTrigger.h" //*************************************************************************** GString ConfigFilename="MkLevel"; sExpLayerTile BlankTile={-1,-1}; //*************************************************************************** CMkLevel::CMkLevel() { memset(&LvlHdr,0,sizeof(sLvlHdr)); Tile2dList.Add(BlankTile); } //*************************************************************************** CMkLevel::~CMkLevel() { } //*************************************************************************** void CMkLevel::Init(const char *Filename,const char *OutDir,int TPBase,int TPW,int TPH) { // Setup filenames and paths GFName Path=Filename; InFilename=Filename; LevelName=Path.File(); Path.File(""); Path.Ext(""); InPath=Path.FullName(); OutPath=OutDir; OutPath.Append('\\'); OutName=OutPath+LevelName; // Load ini file #ifdef _DEBUG ConfigFilename="\\spongebob\\tools\\data\\bin\\mklevel.ini"; #endif Config.LoadAndImport(ConfigFilename); // Setup Texgrab if (TPBase==-1 || TPW==-1 || TPH==-1) GObject::Error(ERR_FATAL,"TPage not set\n"); TexGrab.SetTPage(TPBase,TPW,TPH); TexGrab.SetOutFile(GString(OutName+".Tex")); TexGrab.SetDebug(DebugOn); TexGrab.SetDebugOut(GString(OutName+".Lbm")); TexGrab.NoSort(); TexGrab.AnimatedHeadersOnly(true); TexGrab.DontOutputBoxes(true); //!!! TexGrab.AllowRotate(true); TexGrab.AllowRotate(false); //!!! TexGrab.ShrinkToFit(true); TexGrab.ShrinkToFit(false); // Setup TriList OutTriList.SetTexGrab(TexGrab); // Set up other stuph FlatFace[0].vtx[0].x=+0.5f; FlatFace[0].vtx[0].y=+1.0f; FlatFace[0].vtx[0].z=-4.0f; FlatFace[0].vtx[1].x=-0.5f; FlatFace[0].vtx[1].y= 0.0f; FlatFace[0].vtx[1].z=-4.0f; FlatFace[0].vtx[2].x=+0.5f; FlatFace[0].vtx[2].y= 0.0f; FlatFace[0].vtx[2].z=-4.0f; FlatFace[0].uvs[0].u=1; FlatFace[0].uvs[0].v=1; FlatFace[0].uvs[1].u=0; FlatFace[0].uvs[1].v=0; FlatFace[0].uvs[2].u=1; FlatFace[0].uvs[2].v=0; FlatFace[1].vtx[0].x=-0.5f; FlatFace[1].vtx[0].y= 0.0f; FlatFace[1].vtx[0].z=-4.0f; FlatFace[1].vtx[1].x=+0.5f; FlatFace[1].vtx[1].y=+1.0f; FlatFace[1].vtx[1].z=-4.0f; FlatFace[1].vtx[2].x=-0.5f; FlatFace[1].vtx[2].y=+1.0f; FlatFace[1].vtx[2].z=-4.0f; FlatFace[1].uvs[0].u=0; FlatFace[1].uvs[0].v=0; FlatFace[1].uvs[1].u=1; FlatFace[1].uvs[1].v=1; FlatFace[1].uvs[2].u=0; FlatFace[1].uvs[2].v=1; } //*************************************************************************** //*** Load ****************************************************************** //*************************************************************************** void CMkLevel::Load() { FILE *File; sExpFileHdr *FileHdr; int Size; printf("Load %s\n",LevelName); File=fopen(InFilename,"rb"); if (!File) GObject::Error(ERR_FATAL,"%s Not found\n",InFilename); // Calc File Size fseek(File,0,SEEK_END); Size=ftell(File); fseek(File,0,SEEK_SET); FileHdr=(sExpFileHdr*)malloc(Size); // Load It fread(FileHdr,Size,1,File); fclose(File); LoadTiles(FileHdr); LoadLayers(FileHdr); free(FileHdr); } //*************************************************************************** void CMkLevel::LoadStrList(CList &List,char *TexPtr,int Count) { char FullName[256]; GString FilePath; for (int i=0; iTileW; TileH=FileHdr->TileH; RGBSize=TileW*TileH*3; // Load SetNames LoadStrList(InSetNameList,(char*) &ByteHdr[FileHdr->SetNameOfs],FileHdr->SetNameCount); // Load TexNames LoadStrList(InTexNameList,(char*) &ByteHdr[FileHdr->TexNameOfs],FileHdr->TexNameCount); // Load Tiles u8 *TilePtr=(u8*) &ByteHdr[FileHdr->TileOfs]; InTileList.resize(FileHdr->TileCount); for (i=0; iTileCount; i++) { sExpTile *ThisTilePtr=(sExpTile*)TilePtr; sExpTile &InTile=InTileList[i]; InTile=*ThisTilePtr; InTile.RGB=(u8*)malloc(RGBSize); memcpy(InTile.RGB,TilePtr+sizeof(sExpTile),RGBSize); TilePtr+=RGBSize+sizeof(sExpTile); } // Load Tris sExpTri *TriPtr=(sExpTri*) &ByteHdr[FileHdr->TriOfs]; InTriList.resize(FileHdr->TriCount); for (i=0; iTriCount; i++) { InTriList[i]=TriPtr[i]; } // Load 2d bitmaps ListSize=InSetNameList.size(); BmpList.resize(ListSize); for (i=0; iLayerCount; i++) { sExpLayerHdr *LayerHdr=(sExpLayerHdr *)&ByteHdr[FileHdr->LayerOfs[i]]; switch(LayerHdr->Type) { case LAYER_TYPE_TILE: switch (LayerHdr->SubType) { case LAYER_SUBTYPE_ACTION: LayerList.push_back(new CMkLevelLayer3d(LayerHdr)); break; case LAYER_SUBTYPE_MID: LayerList.push_back(new CMkLevelLayerTile(LayerHdr)); break; case LAYER_SUBTYPE_BACK: default: break; } break; case LAYER_TYPE_COLLISION: LayerList.push_back(new CMkLevelLayerCollision(LayerHdr)); break; case LAYER_TYPE_SHADE: LayerList.push_back(new CMkLevelLayerShade(LayerHdr)); break; case LAYER_TYPE_ACTOR: LayerList.push_back(new CMkLevelLayerActor(LayerHdr)); break; case LAYER_TYPE_ITEM: LayerList.push_back(new CMkLevelLayerItem(LayerHdr)); break; case LAYER_TYPE_PLATFORM: LayerList.push_back(new CMkLevelLayerPlatform(LayerHdr)); break; case LAYER_TYPE_TRIGGER: LayerList.push_back(new CMkLevelLayerTrigger(LayerHdr)); break; case LAYER_TYPE_FX: LayerList.push_back(new CMkLevelLayerFX(LayerHdr)); break; default: GObject::Error(ERR_FATAL,"Unknown Layer Type\n"); } } } //*************************************************************************** //*** Process *************************************************************** //*************************************************************************** void CMkLevel::Process() { printf("PreProcess Layers\n"); PreProcessLayers(); printf("Process Tilebank\n"); ProcessTileBanks(); printf("Process Layers\n"); ProcessLayers(); OutTriList.Process(); } //*************************************************************************** void CMkLevel::PreProcessLayers() { int LayerCount=LayerList.size(); for (int i=0; iPreProcess(this); } } //*************************************************************************** void CMkLevel::ProcessLayers() { int LayerCount=LayerList.size(); for (int i=0; iProcess(this); } } //*************************************************************************** void CMkLevel::ProcessTileBanks() { PreProcessTileBank2d(); PreProcessTileBank3d(); TexGrab.Process(); ProcessTileBank2d(); ProcessTileBank3d(); } //*************************************************************************** void CMkLevel::PreProcessTileBank2d() { int i,ListSize=Tile2dList.size(); Tile2dList[0].Tile=-1; // Extract Tex data from list for (i=1; i &TexInfo=TexGrab.GetTexInfo(); OutTile2dList.resize(ListSize); for (i=1; iIsType(Type,SubType)) return(LayerList[i]); } return(0); } //*************************************************************************** int CMkLevel::Create3dTile(sExpLayerTile &InTile) { sExpTile &SrcTile=InTileList[InTile.Tile]; CFace F; int i,ListSize; CList SortList; CList ZPosList; if (SrcTile.TriCount) { for (i=0; iThisTri.vtx[1].z) ThisZPos=ThisTri.vtx[1].z; if (ThisZPos>ThisTri.vtx[2].z) ThisZPos=ThisTri.vtx[2].z; ListSize=SortList.size(); for (ListPos=0; ListPos=0 && InTex.SetBmpW) { printf("AARGH!!! %s(%i) wants X=%i,tile is only %i Wide\n",Name,InTex.Set,InTex.XOfs*16,BmpW); InTex.XOfs=0; } if (InTex.YOfs*16>BmpH) { printf("AARGH!!! %s(%i) wants Y=%i,tile is only %i High\n",Name,InTex.Set,InTex.YOfs*16,BmpH); InTex.YOfs=0; } MakeTexName(InTex,TexName); ThisRect.X=InTex.XOfs*16; ThisRect.Y=InTex.YOfs*16; ThisRect.W=16; ThisRect.H=16; ThisFrame.Grab(InFrame,ThisRect); if (InTex.Flags& PC_TILE_FLAG_MIRROR_X) ThisFrame.FlipX(); if (InTex.Flags & PC_TILE_FLAG_MIRROR_Y) ThisFrame.FlipY(); InTex.TexID=TexGrab.AddMemFrame(TexName,ThisFrame); #ifdef _DEBUG if (0) { if (!ThisFrame.IsBlank()) { char DbgName[256]; sprintf(DbgName,"/x/%s.lbm",TexName); ThisFrame.SaveLbm(DbgName); } } #endif return(InTex.TexID); } //*************************************************************************** void CMkLevel::MakeTexName(sMkLevelTex &InTex,GString &OutStr) { char NewName[256]; GString Name=GFName(InSetNameList[InTex.Set]).File(); sprintf(NewName,"%s_%02d_%02d_%01d_",Name,InTex.XOfs,InTex.YOfs,InTex.Flags&PC_TILE_FLAG_MIRROR_XY); OutStr=NewName; } //*************************************************************************** int CMkLevel::FindRGBMatch(sMkLevelTex &ThisTex) { int i,ListSize=Tex2dList.size(); int Size=TileW*TileH; u8 *RGBPtr=ThisTex.RGB; // Create Checksum for this tile ThisTex.RChk=0; ThisTex.GChk=0; ThisTex.BChk=0; for (i=0; i &TriList=OutTriList.GetOutTriList(); vector const &VtxList=OutTriList.GetVtxList(); int ThisPos=ftell(File); int i,ListSize=TriList.size(); int MaxOT=0; for (i=0;i63) OtOfs=63; // Write It fwrite(&T,1,sizeof(sTri),File); } printf("MAXOT = %i\n",MaxOT); return(ThisPos); } //*************************************************************************** //*** Write ***************************************************************** //*************************************************************************** void CMkLevel::WriteLevel() { GString OutFilename=OutName+".Lvl"; File=fopen(OutFilename,"wb"); fwrite(&LvlHdr,1,sizeof(sLvlHdr),File); WriteLayers(); // rewrite header fseek(File,0,SEEK_SET); fwrite(&LvlHdr,1,sizeof(sLvlHdr),File); fclose(File); } //*************************************************************************** void CMkLevel::WriteLayers() { // Back (Shade) LvlHdr.BackLayer=WriteLayer(LAYER_TYPE_SHADE,LAYER_SUBTYPE_BACK,0);//"Shade"); // Mid LvlHdr.MidLayer=WriteLayer(LAYER_TYPE_TILE,LAYER_SUBTYPE_MID,"Mid"); // Action LvlHdr.ActionLayer=WriteLayer(LAYER_TYPE_TILE,LAYER_SUBTYPE_ACTION,"Action"); // Fore // LvlHdr.ForeLayer=WriteLayer(LAYER_TYPE_TILE,LAYER_SUBTYPE_FORE,"Fore"); // Collision LvlHdr.CollisionLayer=WriteLayer(LAYER_TYPE_COLLISION,LAYER_SUBTYPE_NONE,"Collision"); // Things LvlHdr.ActorList=WriteThings(LAYER_TYPE_ACTOR,"Actor List"); LvlHdr.ItemList=WriteThings(LAYER_TYPE_ITEM,"Item List"); LvlHdr.PlatformList=WriteThings(LAYER_TYPE_PLATFORM,"Platform List"); LvlHdr.TriggerList=WriteThings(LAYER_TYPE_TRIGGER,"FX List"); LvlHdr.FXList=WriteThings(LAYER_TYPE_FX,"FX List"); } //*************************************************************************** int CMkLevel::WriteLayer(int Type,int SubType,const char *LayerName) { CMkLevelLayer *ThisLayer=FindLayer(Type,SubType); int Ofs; if (!ThisLayer) { if (LayerName) GObject::Error(ERR_WARNING,"No %s Layer Found in %s!!\n",LayerName,LevelName); return(0); } Ofs=ThisLayer->Write(File,LayerName,LevelName); PadFile(File); return(Ofs); } //*************************************************************************** int CMkLevel::WriteThings(int Type,const char *LayerName) { CMkLevelLayer *ThisLayer=FindLayer(Type,LAYER_SUBTYPE_NONE); int Ofs; if (!ThisLayer) { GFName Name=InFilename; if (LayerName) GObject::Error(ERR_WARNING,"No %s Layer Found in %s!!\n",LayerName,Name.File()); return(0); } Ofs=ThisLayer->Write(File,LayerName,LevelName); PadFile(File); return(Ofs); }