This commit is contained in:
Daveo 2000-12-02 18:55:49 +00:00
parent 7551b4f12e
commit 8788076d39
37 changed files with 11186 additions and 0 deletions

View file

@ -0,0 +1,270 @@
/*=========================================================================
ANIMHEADER.CPP
Author: Gary Liddon @
Created:
Project:
Purpose:
Copyright (c) 1998 G R Liddon
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
#include <strstream>
/* Glib
---- */
#include <pcre.h>
#include <gobject.hpp>
/* Local
----- */
#include "animheader.h"
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
using namespace std;
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
static int GetHex(char const * Str);
/*----------------------------------------------------------------------
Vars
---- */
/*----------------------------------------------------------------------
Data
---- */
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int GetHex(char const * Str)
{
char Buffer[1024];
strcpy(Buffer,Str);
strstream i(Buffer,1024);
int Val;
i>>hex>>Val;
return(Val);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void MakeAnimHeader( char * line, AnimHeaderItem * item )
{
int len;
int pos;
char anim[1024];
char animno[8];
pos = 0;
len = strlen( line );
if (len > 4)
{
int count = 0;
// FIND ANIM
while(count != 3)
{
while(line[pos] != '_')
{
pos++;
if (pos >= len)
{
GObject::Error(ERR_FATAL,"Header scan overrun line - %s\n", line);
}
}
pos++;
count++;
}
// GET ANIM NAME
count = 0;
while(line[pos] != ' ')
{
anim[count++] = line[pos++];
if (pos > len)
{
GObject::Error(ERR_FATAL,"Header scan overrun line - %s\n", line);
}
}
anim[count] = 0;
// GET ANIM NUMBER
pos += 3;
count = 0;
while(line[pos] != ',')
{
animno[count++] = line[pos++];
if (pos > len)
{
GObject::Error(ERR_FATAL,"Header scan overrun line - %s\n", line);
}
}
animno[count] = 0;
strupr( anim );
item->m_AnimName = anim;
item->m_Frame = atoi( animno );
}
else
{
GObject::Error(ERR_FATAL,"Incorrect header line - %s\n", line);
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void readAnimHeaderFile(char const * Name, std::vector<AnimHeaderItem> & Items)
{
char Line[1024];
try
{
ifstream InStream;
InStream.open(Name,ios::in);
if (InStream)
{
InStream.getline(Line,1024); // HEADER GUARD
InStream.getline(Line,1024); // HEADER GUARD
InStream.getline(Line,1024); // ENUM
InStream.getline(Line,1024); // {
InStream.getline(Line,1024); // ANIM COUNT
while (!InStream.eof() && Line[0] != '}')
{
InStream.getline(Line,1024);
if (strlen(Line) && Line[0] != '}')
{
AnimHeaderItem MyItem;
MakeAnimHeader( Line, &MyItem );
InStream.getline(Line,1024); // NUMBER OF FRAMES
Items.push_back( MyItem );
}
}
InStream.close();
}
else
{
throw("Error opening anim header file");
}
}
catch (char const * E)
{
GObject::Error(ERR_FATAL,"Error in AddToTexList : %s",E);
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AnimHeaderFile::load(char const * name)
{
vector<AnimHeaderItem> items;
readAnimHeaderFile(name,items);
int numOfItems;
numOfItems=items.size();
for (int f=0;f<numOfItems;f++)
{
AnimHeaderItem dummyResult;
// if (find(items[f].m_texName,dummyResult))
// GObject::Error(ERR_FATAL,"%s already defined in anim header file database",(char const *)items[f].m_texName);
// makeTexNameCompliant(items[f].m_texName);
// m_strToInfo[items[f].m_texName]=items[f];
}
m_lastLoadedFile=name;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void AnimHeaderFile::makeTexNameCompliant(GString & str)
{
str.Lower();
str.Filter("\\",'/');
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool AnimHeaderFile::find(GString const & str,AnimHeaderItem & result)
{
GString srchStr;
map<GString,AnimHeaderItem>::iterator it;
srchStr=str;
makeTexNameCompliant(srchStr);
it=m_strToInfo.find(srchStr);
if (it == m_strToInfo.end())
{
return(false);
}
else
{
result=m_strToInfo[srchStr];
return(true);
}
}
/*===========================================================================
end */

View file

@ -0,0 +1,87 @@
/*=========================================================================
ANIMHEADER.H
Author: Gary Liddon @
Created:
Project:
Purpose:
Copyright (c) 1998 G R Liddon
===========================================================================*/
#pragma warning( disable : 4786 )
#ifndef __ANIMHEADER_H__
#define __ANIMHEADER_H__
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
#include <vector>
#include <map>
/* Glib
---- */
#include <gtypes.h>
#include <gstring.hpp>
/* Local
----- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
struct AnimHeaderItem
{
GString m_AnimName;
int m_Frame;
};
class AnimHeaderFile
{
private:
GString m_lastLoadedFile;
std::map<GString,AnimHeaderItem> m_strToInfo;
void makeTexNameCompliant(GString & str);
public:
void load(char const * name);
bool find(GString const & str,AnimHeaderItem & result);
char const * getLastFileLoaded(void)
{return(m_lastLoadedFile);}
};
/*----------------------------------------------------------------------
Globals
------- */
/* Vars
---- */
/* Data
---- */
/* Functions
--------- */
void readAnimHeaderFile(char const * Name,std::vector<AnimHeaderItem> & Items);
/*---------------------------------------------------------------------- */
#endif /* __ANIMHEADER_H__ */
/*===========================================================================
end */

180
Utils/Libs/GinLib/ginio.cpp Normal file
View file

@ -0,0 +1,180 @@
/*=========================================================================
FILENAME.CPP
Author: Gary Liddon @
Created:
Project:
Purpose:
Copyright (c) 1998 G R Liddon
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
/* Glib
---- */
/* Local
----- */
#include "ginio.h"
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
using namespace std;
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
/*----------------------------------------------------------------------
Vars
---- */
/*----------------------------------------------------------------------
Data
---- */
vector<GinChunk *> GinFile::ChunkHandlers;
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
GinChunk::GinChunk(void)
{
Size=0;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
GinChunk::~GinChunk(void)
{
DumpData();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void GinChunk::Load(Gifstream & In)
{
Data.resize(Size);
In.read((char *)(&Data[0]),Size);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void GinFile::AddHandler(GinChunk * New)
{
ChunkHandlers.push_back(New);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
GinChunk * GinFile::GetHandler(char const * Name)
{
GString ChunkName(Name);
GinChunk * RetChunk;
RetChunk=NULL;
for (int f=0;f<ChunkHandlers.size() && !RetChunk;f++)
{
if (ChunkName==GString(ChunkHandlers[f]->GetName()))
RetChunk=ChunkHandlers[f]->MakeNew();
}
return(RetChunk);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool GinFile::GinHdr::ReadHdr(Gifstream & In)
{
vector<char> Str;
bool Done;
GString RetStr;
Done=false;
Str.reserve(1000);
while (In && !In.eof() && !Done)
{
char c=In.get();
if (!c)
Done=true;
Str.push_back(c);
}
if (Done)
{
Name=&Str[0];
In.Align(4);
if (In)
{
Size=In.Get32();
}
else
Done=false;
}
return(Done);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void GinChunk::DumpData(void)
{
Size=0;
Data.resize(0);
}
/*===========================================================================
end */

233
Utils/Libs/GinLib/ginio.h Normal file
View file

@ -0,0 +1,233 @@
/*=========================================================================
FILENAME.CPP
Author: Gary Liddon @
Created:
Project:
Purpose:
Copyright (c) 1998 G R Liddon
===========================================================================*/
#ifndef __GINIO_H__
#define __GINIO_H__
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
#pragma warning( disable : 4786 )
#include <vector>
#include <fstream>
#include <misc.hpp>
#include <gstring.hpp>
/* Glib
---- */
/* Local
----- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
class GinChunk : public GObject
{
public:
GinChunk(void);
virtual ~GinChunk(void);
void LoadFile(Gifstream & In);
virtual char const * GetName(void) const
{return("DEFAULT"); }
void SetNameSize(char const * NewName,int NewSize)
{
Name=NewName;
Size=NewSize;
}
virtual void Load(Gifstream & In);
virtual GinChunk * MakeNew(void)
{return(new GinChunk);}
protected:
void DumpData(void);
GString Name;
int Size;
std::vector<u8> Data;
};
class GinFile : public GObject
{
public:
GinFile(void)
{
ReadUnknownChunks=false;
}
~GinFile(void)
{
int i;
for (i=0; i<ChunkHandlers.size(); i++) delete ChunkHandlers[i];
ChunkHandlers.clear();
for (i=0; i<Chunks.size(); i++) delete Chunks[i];
Chunks.clear();
}
void ResetChunks()
{
for (int f=0;f<Chunks.size();f++) delete Chunks[f];
Chunks.clear();
}
void SetReadUnknownChunks(bool New)
{
ReadUnknownChunks=New;
}
static void AddHandler(GinChunk * New);
void Load(char const * File)
{
ResetChunks();
Gifstream In(Gifstream::LITTLE_ENDIAN);
In.open(File,std::ios::binary);
if (In)
{
GinHdr MyHdr;
while (MyHdr.ReadHdr(In))
{
int ChunkLenAligned;
int ChunkPos;
GinChunk * ChunkReader;
ChunkReader=GetHandler(MyHdr.Name);
if (!ChunkReader && ReadUnknownChunks)
ChunkReader=new GinChunk;
ChunkLenAligned=GU_AlignVal(MyHdr.Size,4);
ChunkPos=In.tellg();
if (ChunkReader)
{
ChunkReader->SetNameSize(MyHdr.Name,MyHdr.Size);
ChunkReader->Load(In);
Chunks.push_back(ChunkReader);
}
if (In)
In.seekg(ChunkLenAligned+ChunkPos,std::ios::beg);
else
{
Error(ERR_FATAL,"Error loading chunk");
}
}
In.close();
}
else
Error(ERR_FATAL,"Can't open gin file %s",File);
}
int FindChunks(char const * Type,std::vector<GinChunk const *> & RetChunks)
{
int NumOfChunks;
NumOfChunks=0;
for (int f=0;f<Chunks.size();f++)
{
GString Name;
Name=Chunks[f]->GetName();
if (Name==Type)
{
RetChunks.push_back(Chunks[f]);
NumOfChunks++;
}
}
return(NumOfChunks);
}
protected:
struct GinHdr
{
GinHdr(void)
{Size=0;}
bool ReadHdr(Gifstream & In);
bool PeekHdr(Gifstream & In)
{
int InPos;
bool Ret;
InPos=In.tellg();
Ret=ReadHdr(In);
if (Ret)
In.seekg(InPos,std::ios::beg);
return(Ret);
}
GString Name;
int Size;
};
std::vector<GinChunk *> Chunks;
bool ReadUnknownChunks;
static std::vector<GinChunk *> ChunkHandlers;
static GinChunk * GetHandler(char const * Name);
};
/*----------------------------------------------------------------------
Globals
------- */
/* Vars
---- */
/* Data
---- */
/* Functions
--------- */
/*---------------------------------------------------------------------- */
#endif /* __GINIO_H__ */
/*===========================================================================
end */

View file

@ -0,0 +1,152 @@
# Microsoft Developer Studio Project File - Name="GinLib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=GinLib - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ginlib.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ginlib.mak" CFG="GinLib - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "GinLib - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "GinLib - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/TP2psx/utils/GinLib", FUQBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "GinLib - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\glib\include" /I "..\glib\include\pc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "GinLib - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\glib\include" /I "..\glib\include\pc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fr /YX /FD /GZ /c
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "GinLib - Win32 Release"
# Name "GinLib - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\animheader.cpp
# End Source File
# Begin Source File
SOURCE=.\ginio.cpp
# End Source File
# Begin Source File
SOURCE=.\gintex.cpp
# End Source File
# Begin Source File
SOURCE=.\mapread.cpp
# End Source File
# Begin Source File
SOURCE=.\Maths.cpp
# End Source File
# Begin Source File
SOURCE=.\repread.cpp
# End Source File
# Begin Source File
SOURCE=.\script.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\animheader.h
# End Source File
# Begin Source File
SOURCE=.\ginio.h
# End Source File
# Begin Source File
SOURCE=.\gintex.h
# End Source File
# Begin Source File
SOURCE=.\IniClass.h
# End Source File
# Begin Source File
SOURCE=.\mapread.h
# End Source File
# Begin Source File
SOURCE=.\Maths.h
# End Source File
# Begin Source File
SOURCE=.\repread.h
# End Source File
# Begin Source File
SOURCE=.\script.h
# End Source File
# End Group
# End Target
# End Project

View file

@ -0,0 +1,970 @@
#include <algorithm>
#include <gfname.hpp>
#include "gintex.h"
#include "Maths.h"
using namespace std;
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
// Unconditional string compare
// REturns 1 on equal
int IsStrSame(char *Str0,char *Str1,int Len)
{
if (Len==-1)
{
Len=strlen(Str0);
if (strlen(Str1)!=Len) return(0);
}
for (int Loop=0;Loop<Len;Loop++)
{
char C0=Str0[Loop];
char C1=Str1[Loop];
if (C0>='a' && C0<='z') C0+='A'-'a';
if (C1>='a' && C1<='z') C1+='A'-'a';
if (C0!=C1) return(0);
}
return(1);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int CMat4::GetTexId(int v)
{
int NumOfTextures;
NumOfTextures=Mats.size();
if (v>=NumOfTextures)
{
GObject::Error(ERR_WARNING,"erroneous material id of %d\n",v);
v = 0;
}
if (v>=NumOfTextures)
GObject::Error(ERR_FATAL,"material asked for when none exists",v);
return Mats[v].TexId;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CMat4::Load(Gifstream & In)
{
int m = In.Get32();
int o = In.Get32();
Mats.resize(m);
for (int i=0; i<m; i++)
{
for (int j=0; j<8; j++)
In.Get32();
int tf = (int)In.Get32();
int temp2 = In.Get32();
if (temp2&1 == 0)
{
tf = -1;
}
Mats[i].TexId = tf;
Mats[i].Flags = temp2;
}
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CMesh::Load(Gifstream & In)
{
Obj = In.Get32();
int NbMesh = In.Get32();
Chunk.resize(NbMesh);
for (int i=0; i<NbMesh; i++)
{
Chunk[i].MatId = s16(In.Get16());
Chunk[i].NumFace = s16(In.Get16());
Chunk[i].MeshNum = In.Get32();
Chunk[i].Attrib = In.Get32();
Chunk[i].Normals = In.Get32();
Chunk[i].Vcol = In.Get32();
Chunk[i].Tex = In.Get32();
}
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CMod4::Load(Gifstream & In)
{
Mod4Chunk ThisChunk;
In.read((char*)&ThisChunk.nCurObj , sizeof(long));
In.read(ThisChunk.Name, 32);
In.read((char*)&ThisChunk.Radius, sizeof(float));
In.read((char*)&ThisChunk.CentreX, sizeof(float));
In.read((char*)&ThisChunk.CentreY, sizeof(float));
In.read((char*)&ThisChunk.CentreZ, sizeof(float));
In.read((char*)&ThisChunk.ApX, sizeof(float));
In.read((char*)&ThisChunk.ApY, sizeof(float));
In.read((char*)&ThisChunk.ApZ, sizeof(float));
Chunk.push_back(ThisChunk);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CTexName::Load(Gifstream & In)
{
int NumOfNames;
NumOfNames=In.Get32();
for (int f=0;f<NumOfNames;f++)
{
vector<char> Str;
bool Done;
Str.reserve(200);
Done=false;
In.Align(4);
while (!Done)
{
char c;
c=In.get();
if (!c)
Done=true;
Str.push_back(c);
}
Names.push_back(&Str[0]);
}
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CGinTree::Load(Gifstream & In)
{
LoadTree(In,-1);
}
/*****************************************************************************/
void CGinTree::LoadTree(Gifstream & In,int Parent)
{
CNode ThisNode;
In.Align(4);
In.read(ThisNode.Name, 32);
In.read((char*)&ThisNode.XPos, 4);
In.read((char*)&ThisNode.YPos, 4);
In.read((char*)&ThisNode.ZPos, 4);
In.read((char*)&ThisNode.XAng, 4);
In.read((char*)&ThisNode.YAng, 4);
In.read((char*)&ThisNode.ZAng, 4);
In.read((char*)&ThisNode.WAng, 4);
In.read((char*)&ThisNode.Xapk, 4);
In.read((char*)&ThisNode.Yapk, 4);
In.read((char*)&ThisNode.Zapk, 4);
In.read((char*)&ThisNode.Xapu, 4);
In.read((char*)&ThisNode.Yapu, 4);
In.read((char*)&ThisNode.Zapu, 4);
In.read((char*)&ThisNode.Wapu, 4);
int ChildCount= In.Get32();
SceneTree[0].AddChild( SceneTree,ThisNode,Parent);
int Idx=ThisNode.Idx;
for (int Loop=0;Loop<ChildCount;Loop++) LoadTree(In,Idx);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CSkinTree::Load(Gifstream & In)
{
In.Get32(); // Skip Obj number
LoadTree(In,-1);
}
/*****************************************************************************/
void CSkinTree::LoadTree(Gifstream & In,int Parent)
{
CNode ThisNode;
int WeightCount;
In.Align(4);
In.read(ThisNode.Name, 32);
WeightCount=In.Get32();
if (WeightCount)
{
ThisNode.Weights.resize(WeightCount);
for (int Weight=0;Weight<WeightCount;Weight++)
{
ThisNode.Weights[Weight].VertNo=In.Get32();
In.read((char*)&ThisNode.Weights[Weight].Weight, 4);
In.read((char*)&ThisNode.Weights[Weight].X, 4);
In.read((char*)&ThisNode.Weights[Weight].Y, 4);
In.read((char*)&ThisNode.Weights[Weight].Z, 4);
}
}
int ChildCount= In.Get32();
SkinTree[0].AddChild( SkinTree,ThisNode,Parent);
int Idx=ThisNode.Idx;
for (int Loop=0;Loop<ChildCount;Loop++) LoadTree(In,Idx);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
const int CHANNEL_TYPE_TREE = 7; // NODE ANIMATION
void CAnimTree::Load(Gifstream & In)
{
int AnimType=In.Get32();
if (AnimType!=CHANNEL_TYPE_TREE) return;
int FrameCount = In.Get32();
LoadTree(In,-1,FrameCount);
}
/*****************************************************************************/
void CAnimTree::LoadTree(Gifstream & In,int Parent,int FrameCount)
{
CNode ThisNode;
In.Align(4);
ThisNode.Anim.resize(FrameCount);
for (int Frame=0;Frame<FrameCount;Frame++)
{
In.read((char*)&ThisNode.Anim[Frame].XPos, 4);
In.read((char*)&ThisNode.Anim[Frame].YPos, 4);
In.read((char*)&ThisNode.Anim[Frame].ZPos, 4);
In.read((char*)&ThisNode.Anim[Frame].XAng, 4);
In.read((char*)&ThisNode.Anim[Frame].YAng, 4);
In.read((char*)&ThisNode.Anim[Frame].ZAng, 4);
In.read((char*)&ThisNode.Anim[Frame].WAng, 4);
In.read((char*)&ThisNode.Anim[Frame].kX, 4);
In.read((char*)&ThisNode.Anim[Frame].kY, 4);
In.read((char*)&ThisNode.Anim[Frame].kZ, 4);
In.read((char*)&ThisNode.Anim[Frame].uX, 4);
In.read((char*)&ThisNode.Anim[Frame].uY, 4);
In.read((char*)&ThisNode.Anim[Frame].uZ, 4);
In.read((char*)&ThisNode.Anim[Frame].uW, 4);
}
int ChildCount= In.Get32();
AnimTree[0].AddChild( AnimTree,ThisNode,Parent);
int Idx=ThisNode.Idx;
for (int Loop=0;Loop<ChildCount;Loop++) LoadTree(In,Idx,FrameCount);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CKeyAnimTree::Load(Gifstream & In)
{
int AnimType=In.Get32();
if (AnimType!=CHANNEL_TYPE_TREE) return;
AnimType=In.Get32(); // Skip Node type thingy
LoadTree(In,-1);
}
/*****************************************************************************/
void CKeyAnimTree::LoadTree(Gifstream & In,int Parent)
{
CNode ThisNode;
int KeyCount;
In.Align(4);
KeyCount=In.Get32();
ThisNode.KeyAnim.resize(KeyCount);
for (int Frame=0;Frame<KeyCount;Frame++)
{
ThisNode.KeyAnim[Frame].Frame=In.Get32();
In.read((char*)&ThisNode.KeyAnim[Frame].XPos, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].YPos, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].ZPos, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].XAng, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].YAng, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].ZAng, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].WAng, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].kX, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].kY, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].kZ, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].uX, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].uY, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].uZ, 4);
In.read((char*)&ThisNode.KeyAnim[Frame].uW, 4);
}
int ChildCount= In.Get32();
AnimTree[0].AddChild( AnimTree,ThisNode,Parent);
int Idx=ThisNode.Idx;
for (int Loop=0;Loop<ChildCount;Loop++) LoadTree(In,Idx);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
bool CScene::SetPruneNodes(int Idx)
{
CNode &ThisNode=GetNode(Idx);
bool NoPrune=false;
int ChildCount=ThisNode.GetChildCount();
for (int Loop=0;Loop<ChildCount;Loop++) NoPrune|= SetPruneNodes(ThisNode.ChildList[Loop]);
int HasData=ThisNode.Weights.size() | ThisNode.Pts.size();
if (!NoPrune && !HasData)
{
ThisNode.Active=false;
return(false);
}
else
{
return(true);
}
}
/*****************************************************************************/
void CScene::BuildPruneTree(int Idx, int ParentIdx)
{
CNode &ThisNode=GetNode(Idx);
if (!ThisNode.Active) return;
ThisNode.AddPruneChild(SceneTree,PruneTree,ParentIdx);
int ChildCount=ThisNode.GetChildCount();
for (int Loop=0;Loop<ChildCount;Loop++) BuildPruneTree(ThisNode.ChildList[Loop],ThisNode.Idx);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int IsAnimDiff(sGinAnim const &Frm0,sGinAnim const &Frm1)
{
if (Frm0.XPos!=Frm1.XPos) return(1);
if (Frm0.YPos!=Frm1.YPos) return(1);
if (Frm0.ZPos!=Frm1.ZPos) return(1);
if (Frm0.XAng!=Frm1.XAng) return(1);
if (Frm0.YAng!=Frm1.YAng) return(1);
if (Frm0.ZAng!=Frm1.ZAng) return(1);
if (Frm0.WAng!=Frm1.WAng) return(1);
return(0);
}
/*****************************************************************************/
void LoadAndShrinkAnim(CNode const &KeyNode,CNode const &AnimNode,CNode &OutNode)
{
// Calc Extents from Key Frames
int Key,Frame;
int StartKey=0,EndKey=KeyNode.KeyAnim.size();
if (!EndKey) // No keys, create 1 and return
{
sGinAnim ForceKey;
ForceKey.Frame=0;
ForceKey.XPos=OutNode.XPos; ForceKey.YPos=OutNode.YPos; ForceKey.ZPos=OutNode.ZPos;
ForceKey.XAng=OutNode.XAng; ForceKey.YAng=OutNode.YAng; ForceKey.ZAng=OutNode.ZAng; ForceKey.WAng=OutNode.WAng;
OutNode.KeyAnim.push_back(ForceKey);
OutNode.ShrunkKeyAnim.push_back(ForceKey);
EndKey=0;
OutNode.StartFrame= 0;
OutNode.EndFrame= 0;
}
else
{
EndKey--;
while ((!IsAnimDiff(KeyNode.KeyAnim[StartKey], KeyNode.KeyAnim[StartKey+1])) && StartKey!=EndKey) StartKey++;
while ((!IsAnimDiff(KeyNode.KeyAnim[EndKey ], KeyNode.KeyAnim[EndKey-1])) && StartKey!=EndKey) EndKey--;
OutNode.StartFrame= KeyNode.KeyAnim[StartKey].Frame;
OutNode.EndFrame= KeyNode.KeyAnim[EndKey].Frame;
EndKey++;
}
OutNode.EndFrame++;
// Transfer Key Frames
int KeyAnimSize=KeyNode.KeyAnim.size();
for (Key=0;Key<KeyAnimSize;Key++) OutNode.KeyAnim.push_back(KeyNode.KeyAnim[Key]); // Transfer All key frames
for (Key=StartKey; Key<EndKey; Key++) OutNode.ShrunkKeyAnim.push_back(KeyNode.KeyAnim[Key]); // Transfer Shrunk key frames
// Transfer Normal frames
int AnimSize=AnimNode.Anim.size();
if (AnimSize)
{
for (Frame=0;Frame<AnimSize;Frame++) OutNode.Anim.push_back(AnimNode.Anim[Frame]); // Transfer All Normal Anim
for (Frame=OutNode.StartFrame; Frame<OutNode.EndFrame; Frame++) OutNode.ShrunkAnim.push_back(AnimNode.Anim[Frame]); // Transfer Shrunk Normal Anim
}
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void Gin4File::Load(char const * Name)
{
MyFile.Load(Name);
MyFile.FindChunks("VERS",VersionChunk);
MyFile.FindChunks("TEX4",TexNamesChunk);
MyFile.FindChunks("MAT4",MatChunk);
MyFile.FindChunks("MOD4",Mod4Chunk);
MyFile.FindChunks("MESH",MshChunk);
MyFile.FindChunks("PTS4",PointsChunk);
MyFile.FindChunks("POLY",TrisChunk);
MyFile.FindChunks("VCOL",VColTrisChunk);
MyFile.FindChunks("MAP4",UVtrisChunk);
MyFile.FindChunks("TREE",SceneTreeChunk);
MyFile.FindChunks("ANIM",AnimTreeChunk);
MyFile.FindChunks("KEY4",KeyAnimTreeChunk);
MyFile.FindChunks("BONE",SkinTreeChunk);
MyFile.FindChunks("PROP",UserPropChunk);
MyFile.FindChunks("CAM4",CameraChunk);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CScene::Load(const char *Name)
{
Gin4File GinFile;
FileName=Name;
MTH_Init();
GinFile.Load(Name);
std::vector<GinChunk const *> &VersionChunk=GinFile.GetVersionChunk();
std::vector<GinChunk const *> &TexNamesChunk=GinFile.GetTexNamesChunk();
std::vector<GinChunk const *> &MatChunk=GinFile.GetMatChunk();
std::vector<GinChunk const *> &MshChunk=GinFile.GetMshChunk();
std::vector<GinChunk const *> &PointsChunk=GinFile.GetPointsChunk();
std::vector<GinChunk const *> &TrisChunk=GinFile.GetTrisChunk();
std::vector<GinChunk const *> &VColTrisChunk=GinFile.GetVColTrisChunk();
std::vector<GinChunk const *> &UVtrisChunk=GinFile.GetUVtrisChunk();
std::vector<GinChunk const *> &SceneTreeChunk=GinFile.GetSceneTreeChunk();
std::vector<GinChunk const *> &AnimTreeChunk=GinFile.GetAnimTreeChunk();
std::vector<GinChunk const *> &KeyAnimTreeChunk=GinFile.GetKeyAnimTreeChunk();
std::vector<GinChunk const *> &SkinTreeChunk=GinFile.GetSkinTreeChunk();
std::vector<GinChunk const *> &UserPropChunk=GinFile.GetUserPropChunk();
std::vector<GinChunk const *> &CameraChunk=GinFile.GetCameraChunk();
int Node,NodeCount;
// Build Scene Tree
CGinTree *GT = (CGinTree*)SceneTreeChunk[0];
std::vector<CNode> const &GinTree=GT->GetTree();
NodeCount=GinTree.size();
for (Node=0;Node<NodeCount;Node++)
{
CNode ThisNode=GinTree[Node];
SceneTree[0].AddChild(SceneTree,ThisNode,ThisNode.ParentIdx);
}
// Build Node Mtx's
for (Node=0;Node<NodeCount;Node++)
{
CNode *ThisNode=&SceneTree[Node];
int ParentIdx=ThisNode->ParentIdx;
ThisNode->Mtx=Identity;
// Build Node Mtx's
if (ParentIdx!=-1)
{
// LocalMtx
TMATRIX ThisMtx,ParentMtx;
CNode *ParentNode=&SceneTree[ParentIdx];
ParentMtx=ParentNode->Mtx;
TQUAT ThisQ(ThisNode->XAng,ThisNode->YAng,ThisNode->ZAng,ThisNode->WAng);
ThisQ.QuatToMat(&ThisMtx);
ThisMtx.SetPosition(ThisNode->XPos,ThisNode->YPos,ThisNode->ZPos);
ThisNode->Mtx=ParentMtx*ThisMtx;
// WorldMtx
ThisNode->WorldMtx=GetWorldMatrix(SceneTree,ParentIdx);
}
}
/*
for (Node=0;Node<NodeCount;Node++)
{
CNode GinNode=GinTree[Node];
SceneTree[0].AddChild(SceneTree,GinNode,GinNode.ParentIdx);
// Build Node Mtx's
CNode ThisNode=SceneTree[Node];
SceneTree[Node].Mtx=Identity;
if (GinNode.ParentIdx!=-1)
{
TMATRIX ThisMtx,ParentMtx;
CNode *ParentNode=&SceneTree[ThisNode.ParentIdx];
ParentMtx=ParentNode->Mtx;
TQUAT ThisQ(ThisNode.XAng,ThisNode.YAng,ThisNode.ZAng,ThisNode.WAng);
ThisQ.QuatToMat(&ThisMtx);
ThisMtx.t[0]=ThisNode.XPos; ThisMtx.t[1]=ThisNode.YPos; ThisMtx.t[2]=ThisNode.ZPos;
SceneTree[Node].Mtx=ParentMtx*ThisMtx;
}
}
*/
//-----------------------------------------------------------------------------
// Load Materials
int MatN = MatChunk.size();
if (MatN)
{
CMat4 * Materials = (CMat4*)MatChunk[0];
AllMaterials = Materials->GetMaterials();
if (TexNamesChunk.size())
{
CTexName * T=(CTexName *)(TexNamesChunk[0]);
vector<GString> const & Strs=T->GetTexNames();
TextureList = Strs;
int NumOfMeshes=MshChunk.size();
for (int j=0; j<NumOfMeshes; j++)
{
CMesh *M = (CMesh*)MshChunk[j];
vector<MeshChunk> const & Mat4Id = M->GetChunk();
for (int i=0; i<Mat4Id.size(); i++)
{
if (Mat4Id[i].MatId>=0)
{
int tid = Materials->GetTexId(Mat4Id[i].MatId);
if (tid >= Strs.size() || tid < 0)
{
GObject::Error(ERR_WARNING,"Texture index odd (aksed for %d, max is %d) adjusting to 0\n",tid,Strs.size());
tid=0;
}
// else
{
GString const & TexFile=Strs[tid];
/* Only add texture to list if it hasn't been on it before */
if (find(AllTexNames.begin(),AllTexNames.end(),TexFile) == AllTexNames.end()) AllTexNames.push_back(TexFile);
}
}
}
}
}
}
else
{
GObject::Error(ERR_WARNING,"No Materials\n");
}
//-----------------------------------------------------------------------------
// Load Models and Meshes
for (int m=0; m<MshChunk.size(); m++)
{
CMesh *M = (CMesh*)MshChunk[m];
int CurMod = M->getObj();
CNode *ThisNode=GetNodePtr(GinFile.GetModelName(CurMod));
if (loadPoints( CurMod, PointsChunk,ThisNode) != -1)
{
vector<MeshChunk> const &MeshChunks = M->GetChunk();
for (int mn=0; mn<MeshChunks.size(); mn++)
{
if (loadTris( CurMod, MeshChunks[mn].MeshNum, TrisChunk,ThisNode)!=-1)
{
int MatIdx = addMaterialIdx(MeshChunks[mn].MatId);
for (int i=0; i<MeshChunks[mn].NumFace; i++) ThisNode->TriMaterial.push_back(MatIdx);
loadVCol( CurMod, MeshChunks[mn].MeshNum, VColTrisChunk,ThisNode);
loadUV( CurMod, MeshChunks[mn].MeshNum, UVtrisChunk,ThisNode);
int Size=ThisNode->Tris.size();
ThisNode->UVTris.resize(Size);
ThisNode->VColTris.resize(Size);
ThisNode->TriMaterial.resize(Size);
}
}
}
}
//-----------------------------------------------------------------------------
// Load Anims
// Sort KeyFrame Anims
CKeyAnimTree *KATC= (CKeyAnimTree*)KeyAnimTreeChunk[0];
CAnimTree *NATC = (CAnimTree*)AnimTreeChunk[0];
std::vector<CNode>const &KeyAnimTree=KATC->GetTree();
std::vector<CNode>const &AnimTree=NATC->GetTree();
NodeCount=KeyAnimTree.size();
for (Node=0;Node<NodeCount;Node++)
{
LoadAndShrinkAnim(KeyAnimTree[Node],AnimTree[Node],SceneTree[Node]);
}
//-----------------------------------------------------------------------------
// Load Camera(s)
int CamCount=CameraChunk.size();
if (CamCount)
{
for (int Cam=0;Cam<CamCount;Cam++)
{
CCamera *CamC= (CCamera *)CameraChunk[Cam];
Camera.push_back(CamC->GetCam());
}
}
//-----------------------------------------------------------------------------
// Load Skin Weight
if (SkinTreeChunk.size())
{
CSkinTree *ST = (CSkinTree*)SkinTreeChunk[0];
std::vector<CNode> const &SkinTree=ST->GetTree();
NodeCount=SkinTree.size();
for (Node=0;Node<NodeCount;Node++)
{
int WeightCount=SkinTree[Node].Weights.size();
if (WeightCount)
{
SceneTree[Node].Weights.resize(WeightCount);
for (int Weight=0;Weight<WeightCount;Weight++) SceneTree[Node].Weights[Weight]=SkinTree[Node].Weights[Weight];
}
}
}
//-----------------------------------------------------------------------------
// Load User Props - Loaded as Ini File
int PropCount=UserPropChunk.size();
for (int Loop=0;Loop<PropCount;Loop++)
{
CUserProp *UP=(CUserProp*)UserPropChunk[Loop];
if (UP)
{
CNode *ThisNode=GetNodePtr(UP->GetModNum()+1); // Skip SceneRoot);
if (ThisNode)
{
std::vector<char> const & Prop=UP->GetUserProp();
int Size=Prop.size()-1;
if (Size>0)
{
// ThisNode->UserProp.resize(Size);
// for (int c=0;c<Size;c++) ThisNode->UserProp[c]=Prop[c];
char *PropPtr=(char*)&Prop[0];
ThisNode->UserProp.Import(PropPtr);
}
}
}
}
//-----------------------------------------------------------------------------
// Build Pruned Tree
ResetPruneTree();
SetPruneNodes(0);
BuildPruneTree(0,-1);
//-----------------------------------------------------------------------------
// Print Trees
// PrintSceneTree();
// PrintPruneTree();
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
void CScene::PrintTreeNode(int Idx,const int Tree)
{
/*
CNode &Node=SceneTree[Idx];
int NodeIdx,NodeParentIdx;
std::vector<int> ChildList;
if (Tree==0)
{
ChildList=Node.ChildList;
NodeIdx=Node.Idx;
NodeParentIdx=Node.ParentIdx;
}
else
{
ChildList=Node.PruneChildList;
NodeIdx=Node.PruneIdx;
NodeParentIdx=Node.PruneParentIdx;
}
int ChildCount=ChildList.size();
for (int Sp=0;Sp<PrintTreeSpace;Sp++) printf("| ");
printf("(P=%i I=%i C=%i) %s - T=%i, V=%i A=%i\n",NodeParentIdx,NodeIdx,ChildCount,Node.Name,Node.Tris.size(),Node.Pts.size(),Node.Anim.size());
PrintTreeSpace++;
for (int Child=0;Child<ChildCount;Child++) PrintTreeNode(ChildList[Child],Tree);
PrintTreeSpace--;
*/
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int CScene::loadPoints( int CurMod, vector<GinChunk const *> &Points ,CNode *ThisNode)
{
for (int f=0; f<Points.size(); f++)
{
CPts4 * T;
T=(CPts4 *)(Points[f]);
if (T->GetModNum() == CurMod)
{
std::vector<TVECTOR> const & ThesePts=T->GetPts();
int Size= ThesePts.size();
ThisNode->Pts.resize(Size);
ThisNode->RelPts.resize(Size);
TMATRIX IMtx=ThisNode->Mtx;
IMtx.inverse(ThisNode->Mtx);
for (int g=0;g<Size;g++)
{
/*Abs Pnt*/ ThisNode->Pts[g] = ThesePts[g];
/*Rel Pnt*/
//TVECTOR InVtx(ThesePts[g].x,ThesePts[g].y,ThesePts[g].z);
TVECTOR InVtx=ThesePts[g];//(ThesePts[g].x,ThesePts[g].y,ThesePts[g].z);
TVECTOR OutVtx=IMtx*InVtx;
// ThisNode->RelPts[g].x = OutVtx.GetX();
// ThisNode->RelPts[g].y = OutVtx.GetY();
// ThisNode->RelPts[g].z = OutVtx.GetZ();
ThisNode->RelPts[g]=OutVtx;
}
return (Size);
}
}
return -1;
}
/*****************************************************************************/
int CScene::loadTris( int CurMod, int CurMesh, vector<GinChunk const *> &Tris,CNode *ThisNode)
{
for (int i=0; i<Tris.size(); i++)
{
CPoly * T;
T=(CPoly *)(Tris[i]);
if (T->GetModNum() == CurMod && T->GetMeshNum() == CurMesh)
{
std::vector<sGinTri> const & TheseTris=T->GetTris();
int Size = TheseTris.size();
ThisNode->TriBase=ThisNode->Tris.size();
for (int j=0; j<Size; j++) ThisNode->Tris.push_back(TheseTris[j]);
return (Size);
}
}
return -1;
}
/*****************************************************************************/
int CScene::loadUV( int CurMod, int CurMesh, vector<GinChunk const *> &UVTris,CNode *ThisNode)
{
for (int i=0; i<UVTris.size(); i++)
{
CUVtri *T;
T = (CUVtri*)UVTris[i];
if (T->GetModNum() == CurMod && T->GetMeshNum() == CurMesh)
{
std::vector<sUVTri> const & TheseTris=T->GetUVTris();
int Size = TheseTris.size();
for (int j=0; j<Size; j++) ThisNode->UVTris.push_back(TheseTris[j]);
return (Size);
}
}
return -1;
}
/*****************************************************************************/
int CScene::loadVCol( int CurMod, int CurMesh, vector<GinChunk const *> &VColTris,CNode *ThisNode)
{
for (int i=0; i<VColTris.size(); i++)
{
CVcol *T;
T = (CVcol*)VColTris[i];
if (T->GetModNum() == CurMod && T->GetMeshNum() == CurMesh)
{
std::vector<sVColTri> const & TheseTris=T->GetVcolTris();
int Size = TheseTris.size();
for (int j=0; j<Size; j++) ThisNode->VColTris.push_back(TheseTris[j]);
return (Size);
}
}
return -1;
}
/*****************************************************************************/
int CScene::addMaterialIdx( int idx )
{
int c = UsedMaterials.size();
for (int i=0; i<c; i++)
{
if (UsedMaterials[i] == idx) return i;
}
UsedMaterials.push_back(idx);
return c;
}
/*****************************************************************************/
static GString GetNameAndExtOnly(char const * Name)
{
GString Rep(Name);
Rep.Filter("/",'\\');
GFName FName(Rep);
Rep=FName.File();
Rep+=".";
Rep+=FName.Ext();
Rep.Lower();
return(Rep);
}
/*****************************************************************************/
void CScene::GetNonSharedTextures(vector<GString> const & SharedTextures,vector<GString> & Dest)
{
for (int f=0;f<AllTexNames.size();f++)
{
bool Found;
Found=false;
GString NameOnly(GetNameAndExtOnly(AllTexNames[f]));
for (int t=0;t<SharedTextures.size() && !Found;t++)
{
GString TexNameOnly(GetNameAndExtOnly(SharedTextures[t]));
Found=TexNameOnly==NameOnly;
}
if (!Found)
{
GFName TexName(AllTexNames[f]);
GFName GinName(FileName);
GinName.File(TexName.File());
GinName.Ext(TexName.Ext());
GString FinalName(GinName.FullName());
FinalName.Lower();
Dest.push_back(FinalName);
}
}
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
TMATRIX GetWorldMatrix(std::vector<CNode> const &Tree,int Idx)
{
CNode ThisNode=Tree[Idx];
int ParentIdx=ThisNode.ParentIdx;
TMATRIX ParentMtx=Identity;
if (ParentIdx!=-1) ParentMtx=GetWorldMatrix(Tree,ParentIdx);
TMATRIX ThisMtx=Identity;
TMATRIX PosMtx=Identity;
TMATRIX RotMtx=Identity;
TMATRIX StrMtx=Identity;
TMATRIX SclMtx=Identity;
TMATRIX IStrMtx=Identity;
// Pos
PosMtx=Identity;
PosMtx.SetPosition(ThisNode.XPos,ThisNode.YPos,ThisNode.ZPos);
// Rot
TQUAT RotQ(ThisNode.XAng,ThisNode.YAng,ThisNode.ZAng,ThisNode.WAng);
RotQ.QuatToMat(&RotMtx);
// Stretch
TQUAT StrQ(ThisNode.Xapu,ThisNode.Yapu,ThisNode.Zapu,ThisNode.Wapu);
StrQ.QuatToMat(&StrMtx);
IStrMtx=StrMtx.inverse();
// Scale
SclMtx=Identity;
SclMtx.ApplyScaleXYZ(ThisNode.Xapk,ThisNode.Yapk,ThisNode.Zapk);
ThisMtx= PosMtx*RotMtx*StrMtx*SclMtx*IStrMtx;
return(ParentMtx*ThisMtx);
}
//----------------------------------------------------------------------------
TVECTOR GetWorldPos(std::vector<CNode> const &Tree,int Idx)
{
CNode ThisNode=Tree[Idx];
TVECTOR ThisPos(ThisNode.XPos,ThisNode.YPos,ThisNode.ZPos);
TMATRIX WorldMtx=GetWorldMatrix(Tree,ThisNode.ParentIdx);
// if (WorldMtx!=ThisNode.WorldMtx) printf("!!!");
return(WorldMtx*ThisPos);
}
//----------------------------------------------------------------------------
TVECTOR GetWorldPos(TMATRIX &WorldMtx,TVECTOR &ThisPos)
{
return(WorldMtx*ThisPos);
}
TVECTOR CNode::GetWorldPos(TVECTOR &Pos)
{
return(::GetWorldPos(WorldMtx,Pos));
}
TQUAT CNode::GetWorldAng(TQUAT &Q)
{
return(TQUAT(0,0,0,0));
}

780
Utils/Libs/GinLib/gintex.h Normal file
View file

@ -0,0 +1,780 @@
/********************/
/*** Daves GinTex ***/
/********************/
#pragma warning( disable : 4786 )
#ifndef __GINTEX_H__
#define __GINTEX_H__
#include <vector>
#include "ginio.h"
#include "maths.h"
#include "IniClass.h"
/*****************************************************************************/
int IsStrSame(char *Str0,char *Str1,int Len=-1);
/*****************************************************************************/
/*** Version Chunk ***********************************************************/
/*****************************************************************************/
class CVers : public GinChunk
{
public:
virtual char const * GetName(void) const {return("VERS");}
int GetVersion(void) {return(Version);}
protected:
virtual GinChunk * MakeNew(void) {return(new CVers);}
virtual void Load(Gifstream & In)
{
Version=In.Get32();
}
int Version;
};
/*****************************************************************************/
/*** Material Chunk **********************************************************/
/*****************************************************************************/
struct Material
{
int TexId;
int Flags;
};
class CMat4 : public GinChunk
{
public:
virtual char const * GetName(void) const {return("MAT4");}
std::vector<Material> const & GetMaterials(void) const {return(Mats);}
int GetTexId(int v);
protected:
virtual GinChunk * MakeNew(void) {return(new CMat4);}
virtual void Load(Gifstream & In);
std::vector<Material> Mats;
};
/*****************************************************************************/
/*** Mesh Chunk **************************************************************/
/*****************************************************************************/
struct MeshChunk
{
int MatId;
int NumFace;
int MeshNum;
int Attrib;
int Normals;
int Vcol;
int Tex;
};
class CMesh : public GinChunk
{
public:
virtual char const * GetName(void) const {return("MESH");}
std::vector<MeshChunk> const & GetChunk(void) const {return(Chunk);}
int getObj( void ) const {return Obj;}
protected:
int Obj;
std::vector<MeshChunk> Chunk;
virtual GinChunk * MakeNew(void) {return(new CMesh);}
virtual void Load(Gifstream & In);
};
/*****************************************************************************/
/*** Model Chunk *************************************************************/
/*****************************************************************************/
struct Mod4Chunk
{
long nCurObj;
char Name[32];
float Radius;
float CentreX,CentreY,CentreZ;
float ApX,ApY,ApZ;
};
class CMod4: public GinChunk
{
public:
virtual char const * GetName(void) const {return("MOD4");}
std::vector<Mod4Chunk> const & GetChunk(void) const {return(Chunk);}
char * GetModelName() {return(Chunk[0].Name);}
protected:
std::vector<Mod4Chunk> Chunk;
virtual GinChunk * MakeNew(void) {return(new CMod4);}
virtual void Load(Gifstream & In);
};
/*****************************************************************************/
/*** Texture Name Chunk ******************************************************/
/*****************************************************************************/
class CTexName : public GinChunk
{
public:
virtual char const * GetName(void) const {return("TEX4");}
std::vector<GString> const & GetTexNames(void) const {return(Names);}
virtual GinChunk * MakeNew(void) {return(new CTexName);}
virtual void Load(Gifstream & In);
protected:
std::vector<GString> Names;
};
/*****************************************************************************/
/*** Vtx Chunk ***************************************************************/
/*****************************************************************************/
/*struct vec
{
float x,y,z;
vec() {x = y = z = 0.f;}
vec(float _x, float _y, float _z) {x = _x; y = _y;z = _z;}
};
*/
class CPts4: public GinChunk
{
virtual char const * GetName(void) const {return("PTS4");}
virtual GinChunk * MakeNew(void) {return(new CPts4);}
virtual void Load(Gifstream & In)
{
ModNum = In.Get32();
int nv = In.Get32();
Pnts.resize(nv);
for (int i = 0; i< nv ;i++)
{
float x,y,z;
In.read((char*)&x, 4);
In.read((char*)&y, 4);
In.read((char*)&z, 4);
Pnts[i] = TVECTOR(x,y,z);
}
}
public:
std::vector<TVECTOR> const & GetPts(void) const {return(Pnts);}
int GetModNum(void) const {return ModNum;}
protected:
int ModNum;
std::vector<TVECTOR> Pnts;
};
/*****************************************************************************/
/*** Poly Chunk **************************************************************/
/*****************************************************************************/
struct sGinTri
{
int p[3];
int vis[3];
BOOL operator==(sGinTri const &v1)
{
for (int i=0; i<3;i++)
{
if (p[i]!=v1.p[i]) return(FALSE);
if (vis[i]!=v1.vis[i]) return(FALSE);
}
return (TRUE);
}
};
class CPoly: public GinChunk
{
virtual char const * GetName(void) const {return("POLY");}
virtual GinChunk * MakeNew(void) {return(new CPoly);}
virtual void Load(Gifstream & In)
{
ModNum = In.Get16();
MeshNum = In.Get16();
int nf = In.Get32();
Tris.resize(nf);
for(int i=0; i<nf; i++)
{
for (int j=0; j<3; j++) Tris[i].p[j] = In.Get32();
for (int h=0; h<3; h++) Tris[i].vis[h] = In.Get32();
}
}
public:
std::vector<sGinTri> const & GetTris(void) const {return(Tris);}
int GetModNum(void) const {return ModNum;}
int GetMeshNum(void) const {return MeshNum;}
protected:
int ModNum,MeshNum;
std::vector<sGinTri> Tris;
};
/*****************************************************************************/
/*** Vtx Color Chunk *********************************************************/
/*****************************************************************************/
struct sRGB
{
float r,g,b;
};
struct sVColTri
{
sRGB p[3];
};
class CVcol: public GinChunk
{
virtual char const * GetName(void) const {return("VCOL");}
virtual GinChunk * MakeNew(void) {return(new CVcol);}
virtual void Load(Gifstream & In)
{
ModNum = In.Get32();
MeshNum = In.Get32();
int nf = In.Get32();
Tris.resize(nf);
for(int i=0; i<nf; i++)
{
for (int j=0; j<3; j++)
{
float r,g,b;
In.read((char*)&r, 4);
In.read((char*)&g, 4);
In.read((char*)&b, 4);
Tris[i].p[j].r = r;
Tris[i].p[j].g = g;
Tris[i].p[j].b = b;
}
}
}
public:
std::vector<sVColTri> const & GetVcolTris(void) const {return(Tris);}
int GetModNum(void) const {return ModNum;}
int GetMeshNum(void) const {return MeshNum;}
protected:
int ModNum,MeshNum;
std::vector<sVColTri> Tris;
};
/*****************************************************************************/
/*** Texture UV's Chunk ******************************************************/
/*****************************************************************************/
struct sUV
{
float u,v;
BOOL operator==(sUV const &v1)
{
return(u==v1.u && v==v1.v);
}
};
struct sUVTri
{
sUV p[3];
BOOL operator==(sUVTri const &v1)
{
for (int i=0; i<3;i++)
{
if (!(p[i]==v1.p[i])) return(FALSE);
}
return (TRUE);
}
};
class CUVtri: public GinChunk
{
virtual char const * GetName(void) const {return("MAP4");}
virtual GinChunk * MakeNew(void) {return(new CUVtri);}
virtual void Load(Gifstream & In)
{
ModNum = In.Get16();
MeshNum = In.Get16();
int nf = In.Get32();
Tris.resize(nf);
for(int i=0; i<nf; i++)
{
for (int j=0; j<3; j++)
{
float u,v;
In.read((char*)&u, 4);
In.read((char*)&v, 4);
Tris[i].p[j].u = u;
Tris[i].p[j].v = v;
}
}
}
public:
std::vector<sUVTri> const & GetUVTris(void) const {return(Tris);}
int GetModNum(void) const {return ModNum;}
int GetMeshNum(void) const {return MeshNum;}
protected:
int ModNum,MeshNum;
std::vector<sUVTri> Tris;
};
/*****************************************************************************/
/*** Scene Tree Chunk ********************************************************/
/*****************************************************************************/
struct sGinWeight
{
long VertNo;
float Weight;
float X,Y,Z;
};
struct sGinAnim
{
int Frame;
float XPos,YPos,ZPos;
float XAng,YAng,ZAng,WAng;
float kX,kY,kZ;
float uX,uY,uZ,uW;
};
class CNode
{
public:
int IsNodePrefix(char *InName) // Checks prefix
{
return(IsStrSame(InName,Name,strlen(InName)));
}
int IsNodeName(char *InName) // Checks full name
{
return(IsStrSame(InName,Name));
}
void AddChild(std::vector<CNode> &Tree,CNode &Node,int Parent)
{
Node.ChildList.clear();
int TreeSize=Tree.size();
Node.ParentIdx=Parent;
Node.Idx=TreeSize;
Node.Active=true;
if (Parent!=-1) Tree[Parent].ChildList.push_back(Node.Idx);
if (!(Parent==-1 && Node.Idx)) Tree.push_back(Node);
}
void AddPruneChild(std::vector<CNode> &SceneTree,std::vector<int> &PruneTree,int Parent)
{
PruneIdx=PruneTree.size();
PruneTree.push_back(Idx);
if (Parent!=-1)
{
PruneParentIdx=SceneTree[Parent].PruneIdx;
SceneTree[Parent].PruneChildList.push_back(Idx);
}
else
{
PruneParentIdx=-1;
}
}
TVECTOR GetWorldPos(TVECTOR &Pos);// {return(WorldMtx*Pos);}
TVECTOR GetWorldPos(float X,float Y,float Z) {return(GetWorldPos(TVECTOR (X,Y,Z)));}
TVECTOR GetWorldPos() {return(GetWorldPos(TVECTOR (XPos,YPos,ZPos)));}
TQUAT GetWorldAng(TQUAT &Q);// {return(WorldMtx*Pos);}
TQUAT GetWorldAng(float X,float Y,float Z,float W) {return(GetWorldAng(TQUAT (X,Y,Z,W)));}
TQUAT GetWorldAng() {return(GetWorldAng(TQUAT (XAng,YAng,ZAng,WAng)));}
int GetChildCount() {return(ChildList.size());}
int GetPruneChildCount() {return(PruneChildList.size());}
std::vector<TVECTOR> const &GetPts() const {return(Pts);}
std::vector<TVECTOR> const &GetRelPts() const {return(RelPts);}
std::vector<sGinTri> const &GetTris() const {return(Tris);}
std::vector<sVColTri> const &GetVColTris() const {return(VColTris);}
std::vector<sUVTri> const &GetUVTris() const {return(UVTris);}
std::vector<int> const &GetTriMaterial() const {return(TriMaterial);}
std::vector<sGinAnim> const &GetAnim() const {return(Anim);}
std::vector<sGinAnim> const &GetKeyAnim() const {return(KeyAnim);}
std::vector<sGinAnim> const &GetShrunkAnim() const {return(ShrunkAnim);}
std::vector<sGinAnim> const &GetShrunkKeyAnim() const {return(ShrunkKeyAnim);}
char *GetName() {return(Name);}
int Idx,ParentIdx;
int PruneIdx,PruneParentIdx;
char Name[32];
float XPos,YPos,ZPos;
float XAng,YAng,ZAng,WAng;
float Xapk,Yapk,Zapk;
float Xapu,Yapu,Zapu,Wapu;
int Active;
TMATRIX Mtx,WorldMtx;
CIni UserProp;
std::vector<int> ChildList;
std::vector<int> PruneChildList;
std::vector<sGinWeight> Weights;
std::vector<TVECTOR> Pts;
std::vector<TVECTOR> RelPts;
std::vector<sGinTri> Tris;
std::vector<sVColTri> VColTris;
std::vector<sUVTri> UVTris;
std::vector<int> TriMaterial;
std::vector<sGinAnim> Anim;
std::vector<sGinAnim> KeyAnim;
// Shrunk Anim stuff
int StartFrame,EndFrame;
std::vector<sGinAnim> ShrunkAnim;
std::vector<sGinAnim> ShrunkKeyAnim;
long Flags,Pad;
int TriggerCount,TriggerIdx;
int TriBase;
};
class CGinTree: public GinChunk
{
virtual char const * GetName(void) const {return("TREE");}
virtual GinChunk * MakeNew(void) {return(new CGinTree);}
virtual void Load(Gifstream & In);
void LoadTree(Gifstream & In,int Parent);
public:
std::vector<CNode> const & GetTree(void) const{return(SceneTree);}
protected:
std::vector<CNode> SceneTree;
};
/*****************************************************************************/
/*** Skin Chunk **************************************************************/
/*****************************************************************************/
class CSkinTree: public GinChunk
{
virtual char const * GetName(void) const {return("BONE");}
virtual GinChunk * MakeNew(void) {return(new CSkinTree);}
virtual void Load(Gifstream & In);
void LoadTree(Gifstream & In,int Parent);
public:
std::vector<CNode> const & GetTree(void) const{return(SkinTree);}
protected:
std::vector<CNode> SkinTree;
};
/*****************************************************************************/
/*** Tree Anim Chunk *********************************************************/
/*****************************************************************************/
class CAnimTree: public GinChunk
{
virtual char const * GetName(void) const {return("ANIM");}
virtual GinChunk * MakeNew(void) {return(new CAnimTree);}
virtual void Load(Gifstream & In);
void LoadTree(Gifstream & In,int Parent,int FrameCount);
public:
std::vector<CNode> const & GetTree(void) const{return(AnimTree);}
// int GetFrameCount() {return(FrameCount);}
protected:
// int FrameCount;
std::vector<CNode> AnimTree;
};
/*****************************************************************************/
/*** Tree Key Anim Chunk *****************************************************/
/*****************************************************************************/
class CKeyAnimTree: public GinChunk
{
virtual char const * GetName(void) const {return("KEY4");}
virtual GinChunk * MakeNew(void) {return(new CKeyAnimTree);}
virtual void Load(Gifstream & In);
void LoadTree(Gifstream & In,int Parent);
public:
std::vector<CNode> const & GetTree(void) const{return(AnimTree);}
protected:
std::vector<CNode> AnimTree;
};
/*****************************************************************************/
/*** User Prop Chunk *********************************************************/
/*****************************************************************************/
class CUserProp: public GinChunk
{
virtual char const * GetName(void) const {return("PROP");}
virtual GinChunk * MakeNew(void) {return(new CUserProp);}
virtual void Load(Gifstream & In)
{
ModNum = In.Get32()-1;
int Size = In.Get32();
Prop.resize(Size+1);
for(int i=0; i<Size; i++)
{
In.read((char*)&Prop[i],1);
}
Prop[Size]=0;
}
public:
std::vector<char> const & GetUserProp() const {return(Prop);}
int GetModNum(void) const {return ModNum;}
protected:
int ModNum;
std::vector<char> Prop;
};
/*****************************************************************************/
/*** Camera Chunk ************************************************************/
/*****************************************************************************/
struct sCam
{
std::vector<TVECTOR> CamPos;
std::vector<TVECTOR> Target;
} ;
class CCamera: public GinChunk
{
virtual char const * GetName(void) const {return("CAM4");}
virtual GinChunk * MakeNew(void) {return(new CCamera);}
virtual void Load(Gifstream & In)
{
int Frame,FrameCount = In.Get32();
ThisCam.CamPos.resize(FrameCount);
ThisCam.Target.resize(FrameCount);
for (Frame = 0; Frame< FrameCount;Frame++)
{
float x,y,z;
In.read((char*)&x, 4);
In.read((char*)&y, 4);
In.read((char*)&z, 4);
ThisCam.CamPos[Frame] = TVECTOR(x,y,z);
}
for (Frame = 0; Frame< FrameCount;Frame++)
{
float x,y,z;
In.read((char*)&x, 4);
In.read((char*)&y, 4);
In.read((char*)&z, 4);
ThisCam.Target[Frame]= TVECTOR(x,y,z);
}
}
public:
sCam const & GetCam(void) const {return(ThisCam);}
protected:
sCam ThisCam;
};
/*****************************************************************************/
/*** Gin Loader **************************************************************/
/*****************************************************************************/
class Gin4File : public GObject
{
public:
Gin4File(void)
{
MyFile.AddHandler(new CTexName);
MyFile.AddHandler(new CVers);
MyFile.AddHandler(new CMesh);
MyFile.AddHandler(new CMod4);
MyFile.AddHandler(new CMat4);
MyFile.AddHandler(new CPts4);
MyFile.AddHandler(new CPoly);
MyFile.AddHandler(new CVcol);
MyFile.AddHandler(new CUVtri);
MyFile.AddHandler(new CGinTree);
MyFile.AddHandler(new CAnimTree);
MyFile.AddHandler(new CKeyAnimTree);
MyFile.AddHandler(new CSkinTree);
MyFile.AddHandler(new CUserProp);
MyFile.AddHandler(new CCamera);
}
void Load(char const * Name);
std::vector<GinChunk const *> GetVersionChunk() {return(VersionChunk);}
std::vector<GinChunk const *> GetTexNamesChunk() {return(TexNamesChunk);}
std::vector<GinChunk const *> GetMatChunk() {return(MatChunk);}
std::vector<GinChunk const *> GetMod4Chunk() {return(Mod4Chunk);}
std::vector<GinChunk const *> GetMshChunk() {return(MshChunk);}
std::vector<GinChunk const *> GetPointsChunk() {return(PointsChunk);}
std::vector<GinChunk const *> GetTrisChunk() {return(TrisChunk);}
std::vector<GinChunk const *> GetVColTrisChunk() {return(VColTrisChunk);}
std::vector<GinChunk const *> GetUVtrisChunk() {return(UVtrisChunk);}
std::vector<GinChunk const *> GetSceneTreeChunk() {return(SceneTreeChunk);}
std::vector<GinChunk const *> GetAnimTreeChunk() {return(AnimTreeChunk);}
std::vector<GinChunk const *> GetKeyAnimTreeChunk(){return(KeyAnimTreeChunk);}
std::vector<GinChunk const *> GetSkinTreeChunk() {return(SkinTreeChunk);}
std::vector<GinChunk const *> GetUserPropChunk() {return(UserPropChunk);}
std::vector<GinChunk const *> GetCameraChunk() {return(CameraChunk);}
char * GetModelName(int ModelNum)
{
CMod4 *Mod=(CMod4*)Mod4Chunk[ModelNum];
return(Mod->GetModelName());
};
protected:
GinFile MyFile;
std::vector<GinChunk const *> VersionChunk;
std::vector<GinChunk const *> TexNamesChunk;
std::vector<GinChunk const *> MatChunk;
std::vector<GinChunk const *> Mod4Chunk;
std::vector<GinChunk const *> MshChunk;
std::vector<GinChunk const *> PointsChunk;
std::vector<GinChunk const *> TrisChunk;
std::vector<GinChunk const *> VColTrisChunk;
std::vector<GinChunk const *> UVtrisChunk;
std::vector<GinChunk const *> SceneTreeChunk;
std::vector<GinChunk const *> AnimTreeChunk;
std::vector<GinChunk const *> KeyAnimTreeChunk;
std::vector<GinChunk const *> SkinTreeChunk;
std::vector<GinChunk const *> UserPropChunk;
std::vector<GinChunk const *> CameraChunk;
};
/*****************************************************************************/
/*** Scene Storage ***********************************************************/
/*****************************************************************************/
class CScene
{
public:
void LoadWithTextures(char const * Name);
void Load(char const * Name);
//------------------
//--- Tree Stuff ---
//------------------
CNode &GetNode(int Idx) {return(SceneTree[Idx]);}
CNode *GetNodePtr(int Idx) {return(&GetNode(Idx));}
CNode *GetNodePtr(char *Name,int Start=0)
{
int TreeSize=GetSceneTreeSize();
for (int N=Start; N<TreeSize; N++) if (GetNode(N).IsNodeName(Name)) return(GetNodePtr(N));
return(0);
}
CNode *GetNodePtrPrefix(char *Name,int Start=0)
{
int TreeSize=GetSceneTreeSize();
for (int N=Start; N<TreeSize; N++) if (GetNode(N).IsNodePrefix(Name)) return(GetNodePtr(N));
return(0);
}
int GetSceneNodeCount() {return(SceneTree.size());}
int GetSceneTreeSize() {return(SceneTree.size());}
int GetPruneTreeSize() {return(PruneTree.size());}
CNode &GetSceneNode(int Idx) {return(GetNode(Idx));}
CNode &GetPruneNode(int Idx) {return(GetNode(PruneTree[Idx]));}
void PrintSceneTree(int Idx=0)
{
// printf("SceneTree - %i Nodes\n\n",SceneTree.size());
PrintTreeSpace=0;
PrintTreeNode(Idx,0);
}
void PrintPruneTree(int Idx=0)
{
// printf("PruneTree - %i Nodes\n\n",PruneTree.size());
PrintTreeSpace=0;
PrintTreeNode(Idx,1);
}
void PrintTreeNode(int Idx,const int);
void BuildPruneTree(int Idx, int ParentIdx);
bool SetPruneNodes(int Idx);
void ResetSceneTree() {SceneTree.clear();}
void ResetPruneTree()
{
int TreeSize=SceneTree.size();
for (int n=0;n<TreeSize;n++) SceneTree[n].PruneChildList.clear();
}
int CountAllChildren(int Idx) {return(_CountAllChildren(Idx)+1);}
//-----------------
//-----------------
//-----------------
std::vector<GString> const & GetTexNames(void) const {return(AllTexNames);}
std::vector<GString> const & GetTexList(void) const {return(TextureList);}
std::vector<Material> const & GetMaterials(void) const {return(AllMaterials);}
std::vector<int> const & GetUsedMaterialIdx(void) const {return(UsedMaterials);}
std::vector<sCam> const & GetCamera(void) const {return(Camera);}
void GetNonSharedTextures(std::vector<GString> const & SharedTextures,std::vector<GString> & Dest);
protected:
int loadPoints(int CurMod, std::vector<GinChunk const *> &Points,CNode *ThisNode);
int loadTris(int CurMod, int CurMesh, std::vector<GinChunk const *> &Tris,CNode *ThisNode);
int loadUV(int CurMod, int CurMesh, std::vector<GinChunk const *> &UVTris,CNode *ThisNode);
int loadVCol(int CurMod, int CurMesh, std::vector<GinChunk const *> &VColTris,CNode *ThisNode);
int addMaterialIdx( int idx );
int _CountAllChildren(int Idx)
{
CNode &ThisNode=GetNode(Idx);
int NodeCount=0;
int ChildCount= ThisNode.GetPruneChildCount();
for (int Loop=0;Loop<ChildCount;Loop++) NodeCount+=_CountAllChildren(ThisNode.PruneChildList[Loop]);
return(NodeCount+ChildCount);
}
GString FileName;
std::vector<GString> AllTexNames;
std::vector<GString> TextureList;
std::vector<Material> AllMaterials;
std::vector<int> UsedMaterials;
std::vector<CNode> SceneTree;
std::vector<int> PruneTree;
std::vector<sCam> Camera;
int CurTree;
int PrintTreeSpace;
};
/*****************************************************************************/
TMATRIX GetWorldMatrix(std::vector<CNode> const &Tree,int Idx);
TVECTOR GetWorldPos(std::vector<CNode> const &Tree,int Idx);
TVECTOR GetWorldPos(TMATRIX &WorldMtx,TVECTOR &ThisPos);
#endif

View 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 */

497
Utils/Libs/GinLib/mapread.h Normal file
View file

@ -0,0 +1,497 @@
/*=========================================================================
EXPORT.H
Author:
Created:
Project:
Purpose:
Copyright (c) 1998 Climax Development Ltd
===========================================================================*/
#pragma warning( disable : 4786 )
#ifndef __EXPORT_H__
#define __EXPORT_H__
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
#include <vector>
#include <algorithm>
/* Glib
---- */
#include <gtypes.h>
#include <misc.hpp>
#include <gstring.hpp>
/* Local
----- */
#include "repread.h"
#include "animheader.h"
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
#define MAX_MASKX 8
#define MAX_MASKY 8
#define MAX_LINES 512
enum CELL_MODES
{
CELL_Void =(0),
CELL_Hidden =(1),
CELL_Path =(2),
CELL_Water =(3),
CELL_Queue =(4),
CELL_Thing =(5),
// CELL_TrackRide =(6),
CELL_NoGo =(7),
CELL_Entrance =(8),
CELL_Exit =(9),
CELL_QueueEdit =(10),
CELL_CoasterPylon =(11),
// actions
CELL_Delete =(50),
CELL_DeleteLine =(51),
CELL_PatrolArea =(52),
CELL_BacktrackVoid =(53),
// special modes
// CM_SpecialMode =(128), // yes, these 2 are supposed to be the same
CM_CalcNeighbours =(128),
CM_CalcTile =(129),
CM_CalcDirections =(130),
CM_SetParent =(131),
CM_CreateBridges =(132),
CM_CreateBridgeSpans =(133),
CM_ShowTransparent =(256),
CM_NoModify =(512),
};
enum MAP_TILE_FLAGS
{
TF_NONE = (0<<0),
TF_HIDDEN = (1<<0),
TF_NO_BUILD = (1<<1),
TF_SPAWN = (1<<2),
TF_ENTRANCE = (1<<3),
TF_TRACKRIDE = (1<<4),
TF_NO_WALK = (1<<5),
};
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
enum
{
MAP_MAX_FILE_NAME_LENGTH = 512,
};
enum TILE_TYPE
{
TT_VOID = 0,
TT_PATH = 1,
};
struct CFileName
{
bool Stripped;
char Name[MAP_MAX_FILE_NAME_LENGTH];
char FullName[MAP_MAX_FILE_NAME_LENGTH];
};
struct TILE_PACKET
{
u8 r, g, b, pad;
int height;
int flags;
int frame;
int angle;
int xflip;
int yflip;
int type;
};
#pragma pack(1)
struct OUT_TILE_PACKET // *** TS - Must be reflected in Tile.h - CTile ***
{
u8 mType; // 1
u8 ypos; // 1
u8 mNeighbours; // 1
u8 mDirection; // 1 - 4
u16 mTileIndex; // 2
u8 ColIdx; // 1
u8 mFlags; // 1 - 4
};
#pragma pack()
/* CELL_MODES mType; // 4 make a u8 saves 3
s16 Height; // Make a u8 saves 1
u8 mNeighbours; // Take out saves 1
u8 mDirection; // 2 bits, put in flags saves 1
u16 mTileIndex; // 2 - Also contains frame angle
u8 ColIdx; // 1
u8 mFlags; // 1
u8 heightoffset; // 1 Take out saves 1
s8 mOverlapCounter; // 1 Take out saves 1
u16 FogTblIndex; // 2 Put into frame structure saves 2*/
enum MODEL_FLAGS
{
MODEL_ANIMATE_FLAG = (1 << 24),
MODEL_BUSSTOP_FLAG = (1 << 25),
MODEL_BOOTH_FLAG = (1 << 26),
MODEL_ENTRANCE_FLAG = (1 << 27),
MODEL_OTHERANIM_FLAG = (1 << 28),
MODEL_FLAGS_MASK = (0xff << 24),
};
struct MODEL_PACKET
{
u32 AnimAndFlags;
u16 xp, yp, zp, ya;
};
struct MapCTile
{
float r,g,b;
u16 type;
u16 neighbours;
u8 object;
u8 flag;
float px,py,pz;
float nx,ny,nz;
u32 frame;
char FrameName[128];
int PSXFrame;
int angle;
float u0;
float v0;
float u1;
float v1;
float u2;
float v2;
float u3;
float v3;
// *** NOTE: PLEASE ADD NEW VARIABLES HERE ***
float ambientr, ambientg, ambientb;
bool xflip;
bool yflip;
};
struct SPAWNPOS
{
u8 x, y;
};
struct CObject
{
CFileName Name;
int Width;
int Height;
int Depth;
bool Mask[MAX_MASKX][MAX_MASKY];
};
struct CModel
{
float PosX;
float PosY;
float PosZ;
float AngX;
float AngY;
float AngZ;
char MeshName[512];
u32 Mesh;
// MeshFile * Mesh;
bool Highlight;
// *** NOTE: PLEASE ADD NEW VARIABLES HERE AND CHANGE THE VERSION NO. ***
bool Snap;
bool ShowAxis;
bool m_Animates;
bool m_Busstop;
bool m_Booth;
bool m_Entrance;
bool m_OtherAnim;
};
/*----------------------------------------------------------------------
Globals
------- */
/* Vars
---- */
/* Data
---- */
/* Class
----- */
/*------------------------------------------*/
/* */
/*------------------------------------------*/
class CChunkFile
{
public:
CChunkFile()
{
}
~CChunkFile()
{
}
void Open( const char * file)
{
int fileSize;
fileSize=FileSize(file);
if (fileSize < 0)
GObject::Error(ERR_FATAL,"Error finding size of file %s",file);
Buffer=new u8[fileSize];
if (!Buffer)
GObject::Error(ERR_FATAL,"can't alloc mem");
std::ifstream inFile;
inFile.open(file,std::ios::binary);
if (inFile)
{
inFile.read((char*)(Buffer),fileSize);
inFile.close();
}
else
GObject::Error(ERR_FATAL,"Error opening %s",file);
}
void Seek( int l = 0 ) { Ptr = &Buffer[l]; }
void Close() { free( Buffer ); }
void Skip( int s ) { Ptr += s; }
void Read( int * ptr )
{
*ptr = *((int *)Ptr);
Ptr += 4;
}
void Read( void * ptr, int len )
{
for (int i=0;i<len;i++) ((u8 *)ptr)[i] = Ptr[i];
Ptr += len;
}
protected:
u8 * Buffer;
u8 * Ptr;
};
/*------------------------------------------*/
/* */
/*------------------------------------------*/
class CMapFile
{
public:
CMapFile()
{
m_errorOnMissingFile=true;
AnimHeaderFile=NULL;
}
~CMapFile()
{
}
void Open( const char * map, const char * rep, const char * anim )
{
MapFile.Open( map );
readRepFile( rep, RepItems );
readAnimHeaderFile( anim, AnimItems );
Objects = NULL;
Tiles = NULL;
TileNames = NULL;
Models = NULL;
AnimHeaderFile = anim;
}
void getTexturesUsed(char const * mapFile,std::vector<GString> & textures)
{
m_errorOnMissingFile=false;
MapFile.Open( mapFile );
Objects = NULL;
Tiles = NULL;
TileNames = NULL;
Models = NULL;
Parse();
for (int f=0;f<nbTiles;f++)
{
GString thisTile;
thisTile=TileNames[f].Name;
if (thisTile)
{
if (std::find(textures.begin(),textures.end(),thisTile)==textures.end())
textures.push_back(thisTile);
}
}
Close();
}
void Close()
{
MapFile.Close();
if (Objects) free( Objects );
if (Tiles) free( Tiles );
if (TileNames) free( TileNames );
if (Models) free( Models );
}
void Parse();
void Export( const char * file );
void GetAllTileNames();
int FindFrame( const char * frame );
int FindFileEquate( char * filename );
protected:
int GetVersion( char * version );
void MakeMapPalette(void);
void WriteMapPalette(FILE * F);
void WriteTileHdrs(FILE * F);
u8 GetPalNum(uint x,uint y)
{
if (!((x+y*MapWidth) < TileToPalNum.size()))
GObject::Error(ERR_FATAL,"uh?");
return(TileToPalNum[x+y*MapWidth]);
}
void SetInfoOut( int x, int y, TILE_PACKET * T, OUT_TILE_PACKET * O );
struct Col
{
u8 r,g,b;
};
std::vector<Col> MapPal;
std::vector<u8> TileToPalNum;
const char * AnimHeaderFile;
std::vector<RepItem> RepItems;
std::vector<AnimHeaderItem> AnimItems;
enum
{
NUM_OF_PAL_ENTRIES = 64,
MAX_SPAWNING_TILES = 2,
};
void MakeAnimName( char * out, char * in );
CChunkFile MapFile;
u8 VersionText[4];
int nbTiles;
CFileName * TileNames;
int nbObjects;
CObject * Objects;
int MapWidth;
int MapHeight;
int TileSize;
TILE_PACKET * Tiles;
int nbModels;
int ModelSize;
MODEL_PACKET * Models;
int nbSpawnPoints;
SPAWNPOS Spawn[MAX_SPAWNING_TILES];
bool m_errorOnMissingFile;
};
/* Functions
--------- */
/*---------------------------------------------------------------------- */
#endif /* __EXPORT_H__ */
/*===========================================================================
end */

320
Utils/Libs/GinLib/pak.cpp Normal file
View file

@ -0,0 +1,320 @@
/*=========================================================================
PAK.CPP
Author: Gary Liddon @ Climax (from work by Nick Pelling && Carl Muller)
Created:
Project: Diablo PSX
Purpose: PAK decompress \ compress code
Copyright (c) 1997 Climax Development Ltd
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
/* Glib
---- */
/* Local
----- */
#include <string.h>
#include "pak.h"
/* Graphics
-------- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
#define UNPAKBUFFERSIZE 4096
#define STRMAX 80
#define BUFFERSIZE 30000
#define TRIGGER 20000
#define MAXUNIQUE 127
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
struct Block
{
int data[128];
BOOL blockrep;
int blocksize;
int blockoffset;
u8 * Dest;
int outsize;
virtual void fputc(u8 Val)
{
*Dest=Val;
Dest++;
outsize++;
}
void writeBlock(void);
};
struct CountBlock : Block
{
virtual void fputc(u8 Val)
{
Dest++;
outsize++;
}
};
/*----------------------------------------------------------------------
Positional Vars
--------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
static void writeblock(struct block *theblock);
/*----------------------------------------------------------------------
Vars
---- */
/*----------------------------------------------------------------------
Data
---- */
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void Block::writeBlock(void)
{
if ((blockrep) && (blocksize == 0))
{
/* Terminator */
fputc(128);
fputc(0);
}
else if (blockrep)
{
fputc(blockoffset);
fputc(blocksize);
}
else /* Unique bytes */
{
fputc(blocksize & 127);
for (int i = 0; i <= blocksize; i++)
fputc(data[i]);
}
// Get ready for next block
blockrep = FALSE;
blockoffset = 0;
blocksize = -1;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int lowLevelPak(u8 * Dest,u8 const * buffer,int insize,Block & theblock)
{
long begin, end, bestlength;
int offset, bestoffset;
unsigned char const * theptr;
unsigned char const * ptr1;
unsigned char const * ptr2;
unsigned char const * ptr3;
long BACKDIST, FORWARDDIST, MINBLOCK;
theblock.Dest=Dest;
theblock.outsize=0;
theblock.blockrep=FALSE;
BACKDIST = -128;
FORWARDDIST = 255;
MINBLOCK = 3;
int inpos = 0;
theblock.blocksize = -1;
theblock.data[++theblock.blocksize] = buffer[inpos++];
theblock.data[++theblock.blocksize] = buffer[inpos++];
while (inpos < insize)
{
/* See if we should load new data into the buffer */
begin = -inpos;
end = insize - inpos;
if (begin < BACKDIST)
begin = BACKDIST;
if (end > FORWARDDIST)
end = FORWARDDIST;
bestoffset = begin;
bestlength = 1;
theptr = buffer + (inpos);
ptr1 = buffer + (inpos + begin);
for (offset = begin; offset < 0; offset++)
{
if (*ptr1 == *theptr)
{
if (memcmp(ptr1, theptr, bestlength + 1) == 0)
{
bestlength++;
bestoffset = offset;
ptr2 = ptr1 + bestlength;
ptr3 = theptr + bestlength;
while (*ptr2 == *ptr3)
{
ptr2++;
ptr3++;
bestlength++;
if (bestlength >= end)
break;
}
}
}
if (bestlength >= end)
{
bestlength = end;
break;
}
ptr1++;
}
if (bestlength < MINBLOCK)
{
/* See if last block is unique */
if (theblock.blockrep) /* Flush previous special block */
{
theblock.writeBlock();
theblock.data[++theblock.blocksize] = buffer[inpos++];
}
else
{
/* Add to it */
if (theblock.blocksize >= MAXUNIQUE)
theblock.writeBlock();
theblock.data[++theblock.blocksize] = buffer[inpos++];
}
}
else
{
/* We have found a match */
theblock.writeBlock();
theblock.blockrep = TRUE;
theblock.blocksize = bestlength;
theblock.blockoffset = bestoffset;
inpos += bestlength;
}
}
/* Flush buffer */
theblock.writeBlock();
/* Terminate file */
theblock.blockrep = TRUE;
theblock.blocksize = 0;
theblock.blockoffset = 0;
theblock.writeBlock();
return(theblock.outsize);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int PAK_doPak(u8 * Dest,u8 const * buffer,int insize)
{
Block outBlock;
return(lowLevelPak(Dest,buffer,insize,outBlock));
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int PAK_findPakSize(u8 const * buffer,int insize)
{
CountBlock outBlock;
return(lowLevelPak(NULL,buffer,insize,outBlock));
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int PAK_doUnpak(u8 * Dest,u8 const * Source)
{
int outsize = 0;
while (1) /* ie, continue until end mark */
{
u8 const * From;
int size;
int ch;
ch = *Source++;
if (ch < 128) /* if it is in range {0..127} then */
{
size = (ch + 1);
From=Source;
Source+=size;
}
else
{
size = *Source++;
if (size == 0) /* distance == 0 => end of file */
break;
From=Dest+(s8)ch;
}
memcpy(Dest,From,size);
Dest+=size;
outsize += size;
}
return(outsize);
}
/*===========================================================================
end */

60
Utils/Libs/GinLib/pak.h Normal file
View file

@ -0,0 +1,60 @@
/*=========================================================================
PAK.H
Author: Carl Muller (algorithm Nick Pelling && Carl Muller)
Created:
Project:
Purpose:
Copyright (c) 1997 Climax Development Ltd
===========================================================================*/
#ifndef __PAK_PAK_H__
#define __PAK_PAK_H__
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
/* Glib
---- */
#include <gtypes.h>
/* Local
----- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Globals
------- */
/* Vars
---- */
/* Data
---- */
/* Functions
--------- */
int PAK_doPak(u8 * Dest,u8 const * source,int insize);
int PAK_doUnpak(u8 * Dest,u8 const * Source);
int PAK_findPakSize(u8 const * souce,int insize);
/*---------------------------------------------------------------------- */
#endif /* __PAK_PAK_H__ */
/*===========================================================================
end */

View file

@ -0,0 +1,251 @@
/*=========================================================================
FILENAME.CPP
Author: Gary Liddon @
Created:
Project:
Purpose:
Copyright (c) 1998 G R Liddon
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
#include <strstream>
/* Glib
---- */
#include <pcre.h>
#include <gobject.hpp>
#include <gfname.hpp>
/* Local
----- */
#include "repread.h"
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
using namespace std;
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
static int GetHex(char const * Str);
/*----------------------------------------------------------------------
Vars
---- */
/*----------------------------------------------------------------------
Data
---- */
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
int GetHex(char const * Str)
{
char Buffer[1024];
strcpy(Buffer,Str);
strstream i(Buffer,1024);
int Val;
i>>hex>>Val;
return(Val);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void readRepFile(char const * Name,std::vector<RepItem> & Items)
{
char Line[1024];
try
{
ifstream InStream;
InStream.open(Name,ios::in);
if (InStream)
{
int frameNumber;
frameNumber=0;
InStream.getline(Line,1024);
pcre * MyPattern;
int Matches;
const int NumOfOffsets=60;
int Offsets[NumOfOffsets];
char const * ErrTxt;
int ErrNum;
MyPattern=pcre_compile("(\\S+)\\s+\\$(\\S+)\\s+\\$(\\S+)\\s+\\$(\\S+)\\s+\\$(\\S+)\\s+\\$(\\S+)\\s+\\$(\\S+)\\s+(\\d+)",0,&ErrTxt,&ErrNum,NULL);
while (!InStream.eof())
{
char SwitchText[100];
InStream.getline(Line,1024);
if (strlen(Line))
{
Matches=pcre_exec(MyPattern,NULL,Line,strlen(Line),0,Offsets,NumOfOffsets);
if (Matches != 9)
throw("error parsing rep file");
int Tpage,Clut,u,v,w,h;
bool Rotated;
Tpage=GetHex(&Line[Offsets[4]]);
Clut=GetHex(&Line[Offsets[6]]);
u=GetHex(&Line[Offsets[8]]);
v=GetHex(&Line[Offsets[10]]);
w=GetHex(&Line[Offsets[12]]);
h=GetHex(&Line[Offsets[14]]);
Rotated=atoi(&Line[Offsets[16]]) != 0;
memcpy(SwitchText,&Line[Offsets[2]],Offsets[3]-Offsets[2]);
SwitchText[Offsets[3]-Offsets[2]]=0;
RepItem MyItem;
MyItem.m_texName=SwitchText;
MyItem.m_texName.Lower();
MyItem.m_tpage=Tpage;
MyItem.m_clut=Clut;
MyItem.m_u=u;
MyItem.m_v=v;
MyItem.m_w=w;
MyItem.m_h=h;
MyItem.m_rotated=Rotated;
MyItem.m_frameNumber=frameNumber;
Items.push_back(MyItem);
frameNumber++;
}
}
InStream.close();
}
else
throw("Error opening report file");
}
catch (char const * E)
{
GObject::Error(ERR_FATAL,"Error in AddToTexList : %s",E);
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void RepFile::load(char const * name)
{
vector<RepItem> items;
readRepFile(name,items);
int numOfItems;
numOfItems=items.size();
for (int f=0;f<numOfItems;f++)
{
RepItem dummyResult;
if (find(items[f].m_texName,dummyResult))
GObject::Error(ERR_FATAL,"%s already defined in rep file database",(char const *)items[f].m_texName);
makeTexNameCompliant(items[f].m_texName);
m_strToInfo[items[f].m_texName]=items[f];
}
m_lastLoadedFile=name;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void RepFile::makeTexNameCompliant(GString & str)
{
str.Lower();
str.Filter("\\",'/');
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void RepFileNoDir::makeTexNameCompliant(GString & str)
{
GFName texFileName(str);
str=texFileName.File();
str.Lower();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool RepFile::find(GString const & str,RepItem & result)
{
GString srchStr;
map<GString,RepItem>::iterator it;
srchStr=str;
makeTexNameCompliant(srchStr);
it=m_strToInfo.find(srchStr);
if (it == m_strToInfo.end())
return(false);
else
{
result=m_strToInfo[srchStr];
return(true);
}
}
/*===========================================================================
end */

View file

@ -0,0 +1,98 @@
/*=========================================================================
FILENAME.CPP
Author: Gary Liddon @
Created:
Project:
Purpose:
Copyright (c) 1998 G R Liddon
===========================================================================*/
#pragma warning( disable : 4786 )
#ifndef __REPREAD_H__
#define __REPREAD_H__
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
#include <vector>
#include <map>
/* Glib
---- */
#include <gtypes.h>
#include <gstring.hpp>
/* Local
----- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
struct RepItem
{
GString m_texName;
u16 m_tpage;
u16 m_clut;
u8 m_u,m_v,m_w,m_h;
bool m_rotated;
int m_frameNumber;
};
class RepFile
{
private:
GString m_lastLoadedFile;
std::map<GString,RepItem> m_strToInfo;
virtual void makeTexNameCompliant(GString & str);
public:
void load(char const * name);
bool find(GString const & str,RepItem & result);
char const * getLastFileLoaded(void)
{return(m_lastLoadedFile);}
};
class RepFileNoDir : public RepFile
{
private:
virtual void makeTexNameCompliant(GString & str);
};
/*----------------------------------------------------------------------
Globals
------- */
/* Vars
---- */
/* Data
---- */
/* Functions
--------- */
void readRepFile(char const * Name,std::vector<RepItem> & Items);
/*---------------------------------------------------------------------- */
#endif /* __REPREAD_H__ */
/*===========================================================================
end */

View file

@ -0,0 +1,337 @@
/*=========================================================================
FILENAME.CPP
Author: Gary Liddon @
Created:
Project:
Purpose:
Copyright (c) 1998 G R Liddon
===========================================================================*/
/*----------------------------------------------------------------------
Includes
-------- */
#include "script.h"
/* Std Lib
------- */
/* Glib
---- */
/* Local
----- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
using namespace std;
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
const int DEFAULT_LINE_LENGTH=8192;
/*----------------------------------------------------------------------
Function Prototypes
------------------- */
/*----------------------------------------------------------------------
Vars
---- */
/*----------------------------------------------------------------------
Data
---- */
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
ScriptFile::ScriptFile(void)
{
m_isOpen=false;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
ScriptFile::~ScriptFile(void)
{
close();
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void ScriptFile::close(void)
{
if (m_isOpen)
m_inStream.close();
m_isOpen=false;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void ScriptFile::open(char const * fileName)
{
if (m_isOpen)
close();
m_inStream.open(fileName,ios::binary|ios::in);
if (m_inStream)
{
m_fileName=fileName;
}
else
GObject::Error(ERR_FATAL,"unable to open script file %s",fileName);
m_isOpen=true;
m_lineCount=0;
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void ScriptFile::scriptError(void)
{
GObject::Error(ERR_FATAL,"Ill formatted script file %s, line %d",(char const *)m_fileName,m_lineCount);
}
/*----------------------------------------------------------------------
Function: ak
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void ScriptFile::checkIsOpen(void)
{
if (!m_isOpen)
GObject::Error(ERR_FATAL,"file operation needed by ScriptFile but no file is open");
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool ScriptFile::getNextNonBlankLine(char * line,int lineLen)
{
checkIsOpen();
do
{
if (m_inStream.eof())
return(false);
m_inStream.getline(line,lineLen);
int lineLength;
lineLength=strlen(line);
for (int f=0;f<lineLength;f++)
{
if (line[f] == ';')
line[f]=0;
}
if (strlen(line))
line[strlen(line)-1]=0;
m_lineCount++;
// stripTrailingSpace(line);
}
while (!strlen(line));
return(true);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool ScriptFile::nextLineIsCommand(void)
{
checkIsOpen();
bool retVal;
streampos thisPos;
const int lineLength=DEFAULT_LINE_LENGTH;
char line[lineLength];
int oldLineCount;
oldLineCount=m_lineCount;
retVal=false;
thisPos=m_inStream.tellg();
if (getNextNonBlankLine(line,lineLength))
{
stripTrailingSpace(line);
retVal=isCommand(line);
}
m_inStream.seekg(thisPos);
m_lineCount=oldLineCount;
return(retVal);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
GString ScriptFile::peekNextCommand(void)
{
checkIsOpen();
GString retStr;
if (nextLineIsCommand())
{
const int lineLength=DEFAULT_LINE_LENGTH;
char line[lineLength];
int oldLineCount;
streampos thisPos;
oldLineCount=m_lineCount;
thisPos=m_inStream.tellg();
getNextNonBlankLine(line,lineLength);
stripTrailingSpace(line);
retStr=getCommandString(line);
m_inStream.seekg(thisPos);
m_lineCount=oldLineCount;
}
return(retStr);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
void ScriptFile::stripTrailingSpace(char * line)
{
if (strlen(line))
{
bool done=false;
for (int f=strlen(line)-1;f<=0 && !done ;f--)
{
if ((!isspace(line[f])) )
done=true;
else
line[f]=0;
}
}
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
GString ScriptFile::getCommandString(char * com)
{
char * newStr;
newStr=strdup(com);
newStr[strlen(newStr)-1]=0;
GString retStr(&newStr[1]);
free(newStr);
return(retStr);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool ScriptFile::isCommand(char * line)
{
return ((line[0]=='[') && (line[strlen(line)-1]==']'));
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
GString ScriptFile::getNextLine(void)
{
const int lineLength=DEFAULT_LINE_LENGTH;
char line[lineLength];
getNextNonBlankLine(line,lineLength);
return(line);
}
/*----------------------------------------------------------------------
Function:
Purpose:
Params:
Returns:
---------------------------------------------------------------------- */
bool ScriptFile::eof(void)
{
checkIsOpen();
return(m_inStream.eof());
}
/*===========================================================================
end */

View file

@ -0,0 +1,99 @@
/*=========================================================================
FILENAME.CPP
Author: Gary Liddon @
Created:
Project:
Purpose:
Copyright (c) 1998 G R Liddon
===========================================================================*/
#pragma warning( disable : 4786 )
#ifndef __SCRIPT_H__
#define __SCRIPT_H__
/*----------------------------------------------------------------------
Includes
-------- */
/* Std Lib
------- */
#include <fstream>
/* Glib
---- */
#include <gstring.hpp>
/* Local
----- */
/*----------------------------------------------------------------------
Tyepdefs && Defines
------------------- */
/*----------------------------------------------------------------------
Structure defintions
-------------------- */
class ScriptFile
{
private:
std::ifstream m_inStream;
bool m_isOpen;
GString m_fileName;
int m_lineCount;
void scriptError(void);
bool getNextNonBlankLine(char * Line,int LineLen);
void stripTrailingSpace(char * Line);
GString getCommandString(char * Com);
bool isCommand(char * Line);
void checkIsOpen(void);
protected:
bool eof(void);
GString peekNextCommand(void);
bool nextLineIsCommand(void);
GString getNextLine(void);
void open(char const * fileName);
void close(void);
int getLineCount(void)
{return(m_lineCount);}
public:
ScriptFile(void);
~ScriptFile(void);
};
/*----------------------------------------------------------------------
Globals
------- */
/* Vars
---- */
/* Data
---- */
/* Functions
--------- */
/*---------------------------------------------------------------------- */
#endif /* __SCRIPT_H__ */
/*===========================================================================
end */