222 lines
6.0 KiB
C++
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);
|
|
}
|