Danbias/Code/Game/GameLogic/LevelLoader/LevelParser.cpp

320 lines
7.6 KiB
C++
Raw Normal View History

/////////////////////////////////////
// Created by Pontus Fransson 2013 //
/////////////////////////////////////
#include "LevelParser.h"
2014-01-27 10:14:02 +01:00
#include "Loader.h"
2014-01-27 13:57:18 +01:00
#include "ParseFunctions.h"
2014-01-27 10:14:02 +01:00
2014-01-24 10:01:58 +01:00
using namespace GameLogic;
using namespace ::LevelFileLoader;
using namespace Utility::DynamicMemory;
2014-01-24 10:01:58 +01:00
LevelParser::LevelParser()
{
2014-02-10 16:24:05 +01:00
formatVersion.formatVersionMajor = 3;
formatVersion.formatVersionMinor = 0;
2014-01-24 10:01:58 +01:00
}
LevelParser::~LevelParser()
{
}
std::vector<SmartPointer<ObjectTypeHeader>> LevelParser::Parse(std::wstring filename)
2014-01-24 10:01:58 +01:00
{
int bufferSize = 0;
2014-01-28 16:15:10 +01:00
int counter = 0;
2014-02-12 14:48:58 +01:00
bool loadCgf;
std::vector<SmartPointer<ObjectTypeHeader>> objects;
2014-01-24 10:01:58 +01:00
//Read entire level file.
2014-01-27 10:14:02 +01:00
Loader loader;
2014-01-28 16:15:10 +01:00
char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize);
2014-01-24 10:01:58 +01:00
// Check if file was loaded, else return empty vector
if(!buffer)
{
return std::vector<SmartPointer<ObjectTypeHeader>>();
}
//Read format version
LevelLoaderInternal::FormatVersion levelFormatVersion;
2014-02-04 11:36:10 +01:00
ParseObject(&buffer[counter], &levelFormatVersion, sizeof(levelFormatVersion));
counter += sizeof(levelFormatVersion);
if(this->formatVersion != levelFormatVersion)
{
//Returns an empty vector, because it will most likely fail to read the level format.
return objects;
}
2014-01-24 10:01:58 +01:00
2014-02-04 11:36:10 +01:00
while(counter < bufferSize)
2014-01-24 10:01:58 +01:00
{
2014-02-12 14:48:58 +01:00
loadCgf = true;
2014-01-24 10:01:58 +01:00
//Get typeID
ObjectType typeID;
2014-01-28 16:15:10 +01:00
ParseObject(&buffer[counter], &typeID, sizeof(typeID));
switch((int)typeID)
2014-01-24 10:01:58 +01:00
{
case ObjectType_LevelMetaData:
{
SmartPointer<ObjectTypeHeader> header = new LevelMetaData;
ParseLevelMetaData(&buffer[counter], *(LevelMetaData*)header.Get(), counter);
objects.push_back(header);
break;
}
2014-01-24 10:01:58 +01:00
case ObjectType_SpawnPoint:
{
loadCgf = false;
ObjectHeader* header = new ObjectHeader;
ParseObject(&buffer[counter], *header, counter, loadCgf);
SpawnPointAttributes* spawn = new SpawnPointAttributes;
spawn->typeID = header->typeID;
for(int i = 0; i < 3; i++)
{
spawn->position[i] = header->position[i];
}
delete header;
//objects.push_back(header);
objects.push_back(spawn);
break;
}
//This is by design, static and dynamic is using the same converter. Do not add anything inbetween them.
//Unless they are changed to not be the same.
case ObjectType_Static: case ObjectType_Dynamic:
{
//Get specialType.
ObjectSpecialType specialType;
ParseObject(&buffer[counter+4], &specialType, sizeof(typeID));
switch(specialType)
{
2014-02-12 14:48:58 +01:00
//there is no difference when parsing these specialTypes.
case ObjectSpecialType_CrystalShard:
case ObjectSpecialType_CrystalFormation:
case ObjectSpecialType_Spike:
case ObjectSpecialType_SpikeBox:
case ObjectSpecialType_RedExplosiveBox:
case ObjectSpecialType_StandardBox:
2014-02-12 14:48:58 +01:00
case ObjectSpecialType_Stone:
case ObjectSpecialType_Building:
{
ObjectHeader* header = new ObjectHeader;
2014-02-12 14:48:58 +01:00
ParseObject(&buffer[counter], *header, counter, loadCgf);
objects.push_back(header);
break;
}
2014-02-12 14:48:58 +01:00
case ObjectSpecialType_JumpPad:
{
JumpPadAttributes* header = new JumpPadAttributes;
2014-02-12 14:48:58 +01:00
ParseObject(&buffer[counter], *header, counter, loadCgf);
//Read the spec
ParseObject(&buffer[counter], header->direction, 16);
2014-02-12 14:48:58 +01:00
counter += 16;
objects.push_back(header);
break;
}
2014-02-12 14:48:58 +01:00
case ObjectSpecialType_Portal:
{
PortalAttributes* header = new PortalAttributes;
2014-02-12 14:48:58 +01:00
ParseObject(&buffer[counter], *header, counter, loadCgf);
ParseObject(&buffer[counter], header->destination, 12);
2014-02-12 14:48:58 +01:00
counter += 12;
objects.push_back(header);
break;
}
2014-02-10 16:24:05 +01:00
case ObjectSpecialType_World:
{
2014-02-10 16:24:05 +01:00
WorldAttributes* header = new WorldAttributes;
2014-02-12 14:48:58 +01:00
ParseObject(&buffer[counter], *header, counter, loadCgf);
2014-02-10 16:24:05 +01:00
ParseObject(&buffer[counter], &header->worldSize, 8);
2014-02-12 14:48:58 +01:00
counter += 8;
objects.push_back(header);
break;
}
2014-02-10 16:24:05 +01:00
case ObjectSpecialType_Sky:
{
2014-02-12 14:48:58 +01:00
loadCgf = false;
2014-02-10 16:24:05 +01:00
SkyAttributes* header = new SkyAttributes;
2014-02-12 14:48:58 +01:00
ParseObject(&buffer[counter], *header, counter, loadCgf);
2014-02-10 16:24:05 +01:00
ParseObject(&buffer[counter], &header->skySize, 4);
2014-02-12 14:48:58 +01:00
counter += 4;
2014-02-10 16:24:05 +01:00
objects.push_back(header);
break;
}
2014-02-12 14:48:58 +01:00
default:
//Couldn't find specialType
break;
}
break;
}
2014-01-28 16:15:10 +01:00
case ObjectType_Light:
{
LightType lightType;
//Get Light type
ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
//We only support PointLight for now.
BasicLight* header = new BasicLight;
ParseObject(&buffer[counter], header, sizeof(*header));
counter += sizeof(*header);
objects.push_back(header);
/*switch(lightType)
{
case LightType_PointLight:
{
PointLight* header = new PointLight;
ParseObject(&buffer[counter], header, sizeof(*header));
counter += sizeof(*header);
objects.push_back(header);
break;
}
case LightType_DirectionalLight:
{
DirectionalLight* header = new DirectionalLight;
ParseObject(&buffer[counter], header, sizeof(*header));
counter += sizeof(*header);
objects.push_back(header);
break;
}
case LightType_SpotLight:
{
SpotLight* header = new SpotLight;
ParseObject(&buffer[counter], header, sizeof(*header));
counter += sizeof(*header);
objects.push_back(header);
break;
}
default:
//Undefined LightType.
break;
}
break;*/
}
default:
//Couldn't find typeID. FAIL!!!!!!
break;
2014-01-24 10:01:58 +01:00
}
}
return objects;
}
//f<>r meta information om leveln.
LevelMetaData LevelParser::ParseHeader(std::wstring filename)
2014-01-24 10:01:58 +01:00
{
int bufferSize = 0;
2014-01-28 16:15:10 +01:00
int counter = 0;
LevelMetaData levelHeader;
levelHeader.typeID = ObjectType::ObjectType_Unknown;
2014-01-24 10:01:58 +01:00
//Read entire level file.
2014-01-27 10:14:02 +01:00
Loader loader;
2014-01-28 16:15:10 +01:00
char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize);
2014-01-24 10:01:58 +01:00
//Read format version
LevelLoaderInternal::FormatVersion levelFormatVersion;
2014-02-04 11:36:10 +01:00
ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion));
counter += sizeof(levelFormatVersion);
if(this->formatVersion != levelFormatVersion)
{
//Do something if it's not the same version
//Returns an empty levelHeader with ObjectType_Unknown.
//Because it will not be able to read another version of the level format.
return levelHeader;
}
2014-01-24 10:01:58 +01:00
//Find the header in the returned string.
while(counter < bufferSize)
2014-01-24 10:01:58 +01:00
{
ObjectType typeID;
2014-01-28 16:15:10 +01:00
ParseObject(&buffer[counter], &typeID, sizeof(typeID));
switch(typeID)
2014-01-24 10:01:58 +01:00
{
case ObjectType_LevelMetaData:
2014-01-28 16:15:10 +01:00
ParseLevelMetaData(&buffer[counter], levelHeader, counter);
return levelHeader;
2014-01-24 10:01:58 +01:00
break;
2014-02-04 11:36:10 +01:00
//This is by design, static and dynamic is using the same converter. Do not add anything inbetween them.
case ObjectType_Static: case ObjectType_Dynamic:
{
ObjectHeader header;
2014-02-12 14:48:58 +01:00
ParseObject(&buffer[counter], &header, counter);
switch(header.specialTypeID)
{
case ObjectSpecialType_JumpPad:
counter += sizeof(16);
break;
case ObjectSpecialType_Portal:
counter += sizeof(12);
break;
default:
break;
}
2014-01-24 10:01:58 +01:00
break;
2014-02-04 11:36:10 +01:00
}
case ObjectType_Light:
{
LightType lightType;
ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
//We only support pointlight for now.
counter += sizeof(BasicLight);
/*
2014-02-04 11:36:10 +01:00
switch(lightType)
{
case LightType_PointLight:
{
counter += sizeof(PointLight);
break;
}
case LightType_DirectionalLight:
{
counter += sizeof(DirectionalLight);
break;
}
case LightType_SpotLight:
{
counter += sizeof(SpotLight);
break;
}
default:
//Undefined LightType.
break;
}*/
2014-02-04 11:36:10 +01:00
}
2014-01-24 10:01:58 +01:00
default:
//Couldn't find typeID. FAIL!!!!!!
break;
}
}
return levelHeader;
2014-01-24 10:01:58 +01:00
}