forked from mirrors/0ad
Entities: Removed Tag attribute; it is taken from the filename instead. Made entity XML files be loaded on demand. Probably stopped crash when maps contain non-existent entities. Fixed a few bugs in entity definitions.
Maps: Stored non-entity objects in XML instead of PMP, for easier manual editing. Updated existing maps to newest format, so that they can still work. Added undocumented _rewriteMaps() JS function. Also renamed _mem to vmem, and reclassified its undocumentedness as unintentional, since it's reasonably useful. Loader: added NonprogressiveLoad function, for ScEd/_rewriteMaps/etc which don't care about progressiveness. main.cpp: re-enabled vfs_display, since it doesn't crash now Vector3D: stopped warning This was SVN commit r2078.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "BaseEntity.h"
|
||||
#include "BaseEntityCollection.h"
|
||||
#include "EntityManager.h"
|
||||
#include "CLogger.h"
|
||||
|
||||
#include "Model.h"
|
||||
#include "Terrain.h"
|
||||
@@ -18,6 +19,8 @@
|
||||
#include "Loader.h"
|
||||
#include "LoaderThunks.h"
|
||||
|
||||
#define LOG_CATEGORY "graphics"
|
||||
|
||||
// CMapReader constructor: nothing to do at the minute
|
||||
CMapReader::CMapReader()
|
||||
{
|
||||
@@ -167,21 +170,25 @@ void CMapReader::ApplyData()
|
||||
for (u32 i=0;i<m_Objects.size();i++) {
|
||||
|
||||
if (unpacker.GetVersion() < 3) {
|
||||
|
||||
// Hijack the standard actor instantiation for actors that correspond to entities.
|
||||
// Not an ideal solution; we'll have to figure out a map format that can define entities separately or somesuch.
|
||||
|
||||
CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor(m_ObjectTypes.at(m_Objects[i].m_ObjectIndex));
|
||||
|
||||
if (templateObject)
|
||||
{
|
||||
CVector3D orient = ((CMatrix3D*)m_Objects[i].m_Transform)->GetIn();
|
||||
CVector3D position = ((CMatrix3D*)m_Objects[i].m_Transform)->GetTranslation();
|
||||
debug_warn("Old unsupported map version - objects will be missing");
|
||||
// (getTemplateByActor doesn't work, since entity templates are now
|
||||
// loaded on demand)
|
||||
|
||||
g_EntityManager.create(templateObject, position, atan2(-orient.X, -orient.Z));
|
||||
|
||||
continue;
|
||||
}
|
||||
// // Hijack the standard actor instantiation for actors that correspond to entities.
|
||||
// // Not an ideal solution; we'll have to figure out a map format that can define entities separately or somesuch.
|
||||
//
|
||||
// CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor(m_ObjectTypes.at(m_Objects[i].m_ObjectIndex));
|
||||
//
|
||||
// if (templateObject)
|
||||
// {
|
||||
// CVector3D orient = ((CMatrix3D*)m_Objects[i].m_Transform)->GetIn();
|
||||
// CVector3D position = ((CMatrix3D*)m_Objects[i].m_Transform)->GetTranslation();
|
||||
//
|
||||
// g_EntityManager.create(templateObject, position, atan2(-orient.X, -orient.Z));
|
||||
//
|
||||
// continue;
|
||||
// }
|
||||
}
|
||||
|
||||
CUnit* unit = g_UnitMan.CreateUnit(m_ObjectTypes.at(m_Objects[i].m_ObjectIndex), NULL);
|
||||
@@ -226,6 +233,9 @@ void CMapReader::ReadXML()
|
||||
EL(player);
|
||||
EL(position);
|
||||
EL(orientation);
|
||||
EL(nonentities);
|
||||
EL(nonentity);
|
||||
EL(actor);
|
||||
AT(x);
|
||||
AT(y);
|
||||
AT(z);
|
||||
@@ -266,28 +276,22 @@ void CMapReader::ReadXML()
|
||||
int element_name = child.getNodeName();
|
||||
|
||||
if (element_name == el_template)
|
||||
{
|
||||
// <template>
|
||||
{ // <template>
|
||||
TemplateName = child.getText();
|
||||
}
|
||||
else if (element_name == el_player)
|
||||
{
|
||||
// <player>
|
||||
{ // <player>
|
||||
PlayerID = CStr(child.getText()).ToInt();
|
||||
}
|
||||
else if (element_name == el_position)
|
||||
{
|
||||
// <position>
|
||||
{ // <position>
|
||||
XMBAttributeList attrs = child.getAttributes();
|
||||
Position = CVector3D(
|
||||
CStr(attrs.getNamedItem(at_x)).ToFloat(),
|
||||
CStr(attrs.getNamedItem(at_y)).ToFloat(),
|
||||
CStr(attrs.getNamedItem(at_z)).ToFloat()
|
||||
);
|
||||
Position = CVector3D(CStr(attrs.getNamedItem(at_x)).ToFloat(),
|
||||
CStr(attrs.getNamedItem(at_y)).ToFloat(),
|
||||
CStr(attrs.getNamedItem(at_z)).ToFloat());
|
||||
}
|
||||
else if (element_name == el_orientation)
|
||||
{
|
||||
// <orientation>
|
||||
{ // <orientation>
|
||||
XMBAttributeList attrs = child.getAttributes();
|
||||
Orientation = CStr(attrs.getNamedItem(at_angle)).ToFloat();
|
||||
}
|
||||
@@ -296,8 +300,67 @@ void CMapReader::ReadXML()
|
||||
}
|
||||
|
||||
HEntity ent = g_EntityManager.create(g_EntityTemplateCollection.getTemplate(TemplateName), Position, Orientation);
|
||||
if (! ent)
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to create entity '%ls'", TemplateName.c_str());
|
||||
else
|
||||
ent->SetPlayer(g_Game->GetPlayer(PlayerID));
|
||||
}
|
||||
}
|
||||
else if (child.getNodeName() == el_nonentities)
|
||||
{
|
||||
// <nonentities>
|
||||
|
||||
ent->SetPlayer(g_Game->GetPlayer(PlayerID));
|
||||
XMBElementList children = child.getChildNodes();
|
||||
for (int i = 0; i < children.Count; ++i)
|
||||
{
|
||||
XMBElement child = children.item(i);
|
||||
assert(child.getNodeName() == el_nonentity);
|
||||
|
||||
// <nonentity>
|
||||
|
||||
CStr ActorName;
|
||||
CVector3D Position;
|
||||
float Orientation;
|
||||
|
||||
XMBElementList children = child.getChildNodes();
|
||||
for (int i = 0; i < children.Count; ++i)
|
||||
{
|
||||
XMBElement child = children.item(i);
|
||||
int element_name = child.getNodeName();
|
||||
|
||||
if (element_name == el_actor)
|
||||
{ // <actor>
|
||||
ActorName = child.getText();
|
||||
}
|
||||
else if (element_name == el_position)
|
||||
{ // <position>
|
||||
XMBAttributeList attrs = child.getAttributes();
|
||||
Position = CVector3D(CStr(attrs.getNamedItem(at_x)).ToFloat(),
|
||||
CStr(attrs.getNamedItem(at_y)).ToFloat(),
|
||||
CStr(attrs.getNamedItem(at_z)).ToFloat());
|
||||
}
|
||||
else if (element_name == el_orientation)
|
||||
{ // <orientation>
|
||||
XMBAttributeList attrs = child.getAttributes();
|
||||
Orientation = CStr(attrs.getNamedItem(at_angle)).ToFloat();
|
||||
}
|
||||
else
|
||||
debug_warn("Invalid XML data - DTD shouldn't allow this");
|
||||
}
|
||||
|
||||
CUnit* unit = g_UnitMan.CreateUnit(ActorName, NULL);
|
||||
if (unit && unit->GetModel())
|
||||
{
|
||||
// Copied from CEntity::updateActorTransforms():
|
||||
float s = sin( Orientation );
|
||||
float c = cos( Orientation );
|
||||
CMatrix3D m;
|
||||
m._11 = -c; m._12 = 0.0f; m._13 = -s; m._14 = Position.X;
|
||||
m._21 = 0.0f; m._22 = 1.0f; m._23 = 0.0f; m._24 = Position.Y;
|
||||
m._31 = s; m._32 = 0.0f; m._33 = -c; m._34 = Position.Z;
|
||||
m._41 = 0.0f; m._42 = 0.0f; m._43 = 0.0f; m._44 = 1.0f;
|
||||
unit->GetModel()->SetTransform(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "lib/types.h"
|
||||
#include "MapWriter.h"
|
||||
#include "MapReader.h"
|
||||
#include "UnitManager.h"
|
||||
#include "Unit.h"
|
||||
#include "ObjectManager.h"
|
||||
@@ -10,6 +11,8 @@
|
||||
#include "Terrain.h"
|
||||
#include "LightEnv.h"
|
||||
#include "TextureManager.h"
|
||||
#include "VFSUtil.h"
|
||||
#include "Loader.h"
|
||||
|
||||
#include "ps/XMLWriter.h"
|
||||
#include "lib/res/vfs.h"
|
||||
@@ -54,20 +57,6 @@ static u16 GetHandleIndex(const Handle handle,const std::vector<Handle>& handles
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GetObjectIndex: return the index of the given object in the given list; or 0xffff if
|
||||
// object isn't in list
|
||||
static u16 GetObjectIndex(const CObjectEntry* object,const std::vector<CObjectEntry*>& objects)
|
||||
{
|
||||
for (uint i=0;i<(uint)objects.size();i++) {
|
||||
if (objects[i]==object) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// EnumTerrainTextures: build lists of textures used by map, and tile descriptions for
|
||||
// each tile on the terrain
|
||||
@@ -118,48 +107,6 @@ void CMapWriter::EnumTerrainTextures(CTerrain *pTerrain,
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// EnumObjects: build lists of object types used by map, and object descriptions for
|
||||
// each object in the world
|
||||
void CMapWriter::EnumObjects(CUnitManager *pUnitMan,
|
||||
std::vector<CStr>& objectTypes, std::vector<SObjectDesc>& objects)
|
||||
{
|
||||
// the list of all object entries in use
|
||||
std::vector<CObjectEntry*> objectsInUse;
|
||||
|
||||
// resize object array to required size
|
||||
const std::vector<CUnit*>& units=pUnitMan->GetUnits();
|
||||
objects.clear();
|
||||
objects.reserve(units.size()); // slightly larger than necessary (if there are some entities)
|
||||
|
||||
// now iterate through all the units
|
||||
for (size_t j=0;j<units.size();j++) {
|
||||
|
||||
CUnit* unit=units[j];
|
||||
|
||||
// Ignore entities, since they're outputted to XML instead
|
||||
if (unit->GetEntity())
|
||||
continue;
|
||||
|
||||
u16 index=u16(GetObjectIndex(unit->GetObject(),objectsInUse));
|
||||
if (index==0xffff) {
|
||||
index=(u16)objectsInUse.size();
|
||||
objectsInUse.push_back(unit->GetObject());
|
||||
}
|
||||
|
||||
SObjectDesc obj;
|
||||
obj.m_ObjectIndex=index;
|
||||
memcpy(obj.m_Transform,&unit->GetModel()->GetTransform()._11,sizeof(float)*16);
|
||||
|
||||
objects.push_back(obj);
|
||||
}
|
||||
|
||||
// now build outgoing objectTypes array
|
||||
for (uint i=0;i<(uint)objectsInUse.size();i++) {
|
||||
objectTypes.push_back(objectsInUse[i]->m_Base->m_Name);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PackMap: pack the current world into a raw data stream
|
||||
void CMapWriter::PackMap(CFilePacker& packer, CTerrain *pTerrain, CLightEnv *pLightEnv, CUnitManager *pUnitMan)
|
||||
@@ -186,25 +133,10 @@ void CMapWriter::PackLightEnv(CFilePacker& packer, CLightEnv *pLightEnv)
|
||||
// - data: list of objects types used by map, list of object descriptions
|
||||
void CMapWriter::PackObjects(CFilePacker& packer, CUnitManager *pUnitMan)
|
||||
{
|
||||
// the list of object types used by map
|
||||
std::vector<CStr> objectTypes;
|
||||
// descriptions of each object
|
||||
std::vector<SObjectDesc> objects;
|
||||
|
||||
// build lists by scanning through the world
|
||||
EnumObjects(pUnitMan, objectTypes, objects);
|
||||
|
||||
// pack object types
|
||||
u32 numObjTypes=(u32)objectTypes.size();
|
||||
packer.PackRaw(&numObjTypes,sizeof(numObjTypes));
|
||||
for (uint i=0;i<numObjTypes;i++) {
|
||||
packer.PackString(objectTypes[i]);
|
||||
}
|
||||
|
||||
// pack object data
|
||||
u32 numObjects=(u32)objects.size();
|
||||
packer.PackRaw(&numObjects,sizeof(numObjects));
|
||||
packer.PackRaw(&objects[0],sizeof(SObjectDesc)*numObjects);
|
||||
// (These are now handled by XML, so this function is fairly uninteresting)
|
||||
u32 zero = 0;
|
||||
packer.PackRaw(&zero,sizeof(zero)); // numObjTypes
|
||||
packer.PackRaw(&zero,sizeof(zero)); // numObjects
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -294,6 +226,38 @@ void CMapWriter::WriteXML(const char* filename, CUnitManager* pUnitMan)
|
||||
{
|
||||
float angle = entity->m_orientation;
|
||||
|
||||
XML_Element("Orientation");
|
||||
XML_Attribute("angle", angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
XML_Element("Nonentities");
|
||||
|
||||
const std::vector<CUnit*>& units = pUnitMan->GetUnits();
|
||||
for (std::vector<CUnit*>::const_iterator unit = units.begin(); unit != units.end(); ++unit) {
|
||||
|
||||
// Ignore objects that are entities
|
||||
if ((*unit)->GetEntity())
|
||||
continue;
|
||||
|
||||
XML_Element("Nonentity");
|
||||
|
||||
XML_Setting("Actor", (*unit)->GetObject()->m_Base->m_Name);
|
||||
|
||||
{
|
||||
CVector3D position = (*unit)->GetModel()->GetTransform().GetTranslation();
|
||||
|
||||
XML_Element("Position");
|
||||
XML_Attribute("x", position.X);
|
||||
XML_Attribute("y", position.Y);
|
||||
XML_Attribute("z", position.Z);
|
||||
}
|
||||
|
||||
{
|
||||
CVector3D orient = (*unit)->GetModel()->GetTransform().GetIn();
|
||||
float angle = atan2(-orient.X, -orient.Z);
|
||||
|
||||
XML_Element("Orientation");
|
||||
XML_Attribute("angle", angle);
|
||||
}
|
||||
@@ -314,3 +278,25 @@ void CMapWriter::WriteXML(const char* filename, CUnitManager* pUnitMan)
|
||||
vfs_close(h);
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RewriteAllMaps
|
||||
void CMapWriter::RewriteAllMaps(CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv)
|
||||
{
|
||||
VFSUtil::FileList files;
|
||||
VFSUtil::FindFiles("maps/scenarios", "*.pmp", files);
|
||||
|
||||
for (VFSUtil::FileList::iterator it = files.begin(); it != files.end(); ++it)
|
||||
{
|
||||
CMapReader* reader = new CMapReader;
|
||||
LDR_BeginRegistering();
|
||||
reader->LoadMap(*it, pTerrain, pUnitMan, pLightEnv);
|
||||
LDR_EndRegistering();
|
||||
LDR_NonprogressiveLoad();
|
||||
|
||||
CStr n (*it);
|
||||
n.Replace("scenarios/", "scenarios/new/");
|
||||
CMapWriter writer;
|
||||
writer.SaveMap(n, pTerrain, pLightEnv, pUnitMan);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ public:
|
||||
// SaveMap: try to save the current map to the given file
|
||||
void SaveMap(const char* filename, CTerrain *pTerr, CLightEnv *pLightEnv, CUnitManager *pUnitMan);
|
||||
|
||||
// RewriteAllMaps: for use during development: load/save all maps, to
|
||||
// update them to the newest format.
|
||||
static void RewriteAllMaps(CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv);
|
||||
|
||||
private:
|
||||
// PackMap: pack the current world into a raw data stream
|
||||
void PackMap(CFilePacker& packer, CTerrain *pTerr, CLightEnv *pLightEnv, CUnitManager *pUnitMan);
|
||||
@@ -33,11 +37,6 @@ private:
|
||||
void EnumTerrainTextures(CTerrain *pTerrain, std::vector<CStr>& textures,
|
||||
std::vector<STileDesc>& tileIndices);
|
||||
|
||||
// EnumObjects: build lists of object types used by map, and object descriptions for
|
||||
// each object in the world
|
||||
void EnumObjects(CUnitManager *pUnitMan, std::vector<CStr>& objectTypes,
|
||||
std::vector<SObjectDesc>& objects);
|
||||
|
||||
// WriteXML: output some other data (entities, etc) in XML format
|
||||
void WriteXML(const char* filename, CUnitManager* pUnitMan);
|
||||
};
|
||||
|
||||
@@ -17,11 +17,14 @@ bool CObjectBase::Load(const char* filename)
|
||||
{
|
||||
m_Variants.clear();
|
||||
|
||||
CStr filePath ("art/actors/");
|
||||
filePath += filename;
|
||||
|
||||
CXeromyces XeroFile;
|
||||
if (XeroFile.Load(filename) != PSRETURN_OK)
|
||||
if (XeroFile.Load(filePath) != PSRETURN_OK)
|
||||
return false;
|
||||
|
||||
m_FileName = filename;
|
||||
m_Name = filename;
|
||||
|
||||
XMBElement root = XeroFile.getRoot();
|
||||
|
||||
@@ -59,7 +62,7 @@ bool CObjectBase::Load(const char* filename)
|
||||
CStr element_value (child.getText());
|
||||
|
||||
if (element_name == el_name)
|
||||
m_Name = element_value;
|
||||
m_ShortName = element_value;
|
||||
|
||||
else if (element_name == el_modelname)
|
||||
m_Variants.back().back().m_ModelFilename = element_value;
|
||||
@@ -136,7 +139,7 @@ bool CObjectBase::Load(const char* filename)
|
||||
//// New-format actor file ////
|
||||
|
||||
// Use the filename for the model's name
|
||||
m_Name = CStr(filename).AfterLast("/").BeforeLast(".xml");
|
||||
m_ShortName = CStr(filename).AfterLast("/").BeforeLast(".xml");
|
||||
|
||||
// Define all the elements used in the XML file
|
||||
#define EL(x) int el_##x = XeroFile.getElementID(#x)
|
||||
|
||||
@@ -57,8 +57,8 @@ public:
|
||||
// object name
|
||||
CStr m_Name;
|
||||
|
||||
// file name
|
||||
CStr m_FileName;
|
||||
// short human-readable name
|
||||
CStr m_ShortName;
|
||||
|
||||
struct {
|
||||
// automatically flatten terrain when applying object
|
||||
|
||||
@@ -124,7 +124,7 @@ bool CObjectEntry::BuildModel()
|
||||
m_Model->AddProp(proppoint,propmodel);
|
||||
if (oe->m_WalkAnim) propmodel->SetAnimation(oe->m_WalkAnim);
|
||||
} else {
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to build prop model \"%s\" on actor \"%s\"", (const char*)prop.m_ModelName, (const char*)m_Base->m_Name);
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to build prop model \"%s\" on actor \"%s\"", (const char*)prop.m_ModelName, (const char*)m_Base->m_ShortName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -61,14 +61,11 @@ CObjectBase* CObjectManager::FindObjectBase(const char* objectname)
|
||||
|
||||
// Not already loaded, so try to load it:
|
||||
|
||||
for (uint k = 0; k < m_ObjectTypes.size(); k++) {
|
||||
|
||||
CStr filename ("art/actors/");
|
||||
filename += objectname;
|
||||
|
||||
for (uint k = 0; k < m_ObjectTypes.size(); k++)
|
||||
{
|
||||
CObjectBase* obj = new CObjectBase();
|
||||
|
||||
if (obj->Load(filename))
|
||||
if (obj->Load(objectname))
|
||||
{
|
||||
m_ObjectTypes[k].m_ObjectBases[objectname] = obj;
|
||||
return obj;
|
||||
@@ -151,25 +148,6 @@ void CObjectManager::DeleteObject(CObjectEntry* entry)
|
||||
}
|
||||
|
||||
|
||||
void CObjectManager::AddObjectBase(CObjectBase* base)
|
||||
{
|
||||
m_ObjectTypes[0].m_ObjectBases.insert(make_pair(base->m_FileName, base));
|
||||
}
|
||||
|
||||
void CObjectManager::DeleteObjectBase(CObjectBase* base)
|
||||
{
|
||||
std::map<CStr, CObjectBase*>& objects = m_ObjectTypes[0].m_ObjectBases;
|
||||
|
||||
for (std::map<CStr, CObjectBase*>::iterator it = objects.begin(); it != objects.end(); )
|
||||
if (it->second == base)
|
||||
objects.erase(it++);
|
||||
else
|
||||
++it;
|
||||
|
||||
delete base;
|
||||
}
|
||||
|
||||
|
||||
void CObjectManager::LoadObjects()
|
||||
{
|
||||
AddObjectType("");
|
||||
|
||||
@@ -54,8 +54,6 @@ public:
|
||||
void DeleteObject(CObjectEntry* entry);
|
||||
|
||||
CObjectBase* FindObjectBase(const char* objname);
|
||||
void AddObjectBase(CObjectBase* base);
|
||||
void DeleteObjectBase(CObjectBase* base);
|
||||
|
||||
CBaseEntity* m_SelectedEntity;
|
||||
|
||||
|
||||
+1
-1
@@ -1157,7 +1157,7 @@ sle(11340106);
|
||||
if(!g_Quickstart)
|
||||
{
|
||||
WriteSysInfo();
|
||||
// vfs_display();
|
||||
vfs_display();
|
||||
}
|
||||
else
|
||||
// speed up startup by disabling all sound
|
||||
|
||||
@@ -286,7 +286,7 @@ JSBool JSI_Vector3D::divide( JSContext* cx, JSObject* obj, uintN argc, jsval* ar
|
||||
}
|
||||
|
||||
JSObject* vector3d = JS_NewObject( g_ScriptingHost.getContext(), &JSI_Vector3D::JSI_class, NULL, NULL );
|
||||
JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *v * ( 1.0 / f ) ) );
|
||||
JS_SetPrivate( g_ScriptingHost.getContext(), vector3d, new JSI_Vector3D::Vector3D_Info( *v * ( 1.0f / f ) ) );
|
||||
*rval = OBJECT_TO_JSVAL( vector3d );
|
||||
|
||||
return( JS_TRUE );
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
#include "FilePacker.h"
|
||||
|
||||
#include <stdio.h> // VFS_REPLACE: remove
|
||||
#ifdef SCED
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "lib/res/vfs.h"
|
||||
|
||||
@@ -34,12 +36,11 @@ CFilePacker::CFilePacker(u32 version, const char magicstr[4])
|
||||
// Write: write out to file all packed data added so far
|
||||
void CFilePacker::Write(const char* filename)
|
||||
{
|
||||
/*
|
||||
VFS_REPLACE: this is the entire function body
|
||||
#ifndef SCED
|
||||
// write out all data (including header)
|
||||
if(vfs_store(filename, &m_Data[0], m_Data.size()) < 0)
|
||||
if(vfs_store(filename, &m_Data[0], m_Data.size(), FILE_NO_AIO) < 0)
|
||||
throw CFileWriteError();
|
||||
*/
|
||||
#else
|
||||
|
||||
FILE* fp=fopen(filename,"wb");
|
||||
if (!fp) {
|
||||
@@ -54,6 +55,7 @@ VFS_REPLACE: this is the entire function body
|
||||
|
||||
// all done
|
||||
fclose(fp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -273,3 +273,26 @@ done:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// immediately process all queued load requests.
|
||||
// returns 0 on success, something else on failure.
|
||||
int LDR_NonprogressiveLoad()
|
||||
{
|
||||
int progress_percent;
|
||||
wchar_t description[100];
|
||||
int ret;
|
||||
|
||||
while(1)
|
||||
{
|
||||
ret = LDR_ProgressiveLoad(100.f, description, ARRAY_SIZE(description), &progress_percent);
|
||||
|
||||
switch(ret)
|
||||
{
|
||||
case 1: debug_warn("NonprogressiveLoad: No load in progress"); return 0;
|
||||
case 0: return 0; // success
|
||||
case ERR_TIMED_OUT: break; // try again
|
||||
default: CHECK_ERR(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,3 +84,7 @@ extern int LDR_Cancel();
|
||||
// the request is de-queued. that leaves writing into caller's buffer.
|
||||
extern int LDR_ProgressiveLoad(double time_budget, wchar_t* next_description,
|
||||
size_t max_chars, int* progress_percent);
|
||||
|
||||
// immediately process all queued load requests.
|
||||
// returns 0 on success, something else on failure.
|
||||
extern int LDR_NonprogressiveLoad();
|
||||
@@ -10,7 +10,7 @@
|
||||
using namespace VFSUtil;
|
||||
|
||||
// Because I'm lazy, and it saves a few lines of code in other places:
|
||||
bool VFSUtil::FindFiles (CStr& dirname, const char* filter, FileList& files)
|
||||
bool VFSUtil::FindFiles (const CStr& dirname, const char* filter, FileList& files)
|
||||
{
|
||||
files.clear();
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ typedef std::vector<CStr> FileList;
|
||||
// 'filter': see vfs_next_dirent
|
||||
// 'files' is initially cleared, and undefined on failure.
|
||||
// On failure, logs an error and returns false.
|
||||
extern bool FindFiles(CStr& dirname, const char* filter, FileList& files);
|
||||
extern bool FindFiles(const CStr& dirname, const char* filter, FileList& files);
|
||||
|
||||
|
||||
// called by EnumFiles for each file in a directory (optionally
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "BaseEntityCollection.h"
|
||||
#include "Scheduler.h"
|
||||
#include "timer.h"
|
||||
#include "LightEnv.h"
|
||||
#include "MapWriter.h"
|
||||
|
||||
#include "Game.h"
|
||||
#include "Network/Server.h"
|
||||
@@ -72,8 +74,9 @@ JSFunctionSpec ScriptFunctionTable[] =
|
||||
{"exit", exitProgram, 0, 0, 0 },
|
||||
{"crash", crash, 0, 0, 0 },
|
||||
{"forceGC", forceGC, 0, 0, 0 },
|
||||
{"_mem", js_mem, 0, 0, 0 }, // Intentionally undocumented
|
||||
{0, 0, 0, 0, 0},
|
||||
{"vmem", vmem, 0, 0, 0 },
|
||||
{"_rewriteMaps", _rewriteMaps, 0, 0, 0 },
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
enum ScriptGlobalTinyIDs
|
||||
@@ -486,7 +489,7 @@ JSBool crash(JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObject
|
||||
return *(JSBool*) ptr;
|
||||
}
|
||||
|
||||
JSBool js_mem(JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObject), unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* UNUSEDPARAM(rval))
|
||||
JSBool vmem(JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObject), unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* UNUSEDPARAM(rval))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int left, total;
|
||||
@@ -500,3 +503,10 @@ JSBool js_mem(JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObjec
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool _rewriteMaps(JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObject), unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* UNUSEDPARAM(rval))
|
||||
{
|
||||
extern CLightEnv g_LightEnv;
|
||||
CMapWriter::RewriteAllMaps(g_Game->GetWorld()->GetTerrain(), g_Game->GetWorld()->GetUnitManager(), &g_LightEnv);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
@@ -63,8 +63,11 @@ JSFunc exitProgram;
|
||||
// Crashes.
|
||||
JSFunc crash;
|
||||
|
||||
// Tries to print the amount of remaining video memory. (I don't like starting functions with underscores).
|
||||
JSFunc js_mem;
|
||||
// Tries to print the amount of remaining video memory.
|
||||
JSFunc vmem;
|
||||
|
||||
// You don't want to use this
|
||||
JSFunc _rewriteMaps;
|
||||
|
||||
extern JSFunctionSpec ScriptFunctionTable[];
|
||||
extern JSPropertySpec ScriptGlobalTable[];
|
||||
|
||||
@@ -79,12 +79,12 @@ bool CBaseEntity::loadXML( CStr filename )
|
||||
EL(script);
|
||||
EL(footprint);
|
||||
EL(event);
|
||||
AT(tag);
|
||||
AT(parent);
|
||||
AT(radius);
|
||||
AT(width);
|
||||
AT(height);
|
||||
AT(on);
|
||||
AT(file);
|
||||
#undef AT
|
||||
#undef EL
|
||||
|
||||
@@ -98,13 +98,7 @@ bool CBaseEntity::loadXML( CStr filename )
|
||||
|
||||
XMBElementList RootChildren = Root.getChildNodes();
|
||||
|
||||
m_Tag = Root.getAttributes().getNamedItem( at_tag );
|
||||
|
||||
if( !m_Tag.Length() )
|
||||
{
|
||||
LOG( ERROR, LOG_CATEGORY, "CBaseEntity::LoadXML: Tag attribute was not specified in file %s. Load failed.", filename.c_str() );
|
||||
return( false );
|
||||
}
|
||||
m_Tag = CStr(filename).AfterLast("/").BeforeLast(".xml");
|
||||
|
||||
m_Base_Name = Root.getAttributes().getNamedItem( at_parent );
|
||||
|
||||
@@ -116,7 +110,7 @@ bool CBaseEntity::loadXML( CStr filename )
|
||||
|
||||
if( ChildName == el_script )
|
||||
{
|
||||
CStr Include = Child.getAttributes().getNamedItem( XeroFile.getAttributeID( "file" ) );
|
||||
CStr Include = Child.getAttributes().getNamedItem( at_file );
|
||||
|
||||
jsval dy;
|
||||
|
||||
@@ -164,9 +158,9 @@ bool CBaseEntity::loadXML( CStr filename )
|
||||
else if( ChildName == el_event )
|
||||
{
|
||||
// Action...On for consistency with the GUI.
|
||||
CStrW EventName = CStrW( L"on" ) + (CStrW)Child.getAttributes().getNamedItem( at_on );
|
||||
CStrW EventName = L"on" + (CStrW)Child.getAttributes().getNamedItem( at_on );
|
||||
|
||||
CStrW Code = (CStrW)Child.getText();
|
||||
CStrW Code (Child.getText());
|
||||
|
||||
// Does a property with this name already exist?
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
|
||||
void CBaseEntityCollection::LoadFile( const char* path )
|
||||
{
|
||||
CBaseEntity* newTemplate = new CBaseEntity();
|
||||
if( newTemplate->loadXML( path ) )
|
||||
{
|
||||
m_templates.push_back( newTemplate );
|
||||
LOG(NORMAL, LOG_CATEGORY, "CBaseEntityCollection::loadTemplates(): Loaded template \"%s\"", path);
|
||||
}
|
||||
else
|
||||
LOG(ERROR, LOG_CATEGORY, "CBaseEntityCollection::loadTemplates(): Couldn't load template \"%s\"", path);
|
||||
// Build the entity name -> filename mapping. This is done so that
|
||||
// the entity 'x' can be in units/x.xml, structures/x.xml, etc, and
|
||||
// we don't have to search every directory for x.xml.
|
||||
|
||||
// Extract the filename out of the path+name+extension.
|
||||
// Equivalent to /.*\/(.*)\.xml/, but not as pretty.
|
||||
CStrW tag = CStr(path).AfterLast("/").BeforeLast(".xml");
|
||||
m_templateFilenames[tag] = path;
|
||||
}
|
||||
|
||||
static void LoadFileThunk( const char* path, const vfsDirEnt* ent, void* context )
|
||||
@@ -31,75 +31,56 @@ void CBaseEntityCollection::loadTemplates()
|
||||
{
|
||||
// Load all files in entities/ and its subdirectories.
|
||||
THROW_ERR( VFSUtil::EnumDirEnts( "entities/", "*.xml", true, LoadFileThunk, this ) );
|
||||
|
||||
|
||||
// Fix up parent links in the templates.
|
||||
|
||||
std::vector<CBaseEntity*>::iterator it, it_done;
|
||||
std::vector<CBaseEntity*> done;
|
||||
|
||||
// TODO: MT: Circular references check.
|
||||
|
||||
while( done.size() < m_templates.size() )
|
||||
{
|
||||
for( it = m_templates.begin(); it != m_templates.end(); it++ )
|
||||
{
|
||||
if( !( (*it)->m_Base_Name.Length() ) )
|
||||
{
|
||||
done.push_back( *it );
|
||||
continue;
|
||||
}
|
||||
|
||||
CBaseEntity* Base = getTemplate( (*it)->m_Base_Name );
|
||||
if( Base )
|
||||
{
|
||||
// Check whether it's been loaded yet.
|
||||
for( it_done = done.begin(); it_done != done.end(); it_done++ )
|
||||
{
|
||||
if( *it_done == Base )
|
||||
{
|
||||
(*it)->m_base = Base;
|
||||
(*it)->loadBase();
|
||||
Base = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !Base )
|
||||
{
|
||||
// Done
|
||||
done.push_back( *it );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
LOG( WARNING, LOG_CATEGORY, "Parent template %s does not exist in template %s", CStr8( (*it)->m_Base_Name ).c_str(), CStr8( (*it)->m_Tag ).c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBaseEntity* CBaseEntityCollection::getTemplate( CStrW name )
|
||||
{
|
||||
for( u16 t = 0; t < m_templates.size(); t++ )
|
||||
if( m_templates[t]->m_Tag == name ) return( m_templates[t] );
|
||||
// Check whether this template has already been loaded
|
||||
templateMap::iterator it = m_templates.find( name );
|
||||
if( it != m_templates.end() )
|
||||
return( it->second );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
// Find the filename corresponding to this template
|
||||
templateFilenameMap::iterator filename_it = m_templateFilenames.find( name );
|
||||
if( filename_it == m_templateFilenames.end() )
|
||||
return( NULL );
|
||||
|
||||
CBaseEntity* CBaseEntityCollection::getTemplateByActor( CStrW actorName )
|
||||
{
|
||||
for( u16 t = 0; t < m_templates.size(); t++ )
|
||||
if( m_templates[t]->m_actorName == actorName ) return( m_templates[t] );
|
||||
CStr path( filename_it->second );
|
||||
|
||||
return( NULL );
|
||||
// Try to load to the entity
|
||||
CBaseEntity* newTemplate = new CBaseEntity();
|
||||
if( !newTemplate->loadXML( path ) )
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "CBaseEntityCollection::loadTemplates(): Couldn't load template \"%s\"", path.c_str());
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
LOG(NORMAL, LOG_CATEGORY, "CBaseEntityCollection::loadTemplates(): Loaded template \"%s\"", path.c_str());
|
||||
m_templates[name] = newTemplate;
|
||||
|
||||
// Load the entity's parent, if it has one
|
||||
if( newTemplate->m_Base_Name.Length() )
|
||||
{
|
||||
CBaseEntity* base = getTemplate( newTemplate->m_Base_Name );
|
||||
if( base )
|
||||
newTemplate->m_base = base;
|
||||
else
|
||||
LOG( WARNING, LOG_CATEGORY, "Parent template \"%ls\" does not exist in template \"%ls\"", newTemplate->m_Base_Name.c_str(), newTemplate->m_Tag.c_str() );
|
||||
// (The requested entity will still be returned, but with no parent.
|
||||
// Is this a reasonable thing to do?)
|
||||
}
|
||||
|
||||
return newTemplate;
|
||||
}
|
||||
|
||||
void CBaseEntityCollection::getTemplateNames( std::vector<CStrW>& names )
|
||||
{
|
||||
for( u16 t = 0; t < m_templates.size(); t++ )
|
||||
names.push_back( m_templates[t]->m_Tag );
|
||||
for( templateFilenameMap::iterator it = m_templateFilenames.begin(); it != m_templateFilenames.end(); ++it )
|
||||
names.push_back( it->first );
|
||||
}
|
||||
|
||||
#ifdef SCED
|
||||
// TODO: Fix ScEd, so that it works
|
||||
CBaseEntity* CBaseEntityCollection::getTemplateByID( int n )
|
||||
{
|
||||
return m_templates[n];
|
||||
@@ -108,6 +89,6 @@ CBaseEntity* CBaseEntityCollection::getTemplateByID( int n )
|
||||
|
||||
CBaseEntityCollection::~CBaseEntityCollection()
|
||||
{
|
||||
for( u16 t = 0; t < m_templates.size(); t++ )
|
||||
delete( m_templates[t] );
|
||||
for( templateMap::iterator it = m_templates.begin(); it != m_templates.end(); ++it )
|
||||
delete( it->second );
|
||||
}
|
||||
|
||||
@@ -28,13 +28,15 @@
|
||||
|
||||
class CBaseEntityCollection : public Singleton<CBaseEntityCollection>
|
||||
{
|
||||
std::vector<CBaseEntity*> m_templates;
|
||||
typedef std::map<CStrW, CBaseEntity*> templateMap;
|
||||
typedef std::map<CStrW, CStr> templateFilenameMap;
|
||||
templateMap m_templates;
|
||||
templateFilenameMap m_templateFilenames;
|
||||
public:
|
||||
~CBaseEntityCollection();
|
||||
CBaseEntity* getTemplate( CStrW entityType );
|
||||
void loadTemplates();
|
||||
void LoadFile( const char* path );
|
||||
CBaseEntity* getTemplateByActor( CStrW actorName );
|
||||
|
||||
// Create a list of the names of all templates, for display in ScEd's
|
||||
// entity-selection box. (This isn't really very good, since it includes
|
||||
|
||||
@@ -31,6 +31,9 @@ CEntityManager::~CEntityManager()
|
||||
HEntity CEntityManager::create( CBaseEntity* base, CVector3D position, float orientation )
|
||||
{
|
||||
assert( base );
|
||||
if( !base )
|
||||
return( HEntity() );
|
||||
|
||||
while( m_entities[m_nextalloc].m_refcount )
|
||||
m_nextalloc++;
|
||||
m_entities[m_nextalloc].m_entity = new CEntity( base, position, orientation );
|
||||
|
||||
@@ -176,15 +176,7 @@ bool CEditorData::Init()
|
||||
return false;
|
||||
}
|
||||
|
||||
int progress_percent;
|
||||
wchar_t description[100];
|
||||
int ret2;
|
||||
do
|
||||
{
|
||||
ret2 = LDR_ProgressiveLoad(100.f, description, ARRAY_SIZE(description), &progress_percent);
|
||||
assert(ret2 == 0 || ret2 == 1 || ret2 == ERR_TIMED_OUT);
|
||||
}
|
||||
while (ret2 != 0);
|
||||
LDR_NonprogressiveLoad();
|
||||
|
||||
// create the scene - terrain, camera, light environment etc
|
||||
if (!InitScene()) return false;
|
||||
|
||||
@@ -624,17 +624,7 @@ void CMainFrame::OnFileLoadMap()
|
||||
CMapReader* reader = new CMapReader(); // freed by the progressive loader
|
||||
reader->LoadMap(loadname, g_Game->GetWorld()->GetTerrain(), &g_UnitMan, &g_LightEnv);
|
||||
LDR_EndRegistering();
|
||||
|
||||
int progress_percent;
|
||||
wchar_t description[100];
|
||||
int ret;
|
||||
do
|
||||
{
|
||||
ret = LDR_ProgressiveLoad(100.f, description, ARRAY_SIZE(description), &progress_percent);
|
||||
assert(ret == 0 || ret == 1 || ret == ERR_TIMED_OUT);
|
||||
}
|
||||
while (ret != 0);
|
||||
|
||||
LDR_NonprogressiveLoad();
|
||||
|
||||
CStr filetitle=loaddlg.m_ofn.lpstrFileTitle;
|
||||
int index=filetitle.ReverseFind(CStr("."));
|
||||
|
||||
Reference in New Issue
Block a user