SBSPSS/Utils/MkLevel/Layers/MkLevelLayerTile.cpp
2001-06-27 16:45:56 +00:00

222 lines
6.0 KiB
C++

/******************/
/*** Layer Tile ***/
/******************/
#include <DaveLib.h>
#include <List2d.h>
#include "MkLevelLayer.h"
#include "MkLevelLayerTile.h"
#include "pak.h"
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
CMkLevelLayerTile::CMkLevelLayerTile(sExpLayerHdr *LayerHdr)
{
Type=LayerHdr->Type;
SubType=LayerHdr->SubType;
Width=LayerHdr->Width;
Height=LayerHdr->Height;
sExpLayerTile *MapPtr=(sExpLayerTile *)((int)LayerHdr+sizeof(sExpLayerHdr));
InMap.SetSize(Width,Height);
for (int Y=0; Y<Height; Y++)
{
for (int X=0; X<Width; X++)
{
sExpLayerTile ThisTile;
ThisTile.Tile=MapPtr->Tile;
ThisTile.Flags=MapPtr->Flags;
InMap.Set(X,Y,ThisTile);
MapPtr++;
}
}
}
/*****************************************************************************/
/*****************************************************************************/
/*** Pre-Process *************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CMkLevelLayerTile::PreProcess(CMkLevel *Core)
{
int Width=InMap.GetWidth();
int Height=InMap.GetHeight();
OutMap.SetSize(Width,Height);
for (int Y=0; Y<Height; Y++)
{
for (int X=0; X<Width; X++)
{
sExpLayerTile &InElem=InMap.Get(X,Y);
sMkLevelElem &OutElem=OutMap.Get(X,Y);
OutElem.Elem=0;
if (InElem.Tile)
{ // Dont process blanks
OutElem.Elem=Core->AddTile2d(InElem);
}
}
}
}
/*****************************************************************************/
/*****************************************************************************/
/*** Process *****************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CMkLevelLayerTile::Process(CMkLevel *Core)
{
}
/*****************************************************************************/
/*****************************************************************************/
/** Write ********************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int CMkLevelLayerTile::Write(CMkLevel *Core,FILE *File,const char *LayerName)
{
int HdrPos=ftell(File);
int Width=OutMap.GetWidth();
int Height=OutMap.GetHeight();
Hdr.Type=Type;
Hdr.SubType=SubType;
Hdr.Width=Width;
Hdr.Height=Height;
fwrite(&Hdr,sizeof(sLayerHdr),1,File);
// printf("%s (%i,%i)= %i\n",LayerName,Width,Height,Width*Height*sizeof(sTileMapElem));
Core->GetPakWH(PakW,PakH);
if (PakW && PakH)
{
int OrigSize=Width*Height*sizeof(sTileMapElem);
printf("- PAKing Layer %s (%i,%i).. ",LayerName,Width,Height);
int LvlSize=WritePak(Core,File);
printf("%i bytes - Saved %i Bytes\n",LvlSize,OrigSize-LvlSize);
}
else
{
// printf("- Writing Layer %s (%i,%i).. ",LayerName,Width,Height);
int LvlSize=WriteNormal(Core,File);
// printf("%i bytes\n",LvlSize);
}
PadFile(File);
// ReWrite Hdr
int RetPos=ftell(File);
fseek(File,HdrPos,SEEK_SET);
fwrite(&Hdr,sizeof(sLayerHdr),1,File);
fseek(File,RetPos,SEEK_SET);
Size=ftell(File)-HdrPos;
return(HdrPos);
}
/*****************************************************************************/
void CMkLevelLayerTile::BuildOutElem(int X,int Y,sTileMapElem *Out)
{
sMkLevelElem &In=OutMap.Get(X,Y);
Out->Tile=In.Elem;
}
/*****************************************************************************/
int CMkLevelLayerTile::WriteNormal(CMkLevel *Core,FILE *File)
{
int Width=OutMap.GetWidth();
int Height=OutMap.GetHeight();
sTileMapElem OutElem;
for (int Y=0; Y<Height; Y++)
{
for (int X=0; X<Width; X++)
{
BuildOutElem(X,Y,&OutElem);
fwrite(&OutElem,sizeof(sTileMapElem),1,File);
}
}
return(Width*Height*sizeof(sTileMapElem));
}
/*****************************************************************************/
int CMkLevelLayerTile::WritePak(CMkLevel *Core,FILE *File)
{
int MapW=OutMap.GetWidth();
int MapH=OutMap.GetHeight();
int ChunkW=(MapW/PakW)+1;
int ChunkH=(MapH/PakH)+1;
int BufferSize=PakW*PakH*sizeof(sTileMapElem);
int TotalPak=0;
ChunkBuffer=(sTileMapElem*)malloc(BufferSize);
PakBuffer=(u8*)malloc(BufferSize*8); // Allow for bad pak
for (int ChunkY=0; ChunkY<ChunkH; ChunkY++)
{
for (int ChunkX=0; ChunkX<ChunkW; ChunkX++)
{
// Create Chunk
int ThisChunkW,ThisChunkH,ThisChunkSize;
int PakSize;
ThisChunkSize=BuildPakChunk(ChunkX,ChunkY,ThisChunkW,ThisChunkH);
PakSize=PakChunk(ThisChunkSize);
// if (PakSize>=PakW*PakH*sizeof(sTileMapElem)) GObject::Error(ERR_WARNING,"BAD PAK: %i>%i\n",PakSize,BufferSize);
TotalPak+=PakSize;
fwrite(&PakBuffer,PakSize,1,File);
}
}
free(ChunkBuffer);
free(PakBuffer);
return(TotalPak);
}
/*****************************************************************************/
int CMkLevelLayerTile::BuildPakChunk(int X,int Y,int &ChunkW,int &ChunkH)
{
int MapW=OutMap.GetWidth();
int MapH=OutMap.GetHeight();
// Calc Chunk Pos & size
X=X*PakW;
MapW-=X;
ChunkW=__min(MapW,PakW);
Y=Y*PakH;
MapH-=Y;
ChunkH=__min(MapH,PakH);
// Build Chunk
sTileMapElem *OutPtr=ChunkBuffer;
for (int MY=0; MY<ChunkH; MY++)
{
for (int MX=0; MX<ChunkW; MX++)
{
BuildOutElem(X+MX,Y+MY,OutPtr++);
}
}
return(ChunkW*ChunkH*sizeof(sTileMapElem));
}
/*****************************************************************************/
int CMkLevelLayerTile::PakChunk(int ChunkSize)
{
int PakSize=PAK_doPak(PakBuffer,(u8*)ChunkBuffer,ChunkSize);
return(PakSize);
}