This commit is contained in:
parent
7551b4f12e
commit
8788076d39
37 changed files with 11186 additions and 0 deletions
533
Utils/Libs/GinLib/mapread.cpp
Normal file
533
Utils/Libs/GinLib/mapread.cpp
Normal file
|
@ -0,0 +1,533 @@
|
|||
/*=========================================================================
|
||||
|
||||
EXPORT.CPP
|
||||
|
||||
Author:
|
||||
Created:
|
||||
Project:
|
||||
Purpose:
|
||||
|
||||
Copyright (c) 1998 Climax Development Ltd
|
||||
|
||||
===========================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Includes
|
||||
-------- */
|
||||
|
||||
/* Std Lib
|
||||
------- */
|
||||
|
||||
#include "mapread.h"
|
||||
|
||||
|
||||
/* Glib
|
||||
---- */
|
||||
#include <tquant.h>
|
||||
|
||||
/* Local
|
||||
----- */
|
||||
|
||||
/* Graphics
|
||||
-------- */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Tyepdefs && Defines
|
||||
------------------- */
|
||||
|
||||
#define TILE_SHIFT 8
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Structure defintions
|
||||
-------------------- */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Positional Vars
|
||||
--------------- */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Function Prototypes
|
||||
------------------- */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Vars
|
||||
---- */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Data
|
||||
---- */
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Function:
|
||||
Purpose:
|
||||
Params:
|
||||
Returns:
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
int CMapFile::GetVersion( char * version )
|
||||
{
|
||||
int ret = 0;
|
||||
int len;
|
||||
char whole[8];
|
||||
char frac[8];
|
||||
|
||||
len = strlen(version);
|
||||
if (len)
|
||||
{
|
||||
int pos = 0;
|
||||
int opos = 0;
|
||||
|
||||
while (version[pos] != '.')
|
||||
{
|
||||
whole[pos] = version[pos];
|
||||
pos++;
|
||||
if (pos > len)
|
||||
GObject::Error(ERR_FATAL,"Corrupt Version - %s\n", version);
|
||||
}
|
||||
|
||||
pos++;
|
||||
while (version[pos])
|
||||
{
|
||||
frac[opos] = version[pos];
|
||||
pos++;
|
||||
opos++;
|
||||
if (pos > len)
|
||||
GObject::Error(ERR_FATAL,"Corrupt Version - %s\n", version);
|
||||
}
|
||||
}
|
||||
|
||||
ret = atoi( whole );
|
||||
ret *= 100;
|
||||
ret += atoi( frac );
|
||||
|
||||
GObject::Error(ERR_WARNING, "Map Version %d\n", ret );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Function:
|
||||
Purpose:
|
||||
Params:
|
||||
Returns:
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
int CMapFile::FindFrame( const char * frame )
|
||||
{
|
||||
char InFile[_MAX_FNAME];
|
||||
char CompFile[_MAX_FNAME];
|
||||
|
||||
_splitpath( frame, NULL, NULL, InFile, NULL );
|
||||
|
||||
for (int f=0;f<RepItems.size();f++)
|
||||
{
|
||||
_splitpath( RepItems[f].m_texName, NULL, NULL, CompFile, NULL );
|
||||
if (!strcmp( InFile, CompFile )) return f;
|
||||
}
|
||||
|
||||
if (m_errorOnMissingFile)
|
||||
GObject::Error(ERR_FATAL,"Missing bmp - %s\n", frame);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Function:
|
||||
Purpose:
|
||||
Params:
|
||||
Returns:
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
void CMapFile::Parse()
|
||||
{
|
||||
int i;
|
||||
int version;
|
||||
int x, y;
|
||||
float lowestY;
|
||||
TILE_PACKET * t;
|
||||
|
||||
|
||||
MapFile.Seek( 0 );
|
||||
MapFile.Read( VersionText, 4 );
|
||||
|
||||
version = GetVersion( (char *)VersionText );
|
||||
|
||||
|
||||
// READ GLOBAL TILE NAMES
|
||||
|
||||
MapFile.Read( &nbTiles );
|
||||
TileNames = (CFileName *)malloc( nbTiles * sizeof(CFileName) );
|
||||
|
||||
for (i=0;i<nbTiles;i++)
|
||||
{
|
||||
MapFile.Read( &TileNames[i], sizeof(CFileName) );
|
||||
}
|
||||
|
||||
|
||||
// READ GLOBAL OBJECT INFO
|
||||
|
||||
MapFile.Read( &nbObjects );
|
||||
Objects = (CObject *)malloc( nbObjects * sizeof(CObject) );
|
||||
for (i=0;i<nbObjects;i++)
|
||||
{
|
||||
MapFile.Read( &Objects[i].Name, sizeof(CFileName) );
|
||||
|
||||
if (version < 104)
|
||||
{
|
||||
MapFile.Read( &Objects[i].Width );
|
||||
MapFile.Read( &Objects[i].Height );
|
||||
MapFile.Read( &Objects[i].Depth );
|
||||
MapFile.Read( &Objects[i].Mask, (sizeof(bool) * MAX_MASKX * MAX_MASKY) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// READ TILE MAP
|
||||
|
||||
MapFile.Read( &MapWidth );
|
||||
MapFile.Read( &MapHeight );
|
||||
MapFile.Read( &TileSize );
|
||||
if (TileSize > sizeof(MapCTile)) GObject::Error(ERR_FATAL, "MapCTile STRUCT MISMATCH" );
|
||||
Tiles = (TILE_PACKET *)malloc( (MapWidth * MapHeight * sizeof( TILE_PACKET )) );
|
||||
|
||||
if (!Tiles)
|
||||
GObject::Error(ERR_FATAL, "can't allocate tiles" );
|
||||
|
||||
|
||||
t = Tiles;
|
||||
nbSpawnPoints=0;
|
||||
lowestY = 65536;
|
||||
for (y=0;y<MapHeight;y++)
|
||||
{
|
||||
for (x=0;x<MapWidth;x++)
|
||||
{
|
||||
MapCTile tile;
|
||||
int frame = 0;
|
||||
int angle = 0;
|
||||
|
||||
MapFile.Read( &tile, TileSize );
|
||||
|
||||
strlwr( tile.FrameName );
|
||||
for (int l=0;l<strlen(tile.FrameName);l++)
|
||||
{
|
||||
if (tile.FrameName[l] == '\\') tile.FrameName[l] = '/';
|
||||
}
|
||||
if (tile.frame) frame = FindFrame( tile.FrameName );
|
||||
else frame = 0;
|
||||
|
||||
angle = (int)tile.angle;
|
||||
angle++;
|
||||
angle &= 0x3;
|
||||
if (angle == 2) angle = 0;
|
||||
else if (angle == 0) angle = 2;
|
||||
|
||||
t->frame = tile.frame;
|
||||
t->r = (u8)(tile.r * 255.f);
|
||||
t->g = (u8)(tile.g * 255.f);
|
||||
t->b = (u8)(tile.b * 255.f);
|
||||
t->pad = 0;
|
||||
|
||||
if (tile.flag&TF_SPAWN)
|
||||
{
|
||||
if (nbSpawnPoints>=MAX_SPAWNING_TILES)
|
||||
{
|
||||
GObject::Error(ERR_FATAL, "Max Spawning Positions exceeded for level" );
|
||||
}
|
||||
Spawn[nbSpawnPoints].x = x;
|
||||
Spawn[nbSpawnPoints].y = y;
|
||||
nbSpawnPoints++;
|
||||
|
||||
}
|
||||
|
||||
t->angle = angle;
|
||||
t->flags = (int)(tile.flag&(~TF_SPAWN));
|
||||
t->height = (int)tile.py;
|
||||
t->frame = frame;
|
||||
t->xflip = tile.xflip;
|
||||
t->yflip = tile.yflip;
|
||||
t->type = tile.type;
|
||||
|
||||
// if (t->flags & TF_NO_BUILD)
|
||||
// GObject::Error(ERR_WARNING, "No build flag found\n" );
|
||||
|
||||
if (frame < 0) t->flags |= TF_HIDDEN;
|
||||
|
||||
if (!(tile.flag & TF_HIDDEN) && (x < MapWidth-1) && (y < MapHeight-1))
|
||||
{
|
||||
if (lowestY > tile.py) lowestY = tile.py;
|
||||
}
|
||||
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
GObject::Error( ERR_WARNING, "Lowest land height = %f\n", lowestY );
|
||||
|
||||
t = Tiles;
|
||||
for (y=0;y<MapHeight;y++)
|
||||
{
|
||||
for (x=0;x<MapWidth;x++)
|
||||
{
|
||||
t->height -= (int)lowestY;
|
||||
if (t->height < 0) t->height = 0;
|
||||
|
||||
// if (t->height > sizeof(u16))
|
||||
// {
|
||||
// GObject::Error( ERR_FATAL, "Land height overflow - %d\n", t->height );
|
||||
// }
|
||||
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// READ OBJECT LIST
|
||||
|
||||
MapFile.Read( &nbModels );
|
||||
MapFile.Read( &ModelSize );
|
||||
if (ModelSize > sizeof(CModel)) GObject::Error(ERR_FATAL, "Struct mismatch in CModel" );
|
||||
|
||||
Models = (MODEL_PACKET *)malloc( nbModels * sizeof(MODEL_PACKET) );
|
||||
|
||||
if (!Models)
|
||||
GObject::Error(ERR_FATAL, "Can't allocate models\n" );
|
||||
|
||||
|
||||
MODEL_PACKET * m = Models;
|
||||
for (i=0;i<nbModels;i++)
|
||||
{
|
||||
u32 animflag;
|
||||
u16 angle;
|
||||
CModel model;
|
||||
char MyDir[_MAX_DIR];
|
||||
char MyFile[_MAX_FNAME];
|
||||
|
||||
|
||||
MapFile.Read( &model, ModelSize );
|
||||
|
||||
|
||||
_splitpath( model.MeshName, NULL, MyDir, MyFile, NULL );
|
||||
|
||||
angle = (u16)model.AngY;
|
||||
if (angle == 1) angle = 3;
|
||||
else if (angle == 3) angle = 1;
|
||||
|
||||
animflag = FindFileEquate( MyFile );
|
||||
animflag &= ~MODEL_FLAGS_MASK;
|
||||
if (model.m_Animates) animflag |= MODEL_ANIMATE_FLAG;
|
||||
if (model.m_Busstop) animflag |= MODEL_BUSSTOP_FLAG;
|
||||
if (model.m_Booth) animflag |= MODEL_BOOTH_FLAG;
|
||||
if (model.m_OtherAnim) animflag |= MODEL_OTHERANIM_FLAG;
|
||||
if (model.m_Entrance) animflag |= MODEL_ENTRANCE_FLAG;
|
||||
|
||||
|
||||
m->AnimAndFlags = animflag;
|
||||
m->xp = (u16)(model.PosX / (1 << TILE_SHIFT));
|
||||
m->yp = (u16)(model.PosY - lowestY);
|
||||
m->zp = (u16)(model.PosZ / (1 << TILE_SHIFT));
|
||||
m->ya = (u16)angle;
|
||||
|
||||
// if (m->yp > sizeof(u16))
|
||||
// {
|
||||
// GObject::Error( ERR_FATAL, "Object Y position overflow - %d\n", m->yp );
|
||||
// }
|
||||
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Function:
|
||||
Purpose:
|
||||
Params:
|
||||
Returns:
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
int CMapFile::FindFileEquate( char * name )
|
||||
{
|
||||
strupr( name );
|
||||
|
||||
for (int i=0;i<AnimItems.size();i++)
|
||||
{
|
||||
if (!strcmp( AnimItems[i].m_AnimName, name )) return( AnimItems[i].m_Frame );
|
||||
}
|
||||
|
||||
if (AnimHeaderFile)
|
||||
{
|
||||
GObject::Error( ERR_WARNING, "Could not find anim %s in anim header %s\n", name, AnimHeaderFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
GObject::Error( ERR_WARNING, "Could not find anim %s - anim header not loaded\n", name );
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Function:
|
||||
Purpose:
|
||||
Params:
|
||||
Returns:
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
void CMapFile::MakeMapPalette(void)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
vector<u8> SourcePal;
|
||||
vector<u8> DestPal;
|
||||
|
||||
SourcePal.resize(MapWidth*MapHeight*3);
|
||||
TileToPalNum.resize(MapWidth*MapHeight);
|
||||
DestPal.resize(NUM_OF_PAL_ENTRIES*3);
|
||||
MapPal.resize(NUM_OF_PAL_ENTRIES);
|
||||
|
||||
for (int f=0;f<MapWidth*MapHeight;f++)
|
||||
{
|
||||
SourcePal[f*3+0]=Tiles[f].r;
|
||||
SourcePal[f*3+1]=Tiles[f].g;
|
||||
SourcePal[f*3+2]=Tiles[f].b;
|
||||
}
|
||||
|
||||
tquant(&SourcePal[0],&TileToPalNum[0],&DestPal[0],NUM_OF_PAL_ENTRIES,MapWidth*MapHeight);
|
||||
|
||||
for (int c=0;c<NUM_OF_PAL_ENTRIES;c++)
|
||||
{
|
||||
MapPal[c].r=DestPal[c*3+0];
|
||||
MapPal[c].g=DestPal[c*3+1];
|
||||
MapPal[c].b=DestPal[c*3+2];
|
||||
}
|
||||
}
|
||||
|
||||
void CMapFile::WriteMapPalette(FILE * F)
|
||||
{
|
||||
int count = NUM_OF_PAL_ENTRIES;
|
||||
|
||||
fwrite( &count, sizeof(u32), 1,F);
|
||||
|
||||
for (int f=0;f<count;f++)
|
||||
{
|
||||
u8 Dummy = 0;
|
||||
|
||||
|
||||
fwrite( &MapPal[f].r, sizeof(u8), 1,F);
|
||||
fwrite( &MapPal[f].g, sizeof(u8), 1,F);
|
||||
fwrite( &MapPal[f].b, sizeof(u8), 1,F);
|
||||
fwrite( &Dummy,sizeof(u8),1,F);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Function:
|
||||
Purpose:
|
||||
Params:
|
||||
Returns:
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
void CMapFile::SetInfoOut( int x, int y, TILE_PACKET * T, OUT_TILE_PACKET * O )
|
||||
{
|
||||
|
||||
|
||||
O->mType = 0;
|
||||
|
||||
if (T->height<0)
|
||||
{
|
||||
O->ypos = 0;
|
||||
// printf("low height %d\n", T->height);
|
||||
} else
|
||||
if (T->height>255*4.f)
|
||||
{
|
||||
O->ypos = 255;
|
||||
// printf("hi height %d\n", T->height);
|
||||
} else
|
||||
{
|
||||
O->ypos = (T->height/4.f);
|
||||
}
|
||||
|
||||
|
||||
O->mNeighbours = 0;
|
||||
O->mDirection = 0;
|
||||
|
||||
if (T->frame > 4095) GObject::Error(ERR_FATAL, "Tile index overflow" );
|
||||
|
||||
O->mTileIndex = T->frame;
|
||||
O->mTileIndex |= (T->angle << 12); // STUFF ANGLE IN TOP BITS OF TILE INDEX
|
||||
O->ColIdx = GetPalNum( x, y );
|
||||
O->mFlags = T->flags;
|
||||
|
||||
if (T->xflip) O->mTileIndex |= (1 << 15); // SET X/Y FLIP IN TOP BITS OF TILE INDEX
|
||||
if (T->yflip) O->mTileIndex |= (1 << 14);
|
||||
|
||||
switch(T->type)
|
||||
{
|
||||
case TT_VOID:
|
||||
O->mType = (u8)CELL_Void;
|
||||
break;
|
||||
case TT_PATH:
|
||||
O->mType = (u8)CELL_Path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Function:
|
||||
Purpose:
|
||||
Params:
|
||||
Returns:
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
void CMapFile::Export( const char * file )
|
||||
{
|
||||
FILE * level;
|
||||
|
||||
MakeMapPalette();
|
||||
|
||||
level = fopen( file, "wb" );
|
||||
if (level)
|
||||
{
|
||||
WriteMapPalette( level );
|
||||
|
||||
fwrite( &MapWidth, sizeof( int ), 1, level );
|
||||
fwrite( &MapHeight, sizeof( int ), 1, level );
|
||||
|
||||
for (int y=0;y<MapHeight;y++)
|
||||
{
|
||||
for (int x=0;x<MapWidth;x++)
|
||||
{
|
||||
TILE_PACKET * tile;
|
||||
OUT_TILE_PACKET out;
|
||||
|
||||
tile = &Tiles[x + (y * MapWidth)];
|
||||
|
||||
SetInfoOut( x, y, tile, &out );
|
||||
|
||||
fwrite( &out, sizeof(OUT_TILE_PACKET), 1, level );
|
||||
}
|
||||
}
|
||||
|
||||
fwrite( &nbModels, sizeof( int ), 1, level );
|
||||
for (int i=0;i<nbModels;i++)
|
||||
{
|
||||
fwrite( &Models[i], sizeof(MODEL_PACKET), 1, level );
|
||||
}
|
||||
fwrite( &nbSpawnPoints, sizeof(int), 1, level );
|
||||
for (i=0; i<nbSpawnPoints; i++)
|
||||
{
|
||||
fwrite( &Spawn[i], sizeof(SPAWNPOS), 1, level);
|
||||
}
|
||||
// printf( "WRITTEN %s\n", file );
|
||||
}
|
||||
else
|
||||
{
|
||||
GObject::Error(ERR_FATAL, "Could not save lvl file - %s", file );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================
|
||||
end */
|
Loading…
Add table
Add a link
Reference in a new issue