initial
This commit is contained in:
118
dmserializers/_vpc_/manifest_dmserializers/win32/manifest.txt
Normal file
118
dmserializers/_vpc_/manifest_dmserializers/win32/manifest.txt
Normal file
@@ -0,0 +1,118 @@
|
||||
// ----------------------------------------- //
|
||||
// File generated by VPC //
|
||||
// ----------------------------------------- //
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\dmebaseimporter.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\dmebaseimporter.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\dmebaseimporter.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\dmserializers.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\dmserializers.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\dmserializers.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importactbusy.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importactbusy.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importactbusy.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importcommentary.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importcommentary.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importcommentary.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importkeyvaluebase.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importkeyvaluebase.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importkeyvaluebase.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importmks.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importmks.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importmks.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv1.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv1.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv1.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv2.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv2.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv2.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv3.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv3.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv3.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv4.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv4.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv4.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv5.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv5.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv5.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv6.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv6.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv6.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv7.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv7.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv7.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv8.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv8.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv8.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv9.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv9.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importsfmv9.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importtex.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importtex.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importtex.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importvmf.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importvmf.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importvmf.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
Source file: F:\csgo_64\cstrike15_src\dmserializers\importvmt.cpp
|
||||
Debug output file: F:\csgo_64\cstrike15_src\dmserializers\importvmt.cpp
|
||||
Release output file: F:\csgo_64\cstrike15_src\dmserializers\importvmt.cpp
|
||||
Containing unity file:
|
||||
PCH file:
|
||||
|
||||
42
dmserializers/dmebaseimporter.cpp
Normal file
42
dmserializers/dmebaseimporter.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
|
||||
CDmeBaseImporter::CDmeBaseImporter( char const *formatName, char const *nextFormatName ) :
|
||||
m_pFormatName( formatName ),
|
||||
m_pNextSerializer( nextFormatName )
|
||||
{
|
||||
}
|
||||
|
||||
bool CDmeBaseImporter::IsLatestVersion() const
|
||||
{
|
||||
return g_pDataModel->FindLegacyUpdater( m_pNextSerializer ) == NULL;
|
||||
}
|
||||
|
||||
// Updates ppRoot to first non-legacy generic dmx format, returns false if the conversion fails
|
||||
bool CDmeBaseImporter::Update( CDmElement **ppRoot )
|
||||
{
|
||||
if ( !DoFixup( *ppRoot ) )
|
||||
return false;
|
||||
|
||||
if ( !m_pNextSerializer )
|
||||
return true;
|
||||
|
||||
// Chain
|
||||
IDmLegacyUpdater *pUpdater = g_pDataModel->FindLegacyUpdater( m_pNextSerializer );
|
||||
if ( !pUpdater )
|
||||
return true;
|
||||
|
||||
return pUpdater->Update( ppRoot );
|
||||
}
|
||||
|
||||
|
||||
|
||||
CSFMBaseImporter::CSFMBaseImporter( char const *formatName, char const *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
}
|
||||
43
dmserializers/dmebaseimporter.h
Normal file
43
dmserializers/dmebaseimporter.h
Normal file
@@ -0,0 +1,43 @@
|
||||
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DMEBASEIMPORTER_H
|
||||
#define DMEBASEIMPORTER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "datamodel/idatamodel.h"
|
||||
|
||||
class CDmeBaseImporter : public IDmLegacyUpdater
|
||||
{
|
||||
typedef IDmLegacyUpdater BaseClass;
|
||||
|
||||
public:
|
||||
CDmeBaseImporter( char const *formatName, char const *nextFormatName );
|
||||
|
||||
virtual const char *GetName() const { return m_pFormatName; }
|
||||
virtual bool IsLatestVersion() const;
|
||||
|
||||
virtual bool Update( CDmElement **ppRoot );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pRoot ) = 0;
|
||||
|
||||
protected:
|
||||
char const *m_pFormatName;
|
||||
char const *m_pNextSerializer;
|
||||
};
|
||||
|
||||
class CSFMBaseImporter : public CDmeBaseImporter
|
||||
{
|
||||
typedef CDmeBaseImporter BaseClass;
|
||||
|
||||
public:
|
||||
CSFMBaseImporter( char const *formatName, char const *nextFormatName );
|
||||
};
|
||||
|
||||
#endif // DMEBASEIMPORTER_H
|
||||
3107
dmserializers/dmserializers.cpp
Normal file
3107
dmserializers/dmserializers.cpp
Normal file
File diff suppressed because it is too large
Load Diff
58
dmserializers/dmserializers.h
Normal file
58
dmserializers/dmserializers.h
Normal file
@@ -0,0 +1,58 @@
|
||||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
|
||||
//
|
||||
// The copyright to the contents herein is the property of Valve, L.L.C.
|
||||
// The contents may be used and/or copied only with the written permission of
|
||||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
||||
// the agreement/contract under which the contents have been supplied.
|
||||
//
|
||||
// $Header: $
|
||||
// $NoKeywords: $
|
||||
//
|
||||
// Main header file for the serializers DLL
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef DMSERIALIZERS_H
|
||||
#define DMSERIALIZERS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class IDataModel;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Externally defined importers
|
||||
//-----------------------------------------------------------------------------
|
||||
void InstallActBusyImporter( IDataModel *pFactory );
|
||||
void InstallCommentaryImporter( IDataModel *pFactory );
|
||||
void InstallVMTImporter( IDataModel *pFactory );
|
||||
void InstallSFMV1Importer( IDataModel *pFactory );
|
||||
void InstallSFMV2Importer( IDataModel *pFactory );
|
||||
void InstallSFMV3Importer( IDataModel *pFactory );
|
||||
void InstallSFMV4Importer( IDataModel *pFactory );
|
||||
void InstallSFMV5Importer( IDataModel *pFactory );
|
||||
void InstallSFMV6Importer( IDataModel *pFactory );
|
||||
void InstallSFMV7Importer( IDataModel *pFactory );
|
||||
void InstallSFMV8Importer( IDataModel *pFactory );
|
||||
void InstallSFMV9Importer( IDataModel *pFactory );
|
||||
void InstallVMFImporter( IDataModel *pFactory );
|
||||
void InstallMKSImporter( IDataModel *pFactory );
|
||||
void InstallTEXImporter( IDataModel *pFactory );
|
||||
|
||||
void InstallDMXUpdater( IDataModel *pFactory );
|
||||
void InstallSFMSessionUpdater( IDataModel *pFactory );
|
||||
void InstallPCFUpdater( IDataModel *pFactory );
|
||||
|
||||
|
||||
#endif // DMSERIALIZERS_H
|
||||
|
||||
|
||||
49
dmserializers/dmserializers.vpc
Normal file
49
dmserializers/dmserializers.vpc
Normal file
@@ -0,0 +1,49 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// DMSERIALIZERS.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR ".."
|
||||
$Include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$PreprocessorDefinitions "$BASE;DMSERIALIZERS_LIB"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "Dmserializers"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "dmebaseimporter.cpp"
|
||||
$File "dmserializers.cpp"
|
||||
$File "importactbusy.cpp"
|
||||
$File "importcommentary.cpp"
|
||||
$File "importkeyvaluebase.cpp"
|
||||
$File "importmks.cpp"
|
||||
$File "importsfmv1.cpp"
|
||||
$File "importsfmv2.cpp"
|
||||
$File "importsfmv3.cpp"
|
||||
$File "importsfmv4.cpp"
|
||||
$File "importsfmv5.cpp"
|
||||
$File "importsfmv6.cpp"
|
||||
$File "importsfmv7.cpp"
|
||||
$File "importsfmv8.cpp"
|
||||
$File "importsfmv9.cpp"
|
||||
$File "importtex.cpp"
|
||||
$File "importvmf.cpp"
|
||||
$File "importvmt.cpp"
|
||||
}
|
||||
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$File "dmebaseimporter.h"
|
||||
$File "dmserializers.h"
|
||||
$File "$SRCDIR\public\dmserializers\idmserializers.h"
|
||||
$File "importkeyvaluebase.h"
|
||||
}
|
||||
}
|
||||
13
dmserializers/dmserializers.vpc.vpc_cache
Normal file
13
dmserializers/dmserializers.vpc.vpc_cache
Normal file
@@ -0,0 +1,13 @@
|
||||
"vpc_cache"
|
||||
{
|
||||
"CacheVersion" "1"
|
||||
"win32"
|
||||
{
|
||||
"CRCFile" "dmserializers.vcxproj.vpc_crc"
|
||||
"OutputFiles"
|
||||
{
|
||||
"0" "dmserializers.vcxproj"
|
||||
"1" "dmserializers.vcxproj.filters"
|
||||
}
|
||||
}
|
||||
}
|
||||
185
dmserializers/importactbusy.cpp
Normal file
185
dmserializers/importactbusy.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "importkeyvaluebase.h"
|
||||
#include "dmserializers.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/UtlBuffer.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Serialization class for Key Values
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportActBusy : public CImportKeyValueBase
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const { return "actbusy"; }
|
||||
virtual const char *GetDescription() const { return "ActBusy Script File"; }
|
||||
virtual int GetCurrentVersion() const { return 0; } // doesn't store a version
|
||||
virtual const char *GetImportedFormat() const { return "actbusy"; }
|
||||
virtual int GetImportedVersion() const { return 1; }
|
||||
|
||||
bool Serialize( CUtlBuffer &outBuf, CDmElement *pRoot );
|
||||
CDmElement* UnserializeFromKeyValues( KeyValues *pKeyValues );
|
||||
|
||||
private:
|
||||
// Reads a single element
|
||||
bool UnserializeActBusyKey( CDmAttribute *pChildren, KeyValues *pKeyValues );
|
||||
|
||||
// Writes out the actbusy header
|
||||
void SerializeHeader( CUtlBuffer &buf );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportActBusy s_ImportActBusy;
|
||||
|
||||
void InstallActBusyImporter( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddSerializer( &s_ImportActBusy );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out the actbusy header
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportActBusy::SerializeHeader( CUtlBuffer &buf )
|
||||
{
|
||||
buf.Printf( "// \"act busy name\"\t\tThis is the name that a mapmaker must specify in the hint node.\n" );
|
||||
buf.Printf( "// {\n" );
|
||||
buf.Printf( "// \t\"busy_anim\"\t\t\t\"Activity Name\".\n" );
|
||||
buf.Printf( "// \t\"entry_anim\"\t\t\"Activity Name\"\n" );
|
||||
buf.Printf( "// \t\"exit_anim\"\t\t\t\"Activity Name\"\n" );
|
||||
buf.Printf( "// \t\"busy_sequence\"\t\t\"Sequence Name\". If specified, this is used over the activity name. Specify it in the hint node.\n" );
|
||||
buf.Printf( "// \t\"entry_sequence\"\t\"Sequence Name\". If specified, this is used over the entry anim.\n" );
|
||||
buf.Printf( "// \t\"exit_sequence\"\t\t\"Sequence Name\". If specified, this is used over the exit anim.\n" );
|
||||
buf.Printf( "// \t\"min_time\"\t\t\t\"Minimum time to spend in this busy anim\"\n" );
|
||||
buf.Printf( "// \t\"max_time\"\t\t\t\"Maximum time to spend in this busy anim\" 0 = only stop when interrupted by external event\n" );
|
||||
buf.Printf( "// \t\"interrupts\"\t\tOne of:\n" );
|
||||
buf.Printf( "// \t\t\t\t\t\t\"BA_INT_NONE\"\t\tbreak out only when time runs out. No external influence will break me out.\n" );
|
||||
buf.Printf( "// \t\t\t\t\t\t\"BA_INT_DANGER\"\t\tbreak out of this anim only if threatened\n" );
|
||||
buf.Printf( "// \t\t\t\t\t\t\"BA_INT_PLAYER\"\t\tbreak out of this anim if I can see the player, or I'm threatened\n" );
|
||||
buf.Printf( "// \t\t\t\t\t\t\"BA_INT_AMBUSH\"\t\tsomeone please define this - I have no idea what it does\n" );
|
||||
buf.Printf( "// \t\t\t\t\t\t\"BA_INT_COMBAT\"\t\tbreak out of this anim if combat occurs in my line of sight (bullet hits, grenades, etc), -OR- the max time is reached\n" );
|
||||
buf.Printf( "// }\n" );
|
||||
buf.Printf( "//\n" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out a new actbusy file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportActBusy::Serialize( CUtlBuffer &buf, CDmElement *pRoot )
|
||||
{
|
||||
SerializeHeader( buf );
|
||||
buf.Printf( "\"ActBusy.txt\"\n" );
|
||||
buf.Printf( "{\n" );
|
||||
|
||||
CDmAttribute *pChildren = pRoot->GetAttribute( "children" );
|
||||
if ( !pChildren || pChildren->GetType() != AT_ELEMENT_ARRAY )
|
||||
return NULL;
|
||||
|
||||
CDmrElementArray<> children( pChildren );
|
||||
int nCount = children.Count();
|
||||
|
||||
buf.PushTab();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = children[i];
|
||||
buf.Printf( "\"%s\"\n", pChild->GetName() );
|
||||
buf.Printf( "{\n" );
|
||||
|
||||
buf.PushTab();
|
||||
PrintStringAttribute( pChild, buf, "busy_anim", true );
|
||||
PrintStringAttribute( pChild, buf, "entry_anim", true );
|
||||
PrintStringAttribute( pChild, buf, "exit_anim", true );
|
||||
PrintStringAttribute( pChild, buf, "busy_sequence", true );
|
||||
PrintStringAttribute( pChild, buf, "entry_sequence", true );
|
||||
PrintStringAttribute( pChild, buf, "exit_sequence", true );
|
||||
PrintFloatAttribute( pChild, buf, "min_time" );
|
||||
PrintFloatAttribute( pChild, buf, "max_time" );
|
||||
PrintStringAttribute( pChild, buf, "interrupts" );
|
||||
buf.PopTab();
|
||||
|
||||
buf.Printf( "}\n" );
|
||||
}
|
||||
buf.PopTab();
|
||||
|
||||
buf.Printf( "}\n" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads a single element
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportActBusy::UnserializeActBusyKey( CDmAttribute *pChildren, KeyValues *pKeyValues )
|
||||
{
|
||||
CDmElement *pActBusy = CreateDmElement( "DmElement", pKeyValues->GetName(), NULL );
|
||||
if ( !pActBusy )
|
||||
return false;
|
||||
|
||||
// Each act busy needs to have an editortype associated with it so it displays nicely in editors
|
||||
pActBusy->SetValue( "editorType", "actBusy" );
|
||||
|
||||
float flZero = 0.0f;
|
||||
AddStringAttribute( pActBusy, pKeyValues, "busy_anim", "" );
|
||||
AddStringAttribute( pActBusy, pKeyValues, "entry_anim", "" );
|
||||
AddStringAttribute( pActBusy, pKeyValues, "exit_anim", "" );
|
||||
AddStringAttribute( pActBusy, pKeyValues, "busy_sequence", "" );
|
||||
AddStringAttribute( pActBusy, pKeyValues, "entry_sequence", "" );
|
||||
AddStringAttribute( pActBusy, pKeyValues, "exit_sequence", "" );
|
||||
AddFloatAttribute( pActBusy, pKeyValues, "min_time", &flZero );
|
||||
AddFloatAttribute( pActBusy, pKeyValues, "max_time", &flZero );
|
||||
AddStringAttribute( pActBusy, pKeyValues, "interrupts", "BA_INT_NONE" );
|
||||
|
||||
CDmrElementArray<> children( pChildren );
|
||||
children.AddToTail( pActBusy );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main entry point for the unserialization
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement* CImportActBusy::UnserializeFromKeyValues( KeyValues *pKeyValues )
|
||||
{
|
||||
// Create the main element
|
||||
CDmElement *pElement = CreateDmElement( "DmElement", "ActBusyList", NULL );
|
||||
if ( !pElement )
|
||||
return NULL;
|
||||
|
||||
// Each act busy list needs to have an editortype associated with it so it displays nicely in editors
|
||||
pElement->SetValue( "editorType", "actBusyList" );
|
||||
|
||||
// All actbusy keys are elements of a single element array attribute 'children'
|
||||
CDmAttribute *pChildren = pElement->AddAttribute( "children", AT_ELEMENT_ARRAY );
|
||||
if ( !pChildren )
|
||||
return NULL;
|
||||
|
||||
// Under the root are all the actbusy keys
|
||||
for ( KeyValues *pActBusyKey = pKeyValues->GetFirstTrueSubKey(); pActBusyKey != NULL; pActBusyKey = pActBusyKey->GetNextTrueSubKey() )
|
||||
{
|
||||
if ( !UnserializeActBusyKey( pChildren, pActBusyKey ) )
|
||||
{
|
||||
Warning( "Error importing actbusy element %s\n", pActBusyKey->GetName() );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve all element references recursively
|
||||
RecursivelyResolveElement( pElement );
|
||||
|
||||
return pElement;
|
||||
}
|
||||
93
dmserializers/importcommentary.cpp
Normal file
93
dmserializers/importcommentary.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "importkeyvaluebase.h"
|
||||
#include "dmserializers.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/UtlBuffer.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Serialization class for Key Values
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportCommentary : public CImportKeyValueBase
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const { return "commentary"; }
|
||||
virtual const char *GetDescription() const { return "Commentary File"; }
|
||||
virtual int GetCurrentVersion() const { return 0; } // doesn't store a version
|
||||
virtual const char *GetImportedFormat() const { return "commentary"; }
|
||||
virtual int GetImportedVersion() const { return 1; }
|
||||
|
||||
virtual bool Serialize( CUtlBuffer &outBuf, CDmElement *pRoot );
|
||||
virtual bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion,
|
||||
const char *pSourceFormatName, int nSourceFormatVersion,
|
||||
DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot );
|
||||
|
||||
protected:
|
||||
// Main entry point for derived classes to implement unserialization
|
||||
virtual CDmElement* UnserializeFromKeyValues( KeyValues *pKeyValues ) { Assert( 0 ); return NULL; }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportCommentary s_ImportCommentary;
|
||||
|
||||
void InstallCommentaryImporter( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddSerializer( &s_ImportCommentary );
|
||||
}
|
||||
|
||||
|
||||
bool CImportCommentary::Serialize( CUtlBuffer &buf, CDmElement *pRoot )
|
||||
{
|
||||
IDmSerializer *pKVSerializer = g_pDataModel->FindSerializer( "keyvalues" );
|
||||
if ( !pKVSerializer )
|
||||
return false;
|
||||
|
||||
return pKVSerializer->Serialize( buf, pRoot );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handles creation of the right element for a keyvalue
|
||||
//-----------------------------------------------------------------------------
|
||||
class CElementForKeyValueCallback : public IElementForKeyValueCallback
|
||||
{
|
||||
public:
|
||||
const char *GetElementForKeyValue( const char *pszKeyName, int iNestingLevel )
|
||||
{
|
||||
if ( iNestingLevel == 1 && !Q_strncmp(pszKeyName, "entity", 6) )
|
||||
return "DmeCommentaryNodeEntity";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
bool CImportCommentary::Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion,
|
||||
const char *pSourceFormatName, int nSourceFormatVersion,
|
||||
DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot )
|
||||
{
|
||||
*ppRoot = NULL;
|
||||
|
||||
IDmSerializer *pKVSerializer = g_pDataModel->FindSerializer( "keyvalues" );
|
||||
if ( !pKVSerializer )
|
||||
return false;
|
||||
|
||||
CElementForKeyValueCallback KeyValuesCallback;
|
||||
g_pDataModel->SetKeyValuesElementCallback( &KeyValuesCallback );
|
||||
|
||||
bool bSuccess = pKVSerializer->Unserialize( buf, "keyvalues", nEncodingVersion, pSourceFormatName, nSourceFormatVersion, fileid, idConflictResolution, ppRoot );
|
||||
|
||||
g_pDataModel->SetKeyValuesElementCallback( NULL );
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
293
dmserializers/importkeyvaluebase.cpp
Normal file
293
dmserializers/importkeyvaluebase.cpp
Normal file
@@ -0,0 +1,293 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "importkeyvaluebase.h"
|
||||
#include "dmserializers.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Default serialization method
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportKeyValueBase::Serialize( CUtlBuffer &outBuf, CDmElement *pRoot )
|
||||
{
|
||||
Warning( "Serialization not supported for importing from keyvalues files\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates a new element
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement* CImportKeyValueBase::CreateDmElement( const char *pElementType, const char *pElementName, DmObjectId_t *pId )
|
||||
{
|
||||
// See if we can create an element of that type
|
||||
DmElementHandle_t hElement = g_pDataModel->CreateElement( pElementType, pElementName, DMFILEID_INVALID, pId );
|
||||
if ( hElement == DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
Warning("%s: Element uses unknown element type %s\n", m_pFileName, pElementType );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_pDataModel->GetElement( hElement );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used to output typed attributes to keyvalues
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportKeyValueBase::PrintBoolAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName )
|
||||
{
|
||||
if ( pElement->HasAttribute( pKeyName ) )
|
||||
{
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
|
||||
if ( pAttribute->GetType() == AT_BOOL )
|
||||
{
|
||||
outBuf.Printf("\"%s\" \"%d\"\n", pKeyName, pAttribute->GetValue<bool>( ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CImportKeyValueBase::PrintIntAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName )
|
||||
{
|
||||
if ( pElement->HasAttribute( pKeyName ) )
|
||||
{
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
|
||||
if ( pAttribute->GetType() == AT_INT )
|
||||
{
|
||||
outBuf.Printf("\"%s\" \"%d\"\n", pKeyName, pAttribute->GetValue<int>( ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CImportKeyValueBase::PrintFloatAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName )
|
||||
{
|
||||
if ( pElement->HasAttribute( pKeyName ) )
|
||||
{
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
|
||||
if ( pAttribute->GetType() == AT_FLOAT )
|
||||
{
|
||||
outBuf.Printf("\"%s\" \"%.10f\"\n", pKeyName, pAttribute->GetValue<float>( ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CImportKeyValueBase::PrintStringAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName, bool bSkipEmptryStrings, bool bPrintValueOnly )
|
||||
{
|
||||
if ( pElement->HasAttribute( pKeyName ) )
|
||||
{
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
|
||||
if ( pAttribute->GetType() == AT_STRING )
|
||||
{
|
||||
const char *pValue = pAttribute->GetValueString();
|
||||
if ( !bSkipEmptryStrings || pValue[0] )
|
||||
{
|
||||
if ( !bPrintValueOnly )
|
||||
{
|
||||
outBuf.Printf("\"%s\" \"%s\"\n", pKeyName, pValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
outBuf.Printf("\"%s\"\n", pValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used to add typed attributes from keyvalues
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportKeyValueBase::AddBoolAttribute( CDmElement* pElement, KeyValues *pKeyValues, const char *pKeyName, bool *pDefault )
|
||||
{
|
||||
KeyValues *pKey = pKeyValues->FindKey( pKeyName );
|
||||
bool bValue;
|
||||
if ( pKey )
|
||||
{
|
||||
bValue = pKey->GetInt() != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !pDefault )
|
||||
return true;
|
||||
bValue = *pDefault;
|
||||
}
|
||||
|
||||
return pElement->SetValue( pKeyName, bValue ) != NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used to add typed attributes from keyvalues
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportKeyValueBase::AddIntAttribute( CDmElement* pElement, KeyValues *pKeyValues, const char *pKeyName, int *pDefault )
|
||||
{
|
||||
KeyValues *pKey = pKeyValues->FindKey( pKeyName );
|
||||
int nValue;
|
||||
if ( pKey )
|
||||
{
|
||||
nValue = pKey->GetInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !pDefault )
|
||||
return true;
|
||||
nValue = *pDefault;
|
||||
}
|
||||
|
||||
return pElement->SetValue( pKeyName, nValue ) != NULL;
|
||||
}
|
||||
|
||||
bool CImportKeyValueBase::AddFloatAttribute( CDmElement* pElement, KeyValues *pKeyValues, const char *pKeyName, float *pDefault )
|
||||
{
|
||||
KeyValues *pKey = pKeyValues->FindKey( pKeyName );
|
||||
float flValue;
|
||||
if ( pKey )
|
||||
{
|
||||
flValue = pKey->GetFloat();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !pDefault )
|
||||
return true;
|
||||
flValue = *pDefault;
|
||||
}
|
||||
|
||||
return pElement->SetValue( pKeyName, flValue ) != NULL;
|
||||
}
|
||||
|
||||
bool CImportKeyValueBase::AddStringAttribute( CDmElement* pElement, KeyValues *pKeyValues, const char *pKeyName, const char *pDefault )
|
||||
{
|
||||
KeyValues *pKey = pKeyValues->FindKey( pKeyName );
|
||||
const char *pValue = "";
|
||||
if ( pKey )
|
||||
{
|
||||
pValue = pKey->GetString();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !pDefault )
|
||||
return true;
|
||||
pValue = pDefault;
|
||||
}
|
||||
|
||||
return pElement->SetValue( pKeyName, pValue ) != NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Used to add typed attributes from keyvalues
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportKeyValueBase::AddBoolAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, bool *pDefault )
|
||||
{
|
||||
if ( !AddBoolAttribute( pElement, pKeyValue, pKeyName, pDefault ) )
|
||||
return false;
|
||||
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
|
||||
pAttribute->AddFlag( nFlags );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CImportKeyValueBase::AddIntAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, int *pDefault )
|
||||
{
|
||||
if ( !AddIntAttribute( pElement, pKeyValue, pKeyName, pDefault ) )
|
||||
return false;
|
||||
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
|
||||
pAttribute->AddFlag( nFlags );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CImportKeyValueBase::AddFloatAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, float *pDefault )
|
||||
{
|
||||
if ( !AddFloatAttribute( pElement, pKeyValue, pKeyName, pDefault ) )
|
||||
return false;
|
||||
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
|
||||
pAttribute->AddFlag( nFlags );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CImportKeyValueBase::AddStringAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, const char *pDefault )
|
||||
{
|
||||
if ( !AddStringAttribute( pElement, pKeyValue, pKeyName, pDefault ) )
|
||||
return false;
|
||||
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pKeyName );
|
||||
pAttribute->AddFlag( nFlags );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Recursively resolves all attributes pointing to elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportKeyValueBase::RecursivelyResolveElement( CDmElement* pElement )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
pElement->Resolve();
|
||||
|
||||
CDmAttribute *pAttribute = pElement->FirstAttribute();
|
||||
while ( pAttribute )
|
||||
{
|
||||
switch ( pAttribute->GetType() )
|
||||
{
|
||||
case AT_ELEMENT:
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>();
|
||||
RecursivelyResolveElement( pElement );
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_ELEMENT_ARRAY:
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pElement = array[ i ];
|
||||
RecursivelyResolveElement( pElement );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
pAttribute = pAttribute->NextAttribute( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main entry point for the unserialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportKeyValueBase::Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion,
|
||||
const char *pSourceFormatName, int nSourceFormatVersion,
|
||||
DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot )
|
||||
{
|
||||
*ppRoot = NULL;
|
||||
m_pFileName = g_pDataModel->GetFileName( fileid );
|
||||
|
||||
KeyValues *kv = new KeyValues( "dmx file" );
|
||||
if ( !kv )
|
||||
return false;
|
||||
|
||||
bool bOk = kv->LoadFromBuffer( "dmx file", buf );
|
||||
if ( bOk )
|
||||
{
|
||||
*ppRoot = UnserializeFromKeyValues( kv );
|
||||
}
|
||||
|
||||
kv->deleteThis();
|
||||
return bOk;
|
||||
}
|
||||
84
dmserializers/importkeyvaluebase.h
Normal file
84
dmserializers/importkeyvaluebase.h
Normal file
@@ -0,0 +1,84 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef IMPORTKEYVALUEBASE_H
|
||||
#define IMPORTKEYVALUEBASE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "datamodel/idatamodel.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUtlBuffer;
|
||||
class KeyValues;
|
||||
class CDmElement;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Serialization class for Key Values
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class CImportKeyValueBase : public IDmSerializer
|
||||
{
|
||||
public:
|
||||
// Inherited from IDMSerializer
|
||||
virtual bool StoresVersionInFile() const { return false; }
|
||||
virtual bool IsBinaryFormat() const { return false; }
|
||||
virtual bool Serialize( CUtlBuffer &buf, CDmElement *pRoot );
|
||||
virtual bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion,
|
||||
const char *pSourceFormatName, int nSourceFormatVersion,
|
||||
DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot );
|
||||
|
||||
protected:
|
||||
// Main entry point for derived classes to implement unserialization
|
||||
virtual CDmElement* UnserializeFromKeyValues( KeyValues *pKeyValues ) = 0;
|
||||
|
||||
// Returns the file name associated with the unserialization
|
||||
const char *FileName() const;
|
||||
|
||||
// Creates new elements
|
||||
CDmElement* CreateDmElement( const char *pElementType, const char *pElementName, DmObjectId_t *pId );
|
||||
|
||||
// Recursively resolves all attributes pointing to elements
|
||||
void RecursivelyResolveElement( CDmElement* pElement );
|
||||
|
||||
// Used to add typed attributes from keyvalues
|
||||
bool AddBoolAttribute( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, bool *pDefault = NULL );
|
||||
bool AddIntAttribute( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int *pDefault = NULL );
|
||||
bool AddFloatAttribute( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, float *pDefault = NULL );
|
||||
bool AddStringAttribute( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, const char *pDefault = NULL );
|
||||
|
||||
// Used to add typed attributes from keyvalues
|
||||
bool AddBoolAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, bool *pDefault = NULL );
|
||||
bool AddIntAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, int *pDefault = NULL );
|
||||
bool AddFloatAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, float *pDefault = NULL );
|
||||
bool AddStringAttributeFlags( CDmElement* pElement, KeyValues *pKeyValue, const char *pKeyName, int nFlags, const char *pDefault = NULL );
|
||||
|
||||
// Used to output typed attributes to keyvalues
|
||||
void PrintBoolAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName );
|
||||
void PrintIntAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName );
|
||||
void PrintFloatAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName );
|
||||
void PrintStringAttribute( CDmElement* pElement, CUtlBuffer &outBuf, const char *pKeyName, bool bSkipEmptryStrings = false, bool bPrintValueOnly = false );
|
||||
|
||||
private:
|
||||
const char *m_pFileName;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the file name associated with the unserialization
|
||||
//-----------------------------------------------------------------------------
|
||||
inline const char *CImportKeyValueBase::FileName() const
|
||||
{
|
||||
return m_pFileName;
|
||||
}
|
||||
|
||||
|
||||
#endif // IMPORTKEYVALUEBASE_H
|
||||
673
dmserializers/importmks.cpp
Normal file
673
dmserializers/importmks.cpp
Normal file
@@ -0,0 +1,673 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "importkeyvaluebase.h"
|
||||
#include "dmserializers.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/UtlBuffer.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier2/tier2.h"
|
||||
#include "materialobjects/amalgtexturevars.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Serialization class for make sheet files
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportMKS : public IDmSerializer
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const { return "mks"; }
|
||||
virtual const char *GetDescription() const { return "Valve Make Sheet File"; }
|
||||
virtual bool IsBinaryFormat() const { return false; }
|
||||
virtual bool StoresVersionInFile() const { return false; }
|
||||
virtual int GetCurrentVersion() const { return 0; } // doesn't store a version
|
||||
virtual const char *GetImportedFormat() const { return "mks"; }
|
||||
virtual int GetImportedVersion() const { return 1; }
|
||||
|
||||
bool Serialize( CUtlBuffer &outBuf, CDmElement *pRoot );
|
||||
// Read from the UtlBuffer, return true if successful, and return the read-in root in ppRoot.
|
||||
bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, const char *pSourceFormatName,
|
||||
int nSourceFormatVersion, DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot );
|
||||
|
||||
private:
|
||||
|
||||
CDmElement *CreateDmeAmalgamatedTexture( const char *pName );
|
||||
CDmElement *CreateDmeSequence( const char *pName );
|
||||
CDmElement *CreateDmeSequenceFrame( const char *pName );
|
||||
CDmElement *CreateDmeSheetImage( const char *pImageName );
|
||||
|
||||
|
||||
void SetCurrentSequenceClamp( bool bState );
|
||||
|
||||
int ParsePackingMode( char *word );
|
||||
bool SetPackingMode( int eMode );
|
||||
|
||||
int ParseSequenceType( char *word );
|
||||
bool ValidateSequenceType( int eMode, char *word );
|
||||
bool CreateNewSequence( int mode );
|
||||
|
||||
void ParseFrameImages( CUtlVector<char *> &words, CUtlVector<char *> &outImageNames );
|
||||
bool CreateNewFrame( CUtlVector<char *> &imageNames, float ftime );
|
||||
|
||||
bool ValidateImagePacking( CDmElement *pBitmap, char *pImageName );
|
||||
CDmElement *FindSequence( CDmrElementArray< CDmElement > &mapsequences, int index );
|
||||
CDmElement *FindImage( const char *pFrameName );
|
||||
void AddImage( CDmElement *newSequenceEntry, char *pImageName );
|
||||
|
||||
CDmElement *m_pRoot;
|
||||
int m_NumActualLinesRead;
|
||||
CDmElement *m_pCurrentSequence;
|
||||
DmFileId_t m_Fileid;
|
||||
|
||||
int m_SequenceCount;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportMKS s_ImportMKS;
|
||||
|
||||
void InstallMKSImporter( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddSerializer( &s_ImportMKS );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out a new vmt file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportMKS::Serialize( CUtlBuffer &buf, CDmElement *pRoot )
|
||||
{
|
||||
//PrintStringAttribute( pRoot, buf, "shader", false, true );
|
||||
buf.Printf( "{\n" );
|
||||
buf.PushTab();
|
||||
|
||||
//if ( !SerializeShaderParameter( buf, pRoot ) )
|
||||
// return false;
|
||||
|
||||
buf.PopTab();
|
||||
buf.Printf( "}\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// Helper functions
|
||||
//--------------------------------------------------
|
||||
static void ApplyMacros( char * in_buf )
|
||||
{
|
||||
CUtlVector<char *> Words;
|
||||
V_SplitString( in_buf, " ", Words);
|
||||
if ( ( Words.Count() == 4 ) && (! stricmp( Words[0],"ga_frame") ) )
|
||||
{
|
||||
// ga_frame frm1 frm2 n -> frame frm1{r=a},frm1{g=a},frm1{b=a},frm2{a=a} n
|
||||
sprintf( in_buf, "frame %s{r=0},%s{g=a},%s{b=0},%s{a=a} %s",
|
||||
Words[1], Words[1], Words[1], Words[2], Words[3] );
|
||||
}
|
||||
Words.PurgeAndDeleteElements();
|
||||
}
|
||||
|
||||
static char *MoveToStart( char *pLineBuffer )
|
||||
{
|
||||
// Kill newline '\n'
|
||||
char *pChop = strchr( pLineBuffer, '\n' );
|
||||
if ( pChop )
|
||||
*pChop = 0;
|
||||
|
||||
// Kill '//' remove comment lines.
|
||||
char *comment = Q_strstr( pLineBuffer, "//" );
|
||||
if ( comment )
|
||||
*comment = 0;
|
||||
|
||||
// Move to start of non-whitespace
|
||||
char *in_str = pLineBuffer;
|
||||
while( ( in_str[0]==' ' ) || ( in_str[0]=='\t') )
|
||||
in_str++;
|
||||
|
||||
return in_str;
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// Parse out the packing mode
|
||||
//--------------------------------------------------
|
||||
int CImportMKS::ParsePackingMode( char *word )
|
||||
{
|
||||
// Read in the packing mode requested.
|
||||
int eRequestedMode = PCKM_INVALID;
|
||||
|
||||
if ( !stricmp( word, "flat" ) || !stricmp( word, "rgba" ) )
|
||||
{
|
||||
eRequestedMode = PCKM_FLAT;
|
||||
}
|
||||
else if ( !stricmp( word, "rgb+a" ) )
|
||||
{
|
||||
eRequestedMode = PCKM_RGB_A;
|
||||
}
|
||||
|
||||
if ( eRequestedMode == PCKM_INVALID )
|
||||
{
|
||||
Warning( "*** line %d: invalid packmode specified, allowed values are 'rgba' or 'rgb+a'!\n", m_NumActualLinesRead );
|
||||
}
|
||||
|
||||
return eRequestedMode;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Parse out the sequence type
|
||||
//--------------------------------------------------
|
||||
int CImportMKS::ParseSequenceType( char *word )
|
||||
{
|
||||
int eMode = SQM_ALPHA_INVALID;
|
||||
|
||||
char const *szSeqType = StringAfterPrefix( word, "sequence" );
|
||||
if ( !stricmp( szSeqType, "" ) || !stricmp( szSeqType, "-rgba" ) )
|
||||
{
|
||||
eMode = SQM_RGBA;
|
||||
}
|
||||
else if ( !stricmp( szSeqType, "-rgb" ) )
|
||||
{
|
||||
eMode = SQM_RGB;
|
||||
}
|
||||
else if ( !stricmp( szSeqType, "-a" ) )
|
||||
{
|
||||
eMode = SQM_ALPHA;
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "*** line %d: invalid sequence type '%s', allowed 'sequence-rgba' or 'sequence-rgb' or 'sequence-a'!\n", m_NumActualLinesRead, word );
|
||||
}
|
||||
|
||||
return eMode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Functions to set attribute values
|
||||
//--------------------------------------------------
|
||||
void CImportMKS::SetCurrentSequenceClamp( bool bState )
|
||||
{
|
||||
Warning( "Attempting to set clamp when there is no current sequence!\n" );
|
||||
if ( m_pCurrentSequence )
|
||||
{
|
||||
CDmAttribute *pClamp= m_pCurrentSequence->GetAttribute( "clamp" );
|
||||
Assert( pClamp );
|
||||
pClamp->SetValue< bool >( bState );
|
||||
}
|
||||
}
|
||||
|
||||
bool CImportMKS::SetPackingMode( int eMode )
|
||||
{
|
||||
CDmAttribute *pCurrentPackingModeAttr = m_pRoot->GetAttribute( "packmode" );
|
||||
Assert( pCurrentPackingModeAttr );
|
||||
int currentPackingMode = pCurrentPackingModeAttr->GetValue< int >();
|
||||
|
||||
CDmrElementArray< CDmElement > sequences( m_pRoot, "sequences", true );
|
||||
|
||||
// Assign the packing mode read in to member var.
|
||||
if ( !sequences.Count() )
|
||||
{
|
||||
pCurrentPackingModeAttr->SetValue< int >( eMode );
|
||||
}
|
||||
else if ( currentPackingMode != eMode )
|
||||
{
|
||||
// Allow special changes:
|
||||
// flat -> rgb+a
|
||||
if ( currentPackingMode == PCKM_FLAT && eMode == PCKM_RGB_A )
|
||||
{
|
||||
Msg( "Warning changing packing mode when %d sequences already defined. This may not be serialized correctly.\n", sequences.Count() );
|
||||
pCurrentPackingModeAttr->SetValue< int >( eMode );
|
||||
}
|
||||
// everything else
|
||||
else
|
||||
{
|
||||
Msg( "*** line error: incompatible packmode change when %d sequences already defined!\n", sequences.Count() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// Validation
|
||||
//--------------------------------------------------
|
||||
bool CImportMKS::ValidateSequenceType( int eMode, char *word )
|
||||
{
|
||||
CDmAttribute *pCurrentPackingModeAttr = m_pRoot->GetAttribute( "packmode" );
|
||||
Assert( pCurrentPackingModeAttr );
|
||||
int currentPackingMode = pCurrentPackingModeAttr->GetValue< int >();
|
||||
|
||||
switch ( currentPackingMode )
|
||||
{
|
||||
case PCKM_FLAT:
|
||||
switch ( eMode )
|
||||
{
|
||||
case SQM_RGBA:
|
||||
break;
|
||||
default:
|
||||
Msg( "*** line error: invalid sequence type '%s', packing 'flat' allows only 'sequence-rgba'!\n", word );
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PCKM_RGB_A:
|
||||
switch ( eMode )
|
||||
{
|
||||
case SQM_RGB:
|
||||
case SQM_ALPHA:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Warning( "Invalid packing mode!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// Validate that image packing is correct
|
||||
//--------------------------------------------------
|
||||
bool CImportMKS::ValidateImagePacking( CDmElement *pBitmap, char *pImageName )
|
||||
{
|
||||
CDmAttribute *pCurrentPackingModeAttr = m_pRoot->GetAttribute( "packmode" );
|
||||
Assert( pCurrentPackingModeAttr );
|
||||
int currentPackingMode = pCurrentPackingModeAttr->GetValue< int >();
|
||||
|
||||
if ( currentPackingMode == PCKM_RGB_A )
|
||||
{
|
||||
CDmrElementArray< CDmElement > mapsequences( pBitmap, "mapsequences", true );
|
||||
for ( uint16 idx = 0; idx < mapsequences.Count(); ++idx )
|
||||
{
|
||||
CDmElement *pSeq = FindSequence( mapsequences, idx );
|
||||
|
||||
Assert( pSeq );
|
||||
|
||||
CDmAttribute *pSequenceNumberAttr = pSeq->GetAttribute( "sequencenumber" );
|
||||
Assert( pSequenceNumberAttr );
|
||||
int sequenceNumber = pSequenceNumberAttr->GetValue<int>();
|
||||
|
||||
CDmAttribute *pModeAttr = pSeq->GetAttribute( "mode" );
|
||||
Assert( pModeAttr );
|
||||
int mode = pModeAttr->GetValue<int>();
|
||||
|
||||
CDmAttribute *pCurrentSequenceNumberAttr = m_pCurrentSequence->GetAttribute( "sequencenumber" );
|
||||
Assert( pCurrentSequenceNumberAttr );
|
||||
int currentSequenceNumber = pCurrentSequenceNumberAttr->GetValue<int>();
|
||||
|
||||
CDmAttribute *pCurrentModeAttr = m_pCurrentSequence->GetAttribute( "mode" );
|
||||
Assert( pCurrentModeAttr );
|
||||
int currentMode = pCurrentModeAttr->GetValue<int>();
|
||||
|
||||
if ( ( mode != SQM_RGBA ) && ( mode != currentMode ) )
|
||||
{
|
||||
Msg( "*** line error: 'rgb+a' packing cannot pack image '%s' belonging to sequences %d and %d!\n",
|
||||
pImageName,
|
||||
sequenceNumber,
|
||||
currentSequenceNumber );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Functions to create dme elements
|
||||
//--------------------------------------------------
|
||||
CDmElement *CImportMKS::CreateDmeAmalgamatedTexture( const char *pName )
|
||||
{
|
||||
DmElementHandle_t hElement = g_pDataModel->CreateElement( "DmeAmalgamatedTexture", "CDmeAmalgamatedTexture", m_Fileid );
|
||||
if ( hElement == DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
Warning( "Element uses unknown element type %s\n", "CDmeAmalgamatedTexture" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CDmElement *pElement = g_pDataModel->GetElement( hElement );
|
||||
if ( !pElement )
|
||||
return NULL;
|
||||
|
||||
// Base members
|
||||
if ( !pElement->AddAttribute( "images", AT_ELEMENT_ARRAY ) )
|
||||
return NULL;
|
||||
if ( !pElement->AddAttribute( "packmode", AT_INT ) )
|
||||
return NULL;
|
||||
if ( !pElement->AddAttribute( "width", AT_INT ) )
|
||||
return NULL;
|
||||
if ( !pElement->AddAttribute( "height", AT_INT ) )
|
||||
return NULL;
|
||||
|
||||
return pElement;
|
||||
}
|
||||
|
||||
CDmElement *CImportMKS::CreateDmeSequence( const char *pName )
|
||||
{
|
||||
DmElementHandle_t hElement = g_pDataModel->CreateElement( "DmeSheetSequence", pName, m_Fileid );
|
||||
if ( hElement == DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
Warning( "Element uses unknown element type %s\n", "CDmeSheetSequence" );
|
||||
return false;
|
||||
}
|
||||
|
||||
CDmElement *pElement = g_pDataModel->GetElement( hElement );
|
||||
if ( !pElement )
|
||||
return NULL;
|
||||
|
||||
if ( !pElement->AddAttribute( "sequencenumber", AT_INT ) )
|
||||
return false;
|
||||
if ( !pElement->AddAttribute( "clamp", AT_BOOL ) )
|
||||
return false;
|
||||
if ( !pElement->AddAttribute( "mode", AT_INT ) )
|
||||
return false;
|
||||
if ( !pElement->AddAttribute( "frames", AT_ELEMENT_ARRAY ) )
|
||||
return false;
|
||||
|
||||
CDmAttribute *pClapAttr = pElement->GetAttribute( "clamp" );
|
||||
Assert( pClapAttr );
|
||||
pClapAttr->SetValue< bool >( true );
|
||||
|
||||
CDmAttribute *pModeAttr = pElement->GetAttribute( "mode" );
|
||||
Assert( pModeAttr );
|
||||
pModeAttr->SetValue< int >( SQM_RGBA );
|
||||
|
||||
return pElement;
|
||||
}
|
||||
|
||||
CDmElement *CImportMKS::CreateDmeSequenceFrame( const char *pName )
|
||||
{
|
||||
DmElementHandle_t hElement = g_pDataModel->CreateElement( "DmeSheetSequenceFrame", pName, m_Fileid );
|
||||
if ( hElement == DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
Warning( "Element uses unknown element type %s\n", "CDmeSheetSequenceFrame" );
|
||||
return false;
|
||||
}
|
||||
|
||||
CDmElement *pElement = g_pDataModel->GetElement( hElement );
|
||||
if ( !pElement )
|
||||
return NULL;
|
||||
|
||||
if ( !pElement->AddAttribute( "sheetimages", AT_ELEMENT_ARRAY ) )
|
||||
return false;
|
||||
if ( !pElement->AddAttribute( "displaytime", AT_FLOAT ) )
|
||||
return false;
|
||||
|
||||
return pElement;
|
||||
}
|
||||
|
||||
CDmElement *CImportMKS::CreateDmeSheetImage( const char *pImageName )
|
||||
{
|
||||
DmElementHandle_t hElement = g_pDataModel->CreateElement( "DmeSheetImage", pImageName, m_Fileid );
|
||||
if ( hElement == DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
Warning("Element uses unknown element type %s\n", "CDmeSheetImage" );
|
||||
return false;
|
||||
}
|
||||
|
||||
CDmElement *pElement = g_pDataModel->GetElement( hElement );
|
||||
if ( !pElement )
|
||||
return NULL;
|
||||
|
||||
if ( !pElement->AddAttribute( "xcoord", AT_INT ) )
|
||||
return NULL;
|
||||
if ( !pElement->AddAttribute( "ycoord", AT_INT ) )
|
||||
return NULL;
|
||||
|
||||
return pElement;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// Functions to put this all together
|
||||
//---------------------------------------------------------------
|
||||
|
||||
bool CImportMKS::CreateNewSequence( int mode )
|
||||
{
|
||||
m_pCurrentSequence = CreateDmeSequence( "CDmeSheetSequence" );
|
||||
if ( !m_pCurrentSequence )
|
||||
return false;
|
||||
|
||||
CDmAttribute *pSeqNoAttr = m_pCurrentSequence->GetAttribute( "sequencenumber" );
|
||||
Assert( pSeqNoAttr );
|
||||
pSeqNoAttr->SetValue< int >( m_SequenceCount );
|
||||
m_SequenceCount++;
|
||||
|
||||
CDmAttribute *pSeqType = m_pCurrentSequence->GetAttribute( "mode" );
|
||||
Assert( pSeqType );
|
||||
pSeqType->SetValue< int >( mode );
|
||||
|
||||
CDmrElementArray< CDmElement > sequences( m_pRoot, "sequences", true );
|
||||
sequences.AddToTail( m_pCurrentSequence );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CImportMKS::CreateNewFrame( CUtlVector<char *> &imageNames, float ftime )
|
||||
{
|
||||
CDmElement *pNewFrame = CreateDmeSequenceFrame( "CDmeSheetSequenceFrame" );
|
||||
if ( !pNewFrame )
|
||||
return false;
|
||||
|
||||
CDmAttribute *pDisplayTimeAttr = pNewFrame->GetAttribute( "displaytime" );
|
||||
Assert( pDisplayTimeAttr );
|
||||
pDisplayTimeAttr->SetValue< float >( ftime );
|
||||
|
||||
for ( int i = 0; i < imageNames.Count(); ++i )
|
||||
{
|
||||
Assert( imageNames.Count() <= MAX_IMAGES_PER_FRAME );
|
||||
AddImage( pNewFrame, imageNames[i] );
|
||||
}
|
||||
|
||||
CDmrElementArray< CDmElement > currentFrames( m_pCurrentSequence->GetAttribute( "frames" ) );
|
||||
currentFrames.AddToTail( pNewFrame );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CDmElement *CImportMKS::FindImage( const char *pFrameName )
|
||||
{
|
||||
CDmrElementArray< CDmElement > images = m_pRoot->GetAttribute( "images" );
|
||||
int nCount = images.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( pFrameName, images[i]->GetName() ) )
|
||||
return images[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CDmElement *CImportMKS::FindSequence( CDmrElementArray< CDmElement > &mapsequences, int index )
|
||||
{
|
||||
if ( index < mapsequences.Count() )
|
||||
{
|
||||
return mapsequences[index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CImportMKS::AddImage( CDmElement *pSequenceEntry, char *pImageName )
|
||||
{
|
||||
// Store the image in the image list, this is a string - bitmap mapping.
|
||||
CDmElement *pBitmap = FindImage( pImageName );
|
||||
if ( !pBitmap )
|
||||
{
|
||||
CDmElement *pBitmap = CreateDmeSheetImage( pImageName );
|
||||
if ( !pBitmap )
|
||||
return;
|
||||
|
||||
CDmrElementArray< CDmElement > images = m_pRoot->GetAttribute( "images" );
|
||||
images.AddToTail( pBitmap );
|
||||
}
|
||||
|
||||
pBitmap = FindImage( pImageName );
|
||||
Assert( pBitmap );
|
||||
|
||||
|
||||
CDmrElementArray< CDmElement > sheetImages = pSequenceEntry->GetAttribute( "sheetimages" );
|
||||
sheetImages.AddToTail( pBitmap );
|
||||
|
||||
if ( !ValidateImagePacking( pBitmap, pImageName ) )
|
||||
{
|
||||
Warning( "Image packing validation failed!" );
|
||||
}
|
||||
|
||||
CDmrElementArray< CDmElement > mapSequences( pBitmap, "mapsequences", true );
|
||||
mapSequences.AddToTail( m_pCurrentSequence );
|
||||
|
||||
}
|
||||
|
||||
void CImportMKS::ParseFrameImages( CUtlVector<char *> &words, CUtlVector<char *> &outImageNames )
|
||||
{
|
||||
for ( int i = 0; i < words.Count() - 2; i++ )
|
||||
{
|
||||
char *fnamebuf = words[i+1];
|
||||
outImageNames.AddToTail( fnamebuf );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main entry point for the unserialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportMKS::Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, const char *pSourceFormatName,
|
||||
int nSourceFormatVersion, DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot )
|
||||
{
|
||||
*ppRoot = NULL;
|
||||
m_Fileid = fileid;
|
||||
|
||||
// Create the main element
|
||||
m_pRoot = CreateDmeAmalgamatedTexture( "CDmeAmalgamatedTexture" );
|
||||
if ( !m_pRoot )
|
||||
return false;
|
||||
|
||||
*ppRoot = m_pRoot;
|
||||
|
||||
// Initial value for this param
|
||||
m_SequenceCount = 0;
|
||||
bool bSuccess = SetPackingMode( PCKM_FLAT );
|
||||
if ( !bSuccess )
|
||||
return false;
|
||||
|
||||
char linebuffer[4096];
|
||||
m_NumActualLinesRead = 0;
|
||||
|
||||
while ( buf.IsValid() )
|
||||
{
|
||||
buf.GetLine( linebuffer, sizeof(linebuffer) );
|
||||
++m_NumActualLinesRead;
|
||||
|
||||
char *in_str = MoveToStart( linebuffer );
|
||||
if ( in_str[0] == NULL )
|
||||
continue;
|
||||
|
||||
strlwr( in_str ); // send string to lowercase.
|
||||
ApplyMacros( in_str );
|
||||
CUtlVector<char *> words;
|
||||
V_SplitString( in_str, " ", words);
|
||||
if ( ( words.Count() == 1) && ( !stricmp( words[0], "loop" ) ) )
|
||||
{
|
||||
SetCurrentSequenceClamp( false );
|
||||
}
|
||||
else if ( ( words.Count() == 2 ) && ( !stricmp( words[0], "packmode" ) ) )
|
||||
{
|
||||
// Read in the packing mode requested.
|
||||
int eRequestedMode = ParsePackingMode( words[1] );
|
||||
if ( ( eRequestedMode == PCKM_INVALID ) || !SetPackingMode( eRequestedMode ) )
|
||||
{
|
||||
Warning( "Unable to set packing mode." );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if ( ( words.Count() == 2) && StringHasPrefix( words[0], "sequence" ) )
|
||||
{
|
||||
int seq_no = atoi( words[1] );
|
||||
if ( seq_no != m_SequenceCount )
|
||||
{
|
||||
Warning( "Sequence number mismatch.\n" );
|
||||
}
|
||||
|
||||
// Figure out the sequence type
|
||||
int mode = ParseSequenceType( words[0] );
|
||||
if ( ( mode == SQM_ALPHA_INVALID ) || !ValidateSequenceType( mode, words[0] ) )
|
||||
{
|
||||
Warning( "Invalid sequence type.\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool bSuccess = CreateNewSequence( mode );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
Warning( "Unable to create new sequence.\n" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if ( ( words.Count() >= 3) && (! stricmp( words[0], "frame" ) ) )
|
||||
{
|
||||
if ( m_pCurrentSequence )
|
||||
{
|
||||
float ftime = atof( words[ words.Count() - 1 ] );
|
||||
// Warning( "ftime is %f\n", ftime );
|
||||
|
||||
CUtlVector<char *> imageNames;
|
||||
ParseFrameImages( words, imageNames );
|
||||
bool bSuccess = CreateNewFrame( imageNames, ftime );
|
||||
if ( !bSuccess )
|
||||
{
|
||||
Warning( "Unable to create new frame.\n" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Trying to add a frame when there is no current sequence.\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "*** line %d: Bad command \"%s\"!\n", m_NumActualLinesRead, in_str );
|
||||
return NULL;
|
||||
}
|
||||
words.PurgeAndDeleteElements();
|
||||
}
|
||||
|
||||
// Import compiler settings
|
||||
char pTexFile[MAX_PATH];
|
||||
const char *pFileName = g_pDataModel->GetFileName( fileid );
|
||||
Q_strncpy( pTexFile, pFileName, sizeof(pTexFile) );
|
||||
Q_SetExtension( pTexFile, "txt", sizeof(pTexFile) );
|
||||
if ( g_pFullFileSystem->FileExists( pTexFile ) )
|
||||
{
|
||||
CDmElement *pTextureCompileSettings = NULL;
|
||||
if ( !g_pDataModel->RestoreFromFile( pTexFile, NULL, "tex_source1", &pTextureCompileSettings, CR_COPY_NEW ) )
|
||||
{
|
||||
Warning( "Error reading texture compile settings file \"%s\"!\n", pTexFile );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pTextureCompileSettings->SetFileId( m_pRoot->GetFileId(), TD_DEEP, true );
|
||||
m_pRoot->SetValue( "textureCompileSettings", pTextureCompileSettings );
|
||||
}
|
||||
|
||||
return g_pDataModel->UpdateUnserializedElements( pSourceFormatName, nSourceFormatVersion, fileid, idConflictResolution, ppRoot );
|
||||
}
|
||||
|
||||
|
||||
|
||||
220
dmserializers/importsfmv1.cpp
Normal file
220
dmserializers/importsfmv1.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Format converter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportSFMV1 : public CSFMBaseImporter
|
||||
{
|
||||
typedef CSFMBaseImporter BaseClass;
|
||||
public:
|
||||
CImportSFMV1( char const *formatName, char const *nextFormatName );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pSourceRoot );
|
||||
|
||||
// Fixes up a single time attribute - converting from float seconds to int tenths-of-a-millisecond
|
||||
void ConvertTimeAttribute( CDmElement *pElementInternal, const char *pOldName, const char *pNewName );
|
||||
|
||||
// Fixes up a single timeframe
|
||||
void FixupTimeframe( CDmElement *pElementInternal );
|
||||
|
||||
// Fixes up a single log - converting from int milliseconds to int tenths-of-a-millisecond
|
||||
void FixupLog( CDmElement *pElementInternal );
|
||||
|
||||
CUtlRBTree< CDmElement*, int > m_fixedElements;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportSFMV1 s_ImportDmxV1( "sfm_v1", "sfm_v2" );
|
||||
|
||||
void InstallSFMV1Importer( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddLegacyUpdater( &s_ImportDmxV1 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CImportSFMV1::CImportSFMV1( char const *formatName, char const *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
m_fixedElements.SetLessFunc( DefLessFunc( CDmElement * ) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportSFMV1::DoFixup( CDmElement *pElementInternal )
|
||||
{
|
||||
if ( !pElementInternal )
|
||||
return true;
|
||||
|
||||
if ( m_fixedElements.Find( pElementInternal ) != m_fixedElements.InvalidIndex() )
|
||||
return true;
|
||||
|
||||
m_fixedElements.Insert( pElementInternal );
|
||||
|
||||
const char *pType = pElementInternal->GetTypeString();
|
||||
if ( !Q_strcmp( pType, "DmeTimeFrame" ) )
|
||||
{
|
||||
FixupTimeframe( pElementInternal );
|
||||
}
|
||||
else if ( !Q_strcmp( pType, "DmeLog" ) ||
|
||||
!Q_strcmp( pType, "DmeIntLog" ) ||
|
||||
!Q_strcmp( pType, "DmeFloatLog" ) ||
|
||||
!Q_strcmp( pType, "DmeBoolLog" ) ||
|
||||
!Q_strcmp( pType, "DmeColorLog" ) ||
|
||||
!Q_strcmp( pType, "DmeVector2Log" ) ||
|
||||
!Q_strcmp( pType, "DmeVector3Log" ) ||
|
||||
!Q_strcmp( pType, "DmeVector4Log" ) ||
|
||||
!Q_strcmp( pType, "DmeQAngleLog" ) ||
|
||||
!Q_strcmp( pType, "DmeQuaternionLog" ) ||
|
||||
!Q_strcmp( pType, "DmeVMatrixLog" ) )
|
||||
{
|
||||
FixupLog( pElementInternal );
|
||||
}
|
||||
|
||||
|
||||
for ( CDmAttribute *pAttribute = pElementInternal->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->GetType() == AT_ELEMENT )
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
|
||||
DoFixup( pElement );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = array[ i ];
|
||||
DoFixup( pChild );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up a single time attribute - converting from float seconds to int tenths-of-a-millisecond
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV1::ConvertTimeAttribute( CDmElement *pElementInternal, const char *pOldName, const char *pNewName )
|
||||
{
|
||||
float time = 0.0f;
|
||||
CDmAttribute *pOldAttr = pElementInternal->GetAttribute( pOldName );
|
||||
if ( !pOldAttr )
|
||||
{
|
||||
Warning( "*** Problem in file encountered!\n" );
|
||||
Warning( "*** TimeFrame \"%s\" is missing attribute \"%s\"!\n", pElementInternal->GetName(), pOldName );
|
||||
Warning( "*** Setting new attribute \"%s\" to 0\n", pNewName );
|
||||
}
|
||||
else if ( pOldAttr->GetType() != AT_FLOAT )
|
||||
{
|
||||
Warning( "*** Problem in file encountered!\n" );
|
||||
Warning( "*** TimeFrame \"%s\" has attribute \"%s\" with an unexpected type (expected float)!\n", pElementInternal->GetName(), pOldName );
|
||||
}
|
||||
else
|
||||
{
|
||||
time = pOldAttr->GetValue< float >();
|
||||
pElementInternal->RemoveAttribute( pOldName );
|
||||
}
|
||||
|
||||
CDmAttribute *pNewAttr = NULL;
|
||||
|
||||
// this is disabled because even dmxconvert installs *some* movieobjects factories, when it probably shouldn't
|
||||
// the method of installing movieobjects factories will change at some point in the future, and we can turn on this safety check then
|
||||
#if 0
|
||||
int i = g_pDataModel->GetFirstFactory();
|
||||
if ( g_pDataModel->IsValidFactory( i ) )
|
||||
{
|
||||
// factories installed - most likely from within movieobjects.lib
|
||||
// ie there may be different ways of allocating attributes, so it's not safe to add them here
|
||||
pNewAttr = pElementInternal->GetAttribute( pNewName );
|
||||
if ( !pNewAttr || pNewAttr->GetType() != AT_INT )
|
||||
{
|
||||
Assert( 0 );
|
||||
Warning( "*** Converter error - expected element \"%s\" to contain int attribute \"%s\"!\n", pElementInternal->GetName(), pNewName );
|
||||
Warning( "*** - if you get this error, the converter is out of sync with the element library!\n" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
// no factories installed - most likely from within dmxconvert.exe
|
||||
// ie we're just working with CDmElement subclasses, so it's safe to add attributes
|
||||
pNewAttr = pElementInternal->AddAttribute( pNewName, AT_INT );
|
||||
if ( !pNewAttr )
|
||||
{
|
||||
Assert( 0 );
|
||||
Warning( "*** Converter error - element \"%s\" already has a non-int attribute \"%s\"!\n", pElementInternal->GetName(), pNewName );
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
pNewAttr->SetValue< int >( floor( time * 10000 + 0.5f ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up a single timeframe
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV1::FixupTimeframe( CDmElement *pElementInternal )
|
||||
{
|
||||
ConvertTimeAttribute( pElementInternal, "start", "startTime" );
|
||||
ConvertTimeAttribute( pElementInternal, "duration", "durationTime" );
|
||||
ConvertTimeAttribute( pElementInternal, "offset", "offsetTime" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up a single log - converting from int milliseconds to int tenths-of-a-millisecond
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV1::FixupLog( CDmElement *pElementInternal )
|
||||
{
|
||||
CDmAttribute *pAttr = pElementInternal->GetAttribute( "times" );
|
||||
if ( !pAttr )
|
||||
{
|
||||
Warning( "*** Problem in file encountered!\n" );
|
||||
Warning( "*** Log \"%s\" is missing attribute \"%s\"!\n", pElementInternal->GetName(), "times" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pAttr->GetType() != AT_INT_ARRAY )
|
||||
{
|
||||
Warning( "*** Problem in file encountered!\n" );
|
||||
Warning( "*** Log \"%s\" has attribute \"%s\" with an unexpected type (expected int array)!\n", pElementInternal->GetName(), "times" );
|
||||
return;
|
||||
}
|
||||
|
||||
CDmrArray<int> array( pAttr );
|
||||
int c = array.Count();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
// convert all log times from int milliseconds to int tenths-of-a-millisecond
|
||||
array.Set( i, 10 * array[i] );
|
||||
}
|
||||
}
|
||||
295
dmserializers/importsfmv2.cpp
Normal file
295
dmserializers/importsfmv2.cpp
Normal file
@@ -0,0 +1,295 @@
|
||||
//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Format converter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportSFMV2 : public CSFMBaseImporter
|
||||
{
|
||||
typedef CSFMBaseImporter BaseClass;
|
||||
public:
|
||||
CImportSFMV2( char const *formatName, char const *nextFormatName );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pSourceRoot );
|
||||
|
||||
|
||||
void FixupElement( CDmElement *pElement );
|
||||
// Fixes up all elements
|
||||
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportSFMV2 s_ImportSFMV2( "sfm_v2", "sfm_v3" );
|
||||
|
||||
void InstallSFMV2Importer( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddLegacyUpdater( &s_ImportSFMV2 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CImportSFMV2::CImportSFMV2( char const *formatName, char const *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
struct LayerType_t
|
||||
{
|
||||
char const *loglayertype;
|
||||
int datatype;
|
||||
char const *logtype;
|
||||
};
|
||||
|
||||
static LayerType_t g_LayerTypes[] =
|
||||
{
|
||||
{ "DmeIntLogLayer", AT_INT_ARRAY, "DmeIntLog" },
|
||||
{ "DmeFloatLogLayer", AT_FLOAT_ARRAY, "DmeFloatLog" },
|
||||
{ "DmeBoolLogLayer", AT_BOOL_ARRAY, "DmeBoolLog" },
|
||||
// AT_STRING_ARRAY,
|
||||
// AT_VOID_ARRAY,
|
||||
// AT_OBJECTID_ARRAY,
|
||||
{ "DmeColorLogLayer", AT_COLOR_ARRAY, "DmeColorLog" },
|
||||
{ "DmeVector2LogLayer", AT_VECTOR2_ARRAY, "DmeVector2Log" },
|
||||
{ "DmeVector3LogLayer", AT_VECTOR3_ARRAY, "DmeVector3Log" },
|
||||
{ "DmeVector4LogLayer", AT_VECTOR4_ARRAY, "DmeVector4Log" },
|
||||
{ "DmeQAngleLogLayer", AT_QANGLE_ARRAY, "DmeQAngleLog" },
|
||||
{ "DmeQuaternionLogLayer", AT_QUATERNION_ARRAY, "DmeQuaternionLog" },
|
||||
{ "DmeVMatrixLogLayer", AT_VMATRIX_ARRAY, "DmeVMatrixLog" },
|
||||
// AT_ELEMENT_ARRAY
|
||||
// NO ARRAY TYPES EITHER!!!
|
||||
};
|
||||
|
||||
int GetLogType( char const *type )
|
||||
{
|
||||
int c = ARRAYSIZE( g_LayerTypes );
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( type, g_LayerTypes[ i ].logtype ) )
|
||||
return g_LayerTypes[ i ].datatype;
|
||||
}
|
||||
return AT_UNKNOWN;
|
||||
}
|
||||
|
||||
char const *GetLogLayerType( int nDataType )
|
||||
{
|
||||
int c = ARRAYSIZE( g_LayerTypes );
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
if ( nDataType == g_LayerTypes[ i ].datatype )
|
||||
return g_LayerTypes[ i ].loglayertype;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char const *GetLogLayerType( char const *logType )
|
||||
{
|
||||
int c = ARRAYSIZE( g_LayerTypes );
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( logType, g_LayerTypes[ i ].logtype ) )
|
||||
return g_LayerTypes[ i ].loglayertype;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template< class T >
|
||||
void CopyValues( int layerType, CDmElement *pElement, CDmElement *pLayer, CDmAttribute *pInTimeAttribute, CDmAttribute *pInCurveTypeAttribute )
|
||||
{
|
||||
CDmAttribute *pInValueAttribute = pElement->GetAttribute( "values" );
|
||||
if ( !pInValueAttribute )
|
||||
{
|
||||
Assert( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
CDmrArray<T> outValues( pLayer->AddAttribute( "values", (DmAttributeType_t)layerType ) );
|
||||
CDmrArray<int> outTimes( pLayer->AddAttribute( "times", AT_INT_ARRAY ) );
|
||||
CDmrArray<int> outCurveTypes;
|
||||
if ( pInCurveTypeAttribute )
|
||||
{
|
||||
outCurveTypes.Init( pLayer->AddAttribute( "curvetypes", AT_INT_ARRAY ) );
|
||||
}
|
||||
|
||||
CDmrArray<T> inValues( pInValueAttribute );
|
||||
CDmrArray<int> inTimes( pInTimeAttribute );
|
||||
CDmrArray<int> inCurveTypes( pInCurveTypeAttribute );
|
||||
|
||||
Assert( inValues.Count() == inTimes.Count() );
|
||||
int c = inValues.Count();
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
outTimes.AddToTail( inTimes[ i ] );
|
||||
outValues.AddToTail( inValues[ i ] );
|
||||
if ( outCurveTypes.IsValid() )
|
||||
{
|
||||
outCurveTypes.AddToTail( inCurveTypes[ i ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV2::FixupElement( CDmElement *pElement )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
// Perform the fixup
|
||||
const char *pType = pElement->GetTypeString();
|
||||
int layerType = GetLogType( pType );
|
||||
if ( layerType != AT_UNKNOWN )
|
||||
{
|
||||
/*
|
||||
char buf[ 128 ];
|
||||
g_pDataModel->ToString( pElement->GetId(), buf, sizeof( buf ) );
|
||||
|
||||
Msg( "Processing %s %s id %s\n",
|
||||
pElement->GetTypeString(), pElement->GetName(), buf );
|
||||
*/
|
||||
|
||||
// Find attribute arrays for times, values and curvetypes
|
||||
CDmAttribute *pTimes = pElement->GetAttribute( "times" );
|
||||
CDmAttribute *pCurveTypes = NULL;
|
||||
|
||||
// FIX
|
||||
CDmAttribute *pAttr = pElement->AddAttribute( "usecurvetypes", AT_BOOL );
|
||||
if ( pAttr->GetValue<bool>() )
|
||||
{
|
||||
pCurveTypes = pElement->GetAttribute( "curvetypes" );
|
||||
}
|
||||
|
||||
// Get the default layer (added when the new style log is created)
|
||||
CDmrElementArray<> layers( pElement->AddAttribute( "layers", AT_ELEMENT_ARRAY ) );
|
||||
CDmElement *layer = NULL;
|
||||
if ( layers.Count() == 0 )
|
||||
{
|
||||
DmElementHandle_t hElement = g_pDataModel->CreateElement( GetLogLayerType( layerType ), GetLogLayerType( layerType ), pElement->GetFileId() );
|
||||
layer = g_pDataModel->GetElement( hElement );
|
||||
layers.AddToTail( layer );
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( layers.Count() == 1 );
|
||||
layer = layers[ 0 ];
|
||||
}
|
||||
|
||||
// Copy data
|
||||
switch ( layerType )
|
||||
{
|
||||
default:
|
||||
case AT_UNKNOWN:
|
||||
break;
|
||||
case AT_FLOAT_ARRAY:
|
||||
CopyValues< float >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
case AT_INT_ARRAY:
|
||||
CopyValues< int >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
case AT_BOOL_ARRAY:
|
||||
CopyValues< bool >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
case AT_COLOR_ARRAY:
|
||||
CopyValues< Color >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
case AT_VECTOR2_ARRAY:
|
||||
CopyValues< Vector2D >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
case AT_VECTOR3_ARRAY:
|
||||
CopyValues< Vector >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
case AT_VECTOR4_ARRAY:
|
||||
CopyValues< Vector4D >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
case AT_QANGLE_ARRAY:
|
||||
CopyValues< QAngle >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
case AT_QUATERNION_ARRAY:
|
||||
CopyValues< Quaternion >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
case AT_VMATRIX_ARRAY:
|
||||
CopyValues< VMatrix >( layerType, pElement, layer, pTimes, pCurveTypes );
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the back pointer
|
||||
CDmAttribute *ownerLog = layer->AddAttribute( "ownerlog", AT_ELEMENT );
|
||||
Assert( ownerLog );
|
||||
ownerLog->SetValue( pElement->GetHandle() );
|
||||
|
||||
// Delete the base attributes
|
||||
pElement->RemoveAttribute( "times" );
|
||||
pElement->RemoveAttribute( "values" );
|
||||
pElement->RemoveAttribute( "curvetypes" );
|
||||
}
|
||||
}
|
||||
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV2::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
if ( list.Find( pElement ) != list.InvalidIndex() )
|
||||
return;
|
||||
|
||||
list.Insert( pElement );
|
||||
|
||||
// Descene to bottom of tree, then do fixup coming back up the tree
|
||||
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->GetType() == AT_ELEMENT )
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
|
||||
BuildList( pElement, list );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = array[ i ];
|
||||
BuildList( pChild, list );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CImportSFMV2::DoFixup( CDmElement *pSourceRoot )
|
||||
{
|
||||
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
|
||||
BuildList( pSourceRoot, fixlist );
|
||||
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
|
||||
{
|
||||
// Search and replace in the entire tree!
|
||||
FixupElement( fixlist[ i ] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
228
dmserializers/importsfmv3.cpp
Normal file
228
dmserializers/importsfmv3.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Format converter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportSFMV3 : public CSFMBaseImporter
|
||||
{
|
||||
typedef CSFMBaseImporter BaseClass;
|
||||
public:
|
||||
CImportSFMV3( char const *formatName, char const *nextFormatName );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pSourceRoot );
|
||||
|
||||
|
||||
void FixupElement( CDmElement *pElement );
|
||||
// Fixes up all elements
|
||||
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportSFMV3 s_ImportSFMV3( "sfm_v3", "sfm_v4" );
|
||||
|
||||
void InstallSFMV3Importer( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddLegacyUpdater( &s_ImportSFMV3 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CImportSFMV3::CImportSFMV3( char const *formatName, char const *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
struct LogToCurveInfoTypeMap_t
|
||||
{
|
||||
const char *pLogType;
|
||||
const char *pLogLayerType;
|
||||
const char *pCurveInfoType;
|
||||
};
|
||||
|
||||
LogToCurveInfoTypeMap_t g_typeMap[] =
|
||||
{
|
||||
{ "DmeIntLog", "DmeIntLogLayer", "DmeIntCurveInfo" },
|
||||
{ "DmeFloatLog", "DmeFloatLogLayer", "DmeFloatCurveInfo" },
|
||||
{ "DmeBoolLog", "DmeBoolLogLayer", "DmeBoolCurveInfo" },
|
||||
// string,
|
||||
// void,
|
||||
// objectid,
|
||||
{ "DmeColorLog", "DmeColorLogLayer", "DmeColorCurveInfo" },
|
||||
{ "DmeVector2Log", "DmeVector2LogLayer", "DmeVector2CurveInfo" },
|
||||
{ "DmeVector3Log", "DmeVector3LogLayer", "DmeVector3CurveInfo" },
|
||||
{ "DmeVector4Log", "DmeVector4LogLayer", "DmeVector4CurveInfo" },
|
||||
{ "DmeQAngleLog", "DmeQAngleLogLayer", "DmeQAngleCurveInfo" },
|
||||
{ "DmeQuaternionLog", "DmeQuaternionLogLayer","DmeQuaternionCurveInfo" },
|
||||
{ "DmeVMatrixLog", "DmeVMatrixLogLayer", "DmeVMatrixCurveInfo" },
|
||||
};
|
||||
|
||||
const char *GetCurveInfoTypeFromLogType( const char *pLogType )
|
||||
{
|
||||
int c = ARRAYSIZE( g_typeMap );
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( pLogType, g_typeMap[ i ].pLogType ) )
|
||||
return g_typeMap[ i ].pCurveInfoType;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool IsLogLayerType( const char *pLogLayerType )
|
||||
{
|
||||
int c = ARRAYSIZE( g_typeMap );
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( pLogLayerType, g_typeMap[ i ].pLogLayerType ) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MoveAttribute( CDmElement *pFromElement, const char *pFromAttrName, CDmElement *pToElement = NULL, const char *pToAttrName = NULL, DmAttributeType_t toType = AT_UNKNOWN )
|
||||
{
|
||||
if ( !pToAttrName )
|
||||
{
|
||||
pToAttrName = pFromAttrName;
|
||||
}
|
||||
|
||||
if ( pToElement )
|
||||
{
|
||||
CDmAttribute *pFromAttr = pFromElement->GetAttribute( pFromAttrName );
|
||||
const void *pValue = pFromAttr->GetValueUntyped();
|
||||
DmAttributeType_t fromType = pFromAttr->GetType();
|
||||
if ( toType == AT_UNKNOWN )
|
||||
{
|
||||
toType = fromType;
|
||||
}
|
||||
|
||||
CDmAttribute *pToAttr = pToElement->AddAttribute( pToAttrName, toType );
|
||||
if ( !pToAttr )
|
||||
{
|
||||
Warning( "*** Problem in converter encountered!\n" );
|
||||
Warning( "*** Unable to find or add attribute \"%s\" to element \"%s\"!\n", pToAttrName, pToElement->GetName() );
|
||||
}
|
||||
else if ( fromType != toType )
|
||||
{
|
||||
Warning( "*** Problem in file encountered!\n" );
|
||||
Warning( "*** Element \"%s\" has attribute \"%s\" with an unexpected type!\n", pFromElement->GetName(), pFromAttrName );
|
||||
}
|
||||
else
|
||||
{
|
||||
pToAttr->SetValue( toType, pValue );
|
||||
}
|
||||
}
|
||||
|
||||
pFromElement->RemoveAttribute( pFromAttrName );
|
||||
}
|
||||
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV3::FixupElement( CDmElement *pElement )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
const char *pType = pElement->GetTypeString();
|
||||
|
||||
// log layer
|
||||
if ( IsLogLayerType( pType ) )
|
||||
{
|
||||
pElement->RemoveAttribute( "ownerlog" );
|
||||
return;
|
||||
}
|
||||
|
||||
// log
|
||||
const char *pCurveInfoType = GetCurveInfoTypeFromLogType( pType );
|
||||
if ( !pCurveInfoType )
|
||||
return;
|
||||
|
||||
CDmElement *pCurveInfo = NULL;
|
||||
CDmAttribute *pUseCurveTypeAttr = pElement->GetAttribute( "usecurvetypes" );
|
||||
if ( pUseCurveTypeAttr && pUseCurveTypeAttr->GetValue<bool>() )
|
||||
{
|
||||
DmElementHandle_t hElement = g_pDataModel->CreateElement( "curve info", pCurveInfoType, pElement->GetFileId() );
|
||||
pCurveInfo = g_pDataModel->GetElement( hElement );
|
||||
}
|
||||
pElement->RemoveAttribute( "usecurvetypes" );
|
||||
|
||||
MoveAttribute( pElement, "defaultcurvetype", pCurveInfo, "defaultCurveType", AT_INT );
|
||||
MoveAttribute( pElement, "defaultedgezerovalue",pCurveInfo, "defaultEdgeZeroValue" );
|
||||
MoveAttribute( pElement, "useedgeinfo", pCurveInfo, "useEdgeInfo", AT_BOOL );
|
||||
MoveAttribute( pElement, "rightedgetime", pCurveInfo, "rightEdgeTime", AT_INT );
|
||||
MoveAttribute( pElement, "left_edge_active", pCurveInfo, "leftEdgeActive", AT_BOOL );
|
||||
MoveAttribute( pElement, "right_edge_active", pCurveInfo, "rightEdgeActive", AT_BOOL );
|
||||
MoveAttribute( pElement, "left_edge_curvetype", pCurveInfo, "leftEdgeCurveType", AT_INT );
|
||||
MoveAttribute( pElement, "right_edge_curvetype",pCurveInfo, "rightEdgeCurveType", AT_INT );
|
||||
MoveAttribute( pElement, "left_edge_value", pCurveInfo, "leftEdgeValue" );
|
||||
MoveAttribute( pElement, "right_edge_value", pCurveInfo, "rightEdgeValue" );
|
||||
}
|
||||
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV3::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
if ( list.Find( pElement ) != list.InvalidIndex() )
|
||||
return;
|
||||
|
||||
list.Insert( pElement );
|
||||
|
||||
// Descend to bottom of tree, then do fixup coming back up the tree
|
||||
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->GetType() == AT_ELEMENT )
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
|
||||
BuildList( pElement, list );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = array[ i ];
|
||||
BuildList( pChild, list );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CImportSFMV3::DoFixup( CDmElement *pSourceRoot )
|
||||
{
|
||||
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
|
||||
BuildList( pSourceRoot, fixlist );
|
||||
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
|
||||
{
|
||||
// Search and replace in the entire tree!
|
||||
FixupElement( fixlist[ i ] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
124
dmserializers/importsfmv4.cpp
Normal file
124
dmserializers/importsfmv4.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Format converter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportSFMV4 : public CSFMBaseImporter
|
||||
{
|
||||
typedef CSFMBaseImporter BaseClass;
|
||||
public:
|
||||
CImportSFMV4( char const *formatName, char const *nextFormatName );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pSourceRoot );
|
||||
|
||||
|
||||
void FixupElement( CDmElement *pElement );
|
||||
// Fixes up all elements
|
||||
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportSFMV4 s_ImportSFMV4( "sfm_v4", "sfm_v5" );
|
||||
|
||||
void InstallSFMV4Importer( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddLegacyUpdater( &s_ImportSFMV4 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CImportSFMV4::CImportSFMV4( char const *formatName, char const *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
}
|
||||
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV4::FixupElement( CDmElement *pElement )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
const char *pType = pElement->GetTypeString();
|
||||
|
||||
if ( !V_stricmp( pType, "DmeCamera" ) )
|
||||
{
|
||||
CDmAttribute *pOldToneMapScaleAttr = pElement->GetAttribute( "toneMapScale" );
|
||||
float fNewBloomScale = pOldToneMapScaleAttr->GetValue<float>( );
|
||||
|
||||
Assert( !pElement->HasAttribute("bloomScale") );
|
||||
|
||||
CDmAttribute *pNewBloomScaleAttr = pElement->AddAttribute( "bloomScale", AT_FLOAT );
|
||||
pNewBloomScaleAttr->SetValue( fNewBloomScale );
|
||||
pOldToneMapScaleAttr->SetValue( 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV4::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
if ( list.Find( pElement ) != list.InvalidIndex() )
|
||||
return;
|
||||
|
||||
list.Insert( pElement );
|
||||
|
||||
// Descend to bottom of tree, then do fixup coming back up the tree
|
||||
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->GetType() == AT_ELEMENT )
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
|
||||
BuildList( pElement, list );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = array[ i ];
|
||||
BuildList( pChild, list );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CImportSFMV4::DoFixup( CDmElement *pSourceRoot )
|
||||
{
|
||||
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
|
||||
BuildList( pSourceRoot, fixlist );
|
||||
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
|
||||
{
|
||||
// Search and replace in the entire tree!
|
||||
FixupElement( fixlist[ i ] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
121
dmserializers/importsfmv5.cpp
Normal file
121
dmserializers/importsfmv5.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Format converter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportSFMV5 : public CSFMBaseImporter
|
||||
{
|
||||
typedef CSFMBaseImporter BaseClass;
|
||||
public:
|
||||
CImportSFMV5( char const *formatName, char const *nextFormatName );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pSourceRoot );
|
||||
|
||||
|
||||
void FixupElement( CDmElement *pElement );
|
||||
// Fixes up all elements
|
||||
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportSFMV5 s_ImportSFMV5( "sfm_v5", "sfm_v6" );
|
||||
|
||||
void InstallSFMV5Importer( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddLegacyUpdater( &s_ImportSFMV5 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CImportSFMV5::CImportSFMV5( char const *formatName, char const *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV5::FixupElement( CDmElement *pElement )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
const char *pType = pElement->GetTypeString();
|
||||
|
||||
if ( !V_stricmp( pType, "DmeSpotLight" ) )
|
||||
{
|
||||
pElement->SetType( "DmeProjectedLight" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV5::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
if ( list.Find( pElement ) != list.InvalidIndex() )
|
||||
return;
|
||||
|
||||
list.Insert( pElement );
|
||||
|
||||
// Descend to bottom of tree, then do fixup coming back up the tree
|
||||
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->GetType() == AT_ELEMENT )
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
|
||||
BuildList( pElement, list );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = array[ i ];
|
||||
BuildList( pChild, list );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CImportSFMV5::DoFixup( CDmElement *pSourceRoot )
|
||||
{
|
||||
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
|
||||
BuildList( pSourceRoot, fixlist );
|
||||
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
|
||||
{
|
||||
// Search and replace in the entire tree!
|
||||
FixupElement( fixlist[ i ] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
141
dmserializers/importsfmv6.cpp
Normal file
141
dmserializers/importsfmv6.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Format converter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportSFMV6 : public CSFMBaseImporter
|
||||
{
|
||||
typedef CSFMBaseImporter BaseClass;
|
||||
public:
|
||||
CImportSFMV6( char const *formatName, char const *nextFormatName );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pSourceRoot );
|
||||
|
||||
Quaternion DirectionToOrientation( const Vector &dir );
|
||||
|
||||
void FixupElement( CDmElement *pElement );
|
||||
// Fixes up all elements
|
||||
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportSFMV6 s_ImportSFMV6( "sfm_v6", "sfm_v7" );
|
||||
|
||||
void InstallSFMV6Importer( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddLegacyUpdater( &s_ImportSFMV6 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CImportSFMV6::CImportSFMV6( char const *formatName, char const *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
}
|
||||
|
||||
Quaternion CImportSFMV6::DirectionToOrientation( const Vector &dir )
|
||||
{
|
||||
Vector up( 0, 0, 1 );
|
||||
Vector right = CrossProduct( dir, up );
|
||||
if ( right.IsLengthLessThan( 0.001f ) )
|
||||
{
|
||||
up.Init( 1, 0, 0 );
|
||||
right = CrossProduct( dir, up );
|
||||
}
|
||||
right.NormalizeInPlace();
|
||||
up = CrossProduct( right, dir );
|
||||
|
||||
Quaternion q;
|
||||
BasisToQuaternion( dir, right, up, q );
|
||||
return q;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV6::FixupElement( CDmElement *pElement )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
const char *pType = pElement->GetTypeString();
|
||||
|
||||
if ( !V_stricmp( pType, "DmeProjectedLight" ) )
|
||||
{
|
||||
Vector vDir = pElement->GetValue<Vector>( "direction" );
|
||||
pElement->RemoveAttribute( "direction" );
|
||||
Quaternion q = DirectionToOrientation( vDir );
|
||||
pElement->SetValue<Quaternion>( "orientation", q );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV6::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
if ( list.Find( pElement ) != list.InvalidIndex() )
|
||||
return;
|
||||
|
||||
list.Insert( pElement );
|
||||
|
||||
// Descend to bottom of tree, then do fixup coming back up the tree
|
||||
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->GetType() == AT_ELEMENT )
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
|
||||
BuildList( pElement, list );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = array[ i ];
|
||||
BuildList( pChild, list );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CImportSFMV6::DoFixup( CDmElement *pSourceRoot )
|
||||
{
|
||||
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
|
||||
BuildList( pSourceRoot, fixlist );
|
||||
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
|
||||
{
|
||||
// Search and replace in the entire tree!
|
||||
FixupElement( fixlist[ i ] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
145
dmserializers/importsfmv7.cpp
Normal file
145
dmserializers/importsfmv7.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Format converter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportSFMV7 : public CSFMBaseImporter
|
||||
{
|
||||
typedef CSFMBaseImporter BaseClass;
|
||||
public:
|
||||
CImportSFMV7( char const *formatName, char const *nextFormatName );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pSourceRoot );
|
||||
|
||||
|
||||
void FixupElement( CDmElement *pElement );
|
||||
// Fixes up all elements
|
||||
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportSFMV7 s_ImportSFMV7( "sfm_v7", "sfm_v8" );
|
||||
|
||||
void InstallSFMV7Importer( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddLegacyUpdater( &s_ImportSFMV7 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CImportSFMV7::CImportSFMV7( char const *formatName, char const *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV7::FixupElement( CDmElement *pElement )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
const char *pType = pElement->GetTypeString();
|
||||
|
||||
if ( !V_stricmp( pType, "DmeAnimationSet" ) )
|
||||
{
|
||||
// Add a level of indirection in animation sets
|
||||
// Modify the type of all controls from DmElement to DmeAnimationSetControl
|
||||
CDmrElementArray<> srcPresets( pElement, "presets" );
|
||||
if ( srcPresets.IsValid() )
|
||||
{
|
||||
CDmrElementArray<> presetGroupArray( pElement, "presetGroups", true );
|
||||
CDmElement *pPresetGroup = CreateElement< CDmElement >( "custom", pElement->GetFileId() );
|
||||
pPresetGroup->SetType( "DmePresetGroup" );
|
||||
CDmrElementArray<> presets( pPresetGroup, "presets", true );
|
||||
presetGroupArray.AddToTail( pPresetGroup );
|
||||
|
||||
int nCount = srcPresets.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pPreset = srcPresets[i];
|
||||
if ( pPreset )
|
||||
{
|
||||
pPreset->SetType( "DmePreset" );
|
||||
presets.AddToTail( pPreset );
|
||||
}
|
||||
}
|
||||
|
||||
srcPresets.RemoveAll();
|
||||
}
|
||||
pElement->RemoveAttribute( "presets" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV7::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
if ( list.Find( pElement ) != list.InvalidIndex() )
|
||||
return;
|
||||
|
||||
list.Insert( pElement );
|
||||
|
||||
// Descend to bottom of tree, then do fixup coming back up the tree
|
||||
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->GetType() == AT_ELEMENT )
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
|
||||
BuildList( pElement, list );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = array[ i ];
|
||||
BuildList( pChild, list );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CImportSFMV7::DoFixup( CDmElement *pSourceRoot )
|
||||
{
|
||||
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
|
||||
BuildList( pSourceRoot, fixlist );
|
||||
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
|
||||
{
|
||||
// Search and replace in the entire tree!
|
||||
FixupElement( fixlist[ i ] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
140
dmserializers/importsfmv8.cpp
Normal file
140
dmserializers/importsfmv8.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Format converter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportSFMV8 : public CSFMBaseImporter
|
||||
{
|
||||
typedef CSFMBaseImporter BaseClass;
|
||||
public:
|
||||
CImportSFMV8( const char *formatName, const char *nextFormatName );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pSourceRoot );
|
||||
|
||||
|
||||
void FixupElement( CDmElement *pElement );
|
||||
// Fixes up all elements
|
||||
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportSFMV8 s_ImportSFMV8( "sfm_v8", "sfm_v9" );
|
||||
|
||||
void InstallSFMV8Importer( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddLegacyUpdater( &s_ImportSFMV8 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CImportSFMV8::CImportSFMV8( const char *formatName, const char *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV8::FixupElement( CDmElement *pElement )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
const char *pType = pElement->GetTypeString();
|
||||
|
||||
if ( !V_stricmp( pType, "DmeAnimationSet" ) )
|
||||
{
|
||||
// Remove 'midpoint' from all controls, and
|
||||
// Add 'defaultBalance' and 'defaultMultilevel' to all non-transform controls
|
||||
CDmrElementArray<> srcControls( pElement, "controls" );
|
||||
if ( srcControls.IsValid() )
|
||||
{
|
||||
int nCount = srcControls.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pControl = srcControls[i];
|
||||
if ( pControl )
|
||||
{
|
||||
if ( !pControl->GetValue<bool>( "transform" ) )
|
||||
{
|
||||
pControl->InitValue( "defaultBalance", 0.5f );
|
||||
pControl->InitValue( "defaultMultilevel", 0.5f );
|
||||
pControl->RemoveAttribute( "midpoint" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV8::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
if ( list.Find( pElement ) != list.InvalidIndex() )
|
||||
return;
|
||||
|
||||
list.Insert( pElement );
|
||||
|
||||
// Descend to bottom of tree, then do fixup coming back up the tree
|
||||
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->GetType() == AT_ELEMENT )
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
|
||||
BuildList( pElement, list );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = array[ i ];
|
||||
BuildList( pChild, list );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CImportSFMV8::DoFixup( CDmElement *pSourceRoot )
|
||||
{
|
||||
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
|
||||
BuildList( pSourceRoot, fixlist );
|
||||
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
|
||||
{
|
||||
// Search and replace in the entire tree!
|
||||
FixupElement( fixlist[ i ] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
143
dmserializers/importsfmv9.cpp
Normal file
143
dmserializers/importsfmv9.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose: fixed "color" attribute of lights to be of type Color, rather than Vector4
|
||||
// this should have been put in a *long* time ago, but I somehow missed creating the updater between 3 and 4
|
||||
// fortunately, since all updates happen on untyped elements, it's reasonably safe to do this out of order
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "dmserializers.h"
|
||||
#include "dmebaseimporter.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlmap.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Format converter
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportSFMV9 : public CSFMBaseImporter
|
||||
{
|
||||
typedef CSFMBaseImporter BaseClass;
|
||||
public:
|
||||
CImportSFMV9( const char *formatName, const char *nextFormatName );
|
||||
|
||||
private:
|
||||
virtual bool DoFixup( CDmElement *pSourceRoot );
|
||||
|
||||
|
||||
void FixupElement( CDmElement *pElement );
|
||||
// Fixes up all elements
|
||||
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportSFMV9 s_ImportSFMV9( "sfm_v9", "sfm_v10" );
|
||||
|
||||
void InstallSFMV9Importer( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddLegacyUpdater( &s_ImportSFMV9 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CImportSFMV9::CImportSFMV9( const char *formatName, const char *nextFormatName ) :
|
||||
BaseClass( formatName, nextFormatName )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV9::FixupElement( CDmElement *pElement )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
const char *pType = pElement->GetTypeString();
|
||||
if ( !V_stricmp( pType, "DmeLight" ) ||
|
||||
!V_stricmp( pType, "DmeDirectionalLight" ) ||
|
||||
!V_stricmp( pType, "DmeProjectedLight" ) ||
|
||||
!V_stricmp( pType, "DmePointLight" ) ||
|
||||
!V_stricmp( pType, "DmeSpotLight" ) ||
|
||||
!V_stricmp( pType, "DmeAmbientLight" ) )
|
||||
{
|
||||
const CDmAttribute *pOldAttr = pElement->GetAttribute( "color", AT_VECTOR4 );
|
||||
if ( !pOldAttr )
|
||||
return;
|
||||
|
||||
Color color;
|
||||
|
||||
{ // scoping this section of code since vecColor is invalid after RemoveAttribute
|
||||
const Vector4D &vecColor = pOldAttr->GetValue< Vector4D >();
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
{
|
||||
color[ i ] = ( int )clamp( vecColor[ i ], 0.0f, 255.0f );
|
||||
}
|
||||
|
||||
pElement->RemoveAttribute( "color" );
|
||||
}
|
||||
|
||||
CDmAttribute *pNewAttr = pElement->AddAttribute( "color", AT_COLOR );
|
||||
pNewAttr->SetValue( color );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixes up all elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportSFMV9::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
|
||||
{
|
||||
if ( !pElement )
|
||||
return;
|
||||
|
||||
if ( list.Find( pElement ) != list.InvalidIndex() )
|
||||
return;
|
||||
|
||||
list.Insert( pElement );
|
||||
|
||||
// Descend to bottom of tree, then do fixup coming back up the tree
|
||||
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->GetType() == AT_ELEMENT )
|
||||
{
|
||||
CDmElement *pElement = pAttribute->GetValueElement<CDmElement>( );
|
||||
BuildList( pElement, list );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
CDmrElementArray<> array( pAttribute );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pChild = array[ i ];
|
||||
BuildList( pChild, list );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CImportSFMV9::DoFixup( CDmElement *pSourceRoot )
|
||||
{
|
||||
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
|
||||
BuildList( pSourceRoot, fixlist );
|
||||
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
|
||||
{
|
||||
// Search and replace in the entire tree!
|
||||
FixupElement( fixlist[ i ] );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
567
dmserializers/importtex.cpp
Normal file
567
dmserializers/importtex.cpp
Normal file
@@ -0,0 +1,567 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "importkeyvaluebase.h"
|
||||
#include "dmserializers.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/UtlBuffer.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier2/tier2.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Serialization class for make sheet files
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportTex : public IDmSerializer
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const { return "tex_source1"; }
|
||||
virtual const char *GetDescription() const { return "Valve Texture Configuration File"; }
|
||||
virtual bool IsBinaryFormat() const { return false; }
|
||||
virtual bool StoresVersionInFile() const { return false; }
|
||||
virtual int GetCurrentVersion() const { return 0; } // doesn't store a version
|
||||
virtual const char *GetImportedFormat() const { return "tex"; }
|
||||
virtual int GetImportedVersion() const { return 1; }
|
||||
|
||||
bool Serialize( CUtlBuffer &outBuf, CDmElement *pRoot ) { return false; }
|
||||
// Read from the UtlBuffer, return true if successful, and return the read-in root in ppRoot.
|
||||
bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, const char *pSourceFormatName,
|
||||
int nSourceFormatVersion, DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot );
|
||||
|
||||
private:
|
||||
bool ParseOptionKey( const char *pKeyName, const char *pKeyValue, CDmElement *pTexture );
|
||||
const char *GetPossiblyQuotedWord( const char *pInBuf, char *pOutbuf );
|
||||
bool GetKeyValueFromBuffer( CUtlBuffer &buffer, char *key, char *val );
|
||||
CDmElement *AddProcessor( CDmElement *pElement, const char *pProcessorType, const char *pName );
|
||||
CDmElement *FindProcessor( CDmElement *pElement, const char *pProcessorType, const char *pName );
|
||||
|
||||
// Information for the mipmap processor
|
||||
bool m_bNoNice;
|
||||
bool m_bAlphatestMipmapping;
|
||||
float m_flAlphatestMipmapThreshhold;
|
||||
float m_flAlphatestMipmapHiFreqThreshhold;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportTex s_ImportTex;
|
||||
|
||||
void InstallTEXImporter( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddSerializer( &s_ImportTex );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Processors
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement *CImportTex::AddProcessor( CDmElement *pElement, const char *pProcessorType, const char *pName )
|
||||
{
|
||||
CDmrElementArray< CDmElement > processors( pElement, "processors", true );
|
||||
CDmElement* pProcessor = CreateElement< CDmElement >( pProcessorType, pName, pElement->GetFileId() );
|
||||
processors.AddToTail( pProcessor );
|
||||
return pProcessor;
|
||||
}
|
||||
|
||||
CDmElement *CImportTex::FindProcessor( CDmElement *pElement, const char *pProcessorType, const char *pName )
|
||||
{
|
||||
CDmrElementArrayConst< CDmElement > processors( pElement, "processors" );
|
||||
for ( int i = 0; i < processors.Count(); ++i )
|
||||
{
|
||||
if ( !Q_stricmp( pProcessorType, processors[i]->GetTypeString() ) && !Q_stricmp( pName, processors[i]->GetName() ) )
|
||||
return processors[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Parses key values out of the txt file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportTex::ParseOptionKey( const char *pKeyName, const char *pKeyValue, CDmElement *pTexture )
|
||||
{
|
||||
int iValue = atoi( pKeyValue ); // To properly have "clamps 0" and not enable the clamping
|
||||
|
||||
if( !Q_stricmp( pKeyName, "startframe" ) )
|
||||
{
|
||||
pTexture->SetValue( "startFrame", iValue );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "endframe" ) )
|
||||
{
|
||||
pTexture->SetValue( "endFrame", iValue );
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "cubemap" ) )
|
||||
{
|
||||
pTexture->SetValue( "textureType", iValue ? 1 : 0 );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "volumetexture" ) )
|
||||
{
|
||||
pTexture->SetValue( "volumeTextureDepth", iValue );
|
||||
|
||||
/*
|
||||
// FIXME: Volume textures don't currently support DXT compression
|
||||
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_NOCOMPRESS;
|
||||
*/
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "clamps" ) )
|
||||
{
|
||||
pTexture->SetValue( "clamps", iValue ? true : false );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "clampt" ) )
|
||||
{
|
||||
pTexture->SetValue( "clampt", iValue ? true : false );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "clampu" ) )
|
||||
{
|
||||
pTexture->SetValue( "clampu", iValue ? true : false );
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "nodebug" ) )
|
||||
{
|
||||
pTexture->SetValue( "noDebugOverride", iValue ? true : false );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "pointsample" ) )
|
||||
{
|
||||
if ( iValue != 0 )
|
||||
{
|
||||
pTexture->SetValue( "filterType", 4 );
|
||||
}
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "trilinear" ) )
|
||||
{
|
||||
if ( iValue != 0 )
|
||||
{
|
||||
pTexture->SetValue( "filterType", 2 );
|
||||
}
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "anisotropic" ) )
|
||||
{
|
||||
if ( iValue != 0 )
|
||||
{
|
||||
pTexture->SetValue( "filterType", 1 );
|
||||
}
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "nomip" ) )
|
||||
{
|
||||
pTexture->SetValue( "noMip", iValue ? true : false );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "nolod" ) )
|
||||
{
|
||||
pTexture->SetValue( "noLod", iValue ? true : false );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "nonice" ) )
|
||||
{
|
||||
m_bNoNice = iValue ? true : false;
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "alphatest" ) )
|
||||
{
|
||||
m_bAlphatestMipmapping = iValue ? true : false;
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "alphatest_threshhold" ) )
|
||||
{
|
||||
m_flAlphatestMipmapThreshhold = (float)atof( pKeyValue );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "alphatest_hifreq_threshhold" ) )
|
||||
{
|
||||
m_flAlphatestMipmapHiFreqThreshhold = (float)atof( pKeyValue );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "dxt5" ) )
|
||||
{
|
||||
pTexture->SetValue( "hintDxt5Compression", iValue ? true : false );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "nocompress" ) )
|
||||
{
|
||||
pTexture->SetValue( "noCompression", iValue ? true : false );
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "numchannels" ) )
|
||||
{
|
||||
CDmElement *pProcessor = AddProcessor( pTexture, "DmeTP_ChangeColorChannels", "changeColorChannels" );
|
||||
pProcessor->SetValue( "maxChannels", iValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning("unrecognized option in text file - %s\n", pKeyName );
|
||||
}
|
||||
|
||||
return true;
|
||||
#if 0
|
||||
else if ( !Q_stricmp( pKeyName, "skybox" ) )
|
||||
{
|
||||
// We're going to treat it like a cubemap until the very end (we have to load and process all cubemap
|
||||
// faces at once, so we can match their edges with the texture compression and mipmapping).
|
||||
m_bIsSkyBox = iValue ? true : false;
|
||||
m_bIsCubeMap = iValue ? true : false;
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "skyboxcropped" ) )
|
||||
{
|
||||
m_bIsCroppedSkyBox = iValue ? true : false;
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "bumpscale" ) )
|
||||
{
|
||||
m_flBumpScale = atof( pKeyValue );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "border" ) )
|
||||
{
|
||||
SetFlagValue( m_nFlags, TEXTUREFLAGS_BORDER, iValue );
|
||||
// Gets applied to s, t and u We currently assume black border color
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "normal" ) )
|
||||
{
|
||||
SetFlagValue( m_nFlags, TEXTUREFLAGS_NORMAL, iValue );
|
||||
|
||||
// Normal maps not supported for manual mip painting
|
||||
m_bManualMip = false;
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "normalga" ) )
|
||||
{
|
||||
m_bNormalToDXT5GA = iValue ? true : false;
|
||||
SetFlagValue( m_vtfProcOptions.flags0, VtfProcessingOptions::OPT_NORMAL_GA, iValue );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "invertgreen" ) )
|
||||
{
|
||||
m_bNormalInvertGreen = iValue ? true : false;
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "ssbump" ) )
|
||||
{
|
||||
SetFlagValue( m_nFlags, TEXTUREFLAGS_SSBUMP, iValue );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "allmips" ) )
|
||||
{
|
||||
SetFlagValue( m_nFlags, TEXTUREFLAGS_ALL_MIPS, iValue );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "rendertarget" ) )
|
||||
{
|
||||
SetFlagValue( m_nFlags, TEXTUREFLAGS_RENDERTARGET, iValue );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "oneovermiplevelinalpha" ) )
|
||||
{
|
||||
SetFlagValue( m_vtfProcOptions.flags0, VtfProcessingOptions::OPT_SET_ALPHA_ONEOVERMIP, iValue );
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "premultcolorbyoneovermiplevel" ) )
|
||||
{
|
||||
SetFlagValue( m_vtfProcOptions.flags0, VtfProcessingOptions::OPT_PREMULT_COLOR_ONEOVERMIP, iValue );
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "normaltodudv" ) )
|
||||
{
|
||||
m_bNormalToDuDv = iValue ? true : false;
|
||||
SetFlagValue( m_vtfProcOptions.flags0, VtfProcessingOptions::OPT_NORMAL_DUDV, iValue );
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "stripalphachannel" ) )
|
||||
{
|
||||
m_bStripAlphaChannel = iValue ? true : false;
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "stripcolorchannel" ) )
|
||||
{
|
||||
m_bStripColorChannel = iValue ? true : false;
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "normalalphatodudvluminance" ) )
|
||||
{
|
||||
m_bAlphaToLuminance = iValue ? true : false;
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "dudv" ) )
|
||||
{
|
||||
m_bDuDv = iValue ? true : false;
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "reduce" ) )
|
||||
{
|
||||
m_nReduceX = atoi(pKeyValue);
|
||||
m_nReduceY = m_nReduceX;
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "reducex" ) )
|
||||
{
|
||||
m_nReduceX = atoi(pKeyValue);
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "reducey" ) )
|
||||
{
|
||||
m_nReduceY = atoi(pKeyValue);
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "maxwidth" ) )
|
||||
{
|
||||
m_nMaxDimensionX = atoi(pKeyValue);
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "maxwidth_360" ) )
|
||||
{
|
||||
m_nMaxDimensionX_360 = atoi(pKeyValue);
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "maxheight" ) )
|
||||
{
|
||||
m_nMaxDimensionY = atoi(pKeyValue);
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "maxheight_360" ) )
|
||||
{
|
||||
m_nMaxDimensionY_360 = atoi(pKeyValue);
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "alphatodistance" ) )
|
||||
{
|
||||
m_bAlphaToDistance = iValue ? true : false;
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "distancespread" ) )
|
||||
{
|
||||
m_flDistanceSpread = atof(pKeyValue);
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "pfmscale" ) )
|
||||
{
|
||||
m_pfmscale=atof(pKeyValue);
|
||||
VTexMsg( "pfmscale = %.2f\n", m_pfmscale );
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "pfm" ) )
|
||||
{
|
||||
if ( iValue )
|
||||
g_eMode = BITMAP_FILE_TYPE_PFM;
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "specvar" ) )
|
||||
{
|
||||
int iDecayChannel = -1;
|
||||
|
||||
if ( !Q_stricmp( pKeyValue, "red" ) || !Q_stricmp( pKeyValue, "r" ) )
|
||||
iDecayChannel = 0;
|
||||
if ( !Q_stricmp( pKeyValue, "green" ) || !Q_stricmp( pKeyValue, "g" ) )
|
||||
iDecayChannel = 1;
|
||||
if ( !Q_stricmp( pKeyValue, "blue" ) || !Q_stricmp( pKeyValue, "b" ) )
|
||||
iDecayChannel = 2;
|
||||
if ( !Q_stricmp( pKeyValue, "alpha" ) || !Q_stricmp( pKeyValue, "a" ) )
|
||||
iDecayChannel = 3;
|
||||
|
||||
if ( iDecayChannel >= 0 && iDecayChannel < 4 )
|
||||
{
|
||||
m_vtfProcOptions.flags0 |= ( VtfProcessingOptions::OPT_DECAY_R | VtfProcessingOptions::OPT_DECAY_EXP_R ) << iDecayChannel;
|
||||
m_vtfProcOptions.numNotDecayMips[iDecayChannel] = 0;
|
||||
m_vtfProcOptions.clrDecayGoal[iDecayChannel] = 0;
|
||||
m_vtfProcOptions.fDecayExponentBase[iDecayChannel] = 0.75;
|
||||
m_bManualMip = false;
|
||||
SetFlagValue( m_nFlags, TEXTUREFLAGS_ALL_MIPS, 1 );
|
||||
}
|
||||
}
|
||||
else if ( Q_stricmp( pKeyName, "manualmip" ) == 0 )
|
||||
{
|
||||
if ( ( m_nVolumeTextureDepth == 1 ) && !( m_nFlags & ( TEXTUREFLAGS_NORMAL | TEXTUREFLAGS_NOMIP ) ) )
|
||||
{
|
||||
m_bManualMip = true;
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyName, "mipblend" ) )
|
||||
{
|
||||
SetFlagValue( m_nFlags, TEXTUREFLAGS_ALL_MIPS, 1 );
|
||||
|
||||
// Possible values
|
||||
if ( !Q_stricmp( pKeyValue, "detail" ) ) // Skip 2 mips and fade to gray -> (128, 128, 128, -)
|
||||
{
|
||||
for( int ch = 0; ch < 3; ++ ch )
|
||||
{
|
||||
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_R << ch;
|
||||
// m_vtfProcOptions.flags0 &= ~(VtfProcessingOptions::OPT_DECAY_EXP_R << ch);
|
||||
m_vtfProcOptions.numNotDecayMips[ch] = 2;
|
||||
m_vtfProcOptions.clrDecayGoal[ch] = 128;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if ( !Q_stricmp( pKeyValue, "additive" ) ) // Skip 2 mips and fade to black -> (0, 0, 0, -)
|
||||
{
|
||||
for( int ch = 0; ch < 3; ++ ch )
|
||||
{
|
||||
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_R << ch;
|
||||
m_vtfProcOptions.flags0 &= ~(VtfProcessingOptions::OPT_DECAY_EXP_R << ch);
|
||||
m_vtfProcOptions.numDecayMips[ch] = 2;
|
||||
m_vtfProcOptions.clrDecayGoal[ch] = 0;
|
||||
}
|
||||
}
|
||||
else if ( !Q_stricmp( pKeyValue, "alphablended" ) ) // Skip 2 mips and fade out alpha to 0
|
||||
{
|
||||
for( int ch = 3; ch < 4; ++ ch )
|
||||
{
|
||||
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_R << ch;
|
||||
m_vtfProcOptions.flags0 &= ~(VtfProcessingOptions::OPT_DECAY_EXP_R << ch);
|
||||
m_vtfProcOptions.numDecayMips[ch] = 2;
|
||||
m_vtfProcOptions.clrDecayGoal[ch] = 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
// Parse the given value:
|
||||
// skip=3:r=255:g=255:b=255:a=255 - linear decay
|
||||
// r=0e.75 - exponential decay targeting 0 with exponent base 0.75
|
||||
|
||||
int nSteps = 0; // default
|
||||
|
||||
for ( char const *szParse = pKeyValue; szParse; szParse = strchr( szParse, ':' ), szParse ? ++ szParse : 0 )
|
||||
{
|
||||
if ( char const *sz = StringAfterPrefix( szParse, "skip=" ) )
|
||||
{
|
||||
szParse = sz;
|
||||
nSteps = atoi(sz);
|
||||
}
|
||||
else if ( StringHasPrefix( szParse, "r=" ) ||
|
||||
StringHasPrefix( szParse, "g=" ) ||
|
||||
StringHasPrefix( szParse, "b=" ) ||
|
||||
StringHasPrefix( szParse, "a=" ) )
|
||||
{
|
||||
int ch = 0;
|
||||
switch ( *szParse )
|
||||
{
|
||||
case 'g': case 'G': ch = 1; break;
|
||||
case 'b': case 'B': ch = 2; break;
|
||||
case 'a': case 'A': ch = 3; break;
|
||||
}
|
||||
|
||||
szParse += 2;
|
||||
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_R << ch;
|
||||
m_vtfProcOptions.flags0 &= ~(VtfProcessingOptions::OPT_DECAY_EXP_R << ch);
|
||||
m_vtfProcOptions.numNotDecayMips[ch] = nSteps;
|
||||
m_vtfProcOptions.clrDecayGoal[ch] = atoi( szParse );
|
||||
|
||||
while ( isdigit( *szParse ) )
|
||||
++ szParse;
|
||||
|
||||
// Exponential decay
|
||||
if ( ( *szParse == 'e' || *szParse == 'E' ) && ( szParse[1] == '.' ) )
|
||||
{
|
||||
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_EXP_R << ch;
|
||||
m_vtfProcOptions.fDecayExponentBase[ch] = ( float ) atof( szParse + 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "invalid mipblend setting \"%s\"\n", pKeyValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( !Q_stricmp( pKeyName, "srgb" ) )
|
||||
{
|
||||
// Do nothing for now...this will be removed shortly
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
const char *CImportTex::GetPossiblyQuotedWord( const char *pInBuf, char *pOutbuf )
|
||||
{
|
||||
pInBuf += strspn( pInBuf, " \t" ); // skip whitespace
|
||||
|
||||
const char *pWordEnd;
|
||||
bool bQuote = false;
|
||||
if (pInBuf[0]=='"')
|
||||
{
|
||||
pInBuf++;
|
||||
pWordEnd=strchr(pInBuf,'"');
|
||||
bQuote = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWordEnd=strchr(pInBuf,' ');
|
||||
if (! pWordEnd )
|
||||
pWordEnd = strchr(pInBuf,'\t' );
|
||||
if (! pWordEnd )
|
||||
pWordEnd = pInBuf+strlen(pInBuf);
|
||||
}
|
||||
if ((! pWordEnd ) || (pWordEnd == pInBuf ) )
|
||||
return NULL; // no word found
|
||||
memcpy( pOutbuf, pInBuf, pWordEnd-pInBuf );
|
||||
pOutbuf[pWordEnd-pInBuf]=0;
|
||||
|
||||
pInBuf = pWordEnd;
|
||||
if ( bQuote )
|
||||
pInBuf++;
|
||||
return pInBuf;
|
||||
}
|
||||
|
||||
// GetKeyValueFromBuffer:
|
||||
// fills in "key" and "val" respectively and returns "true" if succeeds.
|
||||
// returns false if:
|
||||
// a) end-of-buffer is reached (then "val" is empty)
|
||||
// b) error occurs (then "val" is the error message)
|
||||
//
|
||||
bool CImportTex::GetKeyValueFromBuffer( CUtlBuffer &buffer, char *key, char *val )
|
||||
{
|
||||
char buf[2048];
|
||||
|
||||
while( buffer.GetBytesRemaining() )
|
||||
{
|
||||
buffer.GetLine( buf, sizeof( buf ) );
|
||||
|
||||
// Scanning algorithm
|
||||
char *pComment = strpbrk( buf, "#\n\r" );
|
||||
if ( pComment )
|
||||
*pComment = 0;
|
||||
|
||||
pComment = strstr( buf, "//" );
|
||||
if ( pComment)
|
||||
*pComment = 0;
|
||||
|
||||
const char *scan = buf;
|
||||
scan=GetPossiblyQuotedWord( scan, key );
|
||||
if ( scan )
|
||||
{
|
||||
scan=GetPossiblyQuotedWord( scan, val );
|
||||
if ( scan )
|
||||
return true;
|
||||
else
|
||||
{
|
||||
sprintf( val, "parameter %s has no value", key );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val[0] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main entry point for the unserialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportTex::Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, const char *pSourceFormatName,
|
||||
int nSourceFormatVersion, DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot )
|
||||
{
|
||||
*ppRoot = NULL;
|
||||
|
||||
m_bNoNice = m_bAlphatestMipmapping = false;
|
||||
m_flAlphatestMipmapThreshhold = m_flAlphatestMipmapHiFreqThreshhold = 0.0f;
|
||||
|
||||
CDmElement *pTexture = CreateElement< CDmElement >( "DmePrecompiledTexture", "root", DMFILEID_INVALID );
|
||||
pTexture->SetValue( "imageFileName", "__unspecified_texture" );
|
||||
|
||||
char pKey[2048];
|
||||
char pVal[2048];
|
||||
while( GetKeyValueFromBuffer( buf, pKey, pVal ) )
|
||||
{
|
||||
ParseOptionKey( pKey, pVal, pTexture );
|
||||
}
|
||||
|
||||
if ( pVal[0] )
|
||||
{
|
||||
Warning( "Error importing txt file! %s\n", pVal );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prefer to do mipmapping as one of the final processors
|
||||
if ( !pTexture->GetValue< bool >( "noMip" ) || !pTexture->GetValue< bool >( "noLod" ) )
|
||||
{
|
||||
CDmElement *pProcessor = AddProcessor( pTexture, "DmeTP_ComputeMipmaps", "computeMipmaps" );
|
||||
pProcessor->SetValue( "noNiceFiltering", m_bNoNice );
|
||||
pProcessor->SetValue( "alphaTestDownsampling", m_bAlphatestMipmapping );
|
||||
pProcessor->SetValue( "alphaTestDownsampleThreshhold", m_flAlphatestMipmapThreshhold );
|
||||
pProcessor->SetValue( "alphaTestDownsampleHiFreqThreshhold" , m_flAlphatestMipmapHiFreqThreshhold );
|
||||
}
|
||||
|
||||
*ppRoot = pTexture;
|
||||
bool bOk = g_pDataModel->UpdateUnserializedElements( pSourceFormatName, nSourceFormatVersion, fileid, idConflictResolution, ppRoot );
|
||||
if ( !bOk )
|
||||
{
|
||||
*ppRoot = NULL;
|
||||
}
|
||||
return bOk;
|
||||
}
|
||||
|
||||
|
||||
|
||||
620
dmserializers/importvmf.cpp
Normal file
620
dmserializers/importvmf.cpp
Normal file
@@ -0,0 +1,620 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "importkeyvaluebase.h"
|
||||
#include "dmserializers.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/UtlBuffer.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Serialization class for VMF files (map files)
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportVMF : public CImportKeyValueBase
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const { return "vmf"; }
|
||||
virtual const char *GetDescription() const { return "Valve Map File"; }
|
||||
virtual int GetCurrentVersion() const { return 0; } // doesn't store a version
|
||||
virtual const char *GetImportedFormat() const { return "vmf"; }
|
||||
virtual int GetImportedVersion() const { return 1; }
|
||||
|
||||
bool Serialize( CUtlBuffer &outBuf, CDmElement *pRoot );
|
||||
CDmElement* UnserializeFromKeyValues( KeyValues *pKeyValues );
|
||||
|
||||
private:
|
||||
// Reads a single entity
|
||||
bool UnserializeEntityKey( CDmAttribute *pEntities, KeyValues *pKeyValues );
|
||||
|
||||
// Reads entity editor keys
|
||||
bool UnserializeEntityEditorKey( CDmAttribute *pEditor, KeyValues *pKeyValues );
|
||||
|
||||
// Reads keys that we currently do nothing with
|
||||
bool UnserializeUnusedKeys( DmElementHandle_t hOther, KeyValues *pKeyValues );
|
||||
|
||||
// Writes out all everything other than entities
|
||||
bool SerializeOther( CUtlBuffer &buf, CDmAttribute *pOther, const char **ppFilter = 0 );
|
||||
|
||||
// Writes out all entities
|
||||
bool SerializeEntities( CUtlBuffer &buf, CDmAttribute *pEntities );
|
||||
|
||||
// Writes out a single attribute recursively
|
||||
bool SerializeAttribute( CUtlBuffer &buf, CDmAttribute *pAttribute, bool bElementArrays );
|
||||
|
||||
// Writes entity editor keys
|
||||
bool SerializeEntityEditorKey( CUtlBuffer &buf, DmElementHandle_t hEditor );
|
||||
|
||||
// Updates the max hammer id
|
||||
void UpdateMaxHammerId( KeyValues *pKeyValue );
|
||||
|
||||
// Max id read from the file
|
||||
int m_nMaxHammerId;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportVMF s_ImportVMF;
|
||||
|
||||
void InstallVMFImporter( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddSerializer( &s_ImportVMF );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets remap name for unserialization/serialization
|
||||
//-----------------------------------------------------------------------------
|
||||
static const char *GetRemapName( const char *pName, bool bSerialization )
|
||||
{
|
||||
const char *pKeyValuesFieldName = "name";
|
||||
const char *pDmeAttributeName = "__name";
|
||||
if ( !Q_stricmp( pName, bSerialization ? pDmeAttributeName : pKeyValuesFieldName ) )
|
||||
return bSerialization ? pKeyValuesFieldName : pDmeAttributeName;
|
||||
return pName;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out a single attribute recursively
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMF::SerializeAttribute( CUtlBuffer &buf, CDmAttribute *pAttribute, bool bElementArrays )
|
||||
{
|
||||
if ( pAttribute->IsStandard() || pAttribute->IsFlagSet( FATTRIB_DONTSAVE ) )
|
||||
return true;
|
||||
|
||||
const char *pFieldName = GetRemapName( pAttribute->GetName(), true );
|
||||
if ( !Q_stricmp( pFieldName, "editorType" ) )
|
||||
return true;
|
||||
|
||||
if ( !IsArrayType( pAttribute->GetType() ) )
|
||||
{
|
||||
if ( !bElementArrays )
|
||||
{
|
||||
buf.Printf( "\"%s\" ", pFieldName );
|
||||
if ( pAttribute->GetType() != AT_STRING )
|
||||
{
|
||||
buf.Printf( "\"" );
|
||||
}
|
||||
g_pDataModel->SetSerializationDelimiter( GetCStringCharConversion() );
|
||||
pAttribute->Serialize( buf );
|
||||
g_pDataModel->SetSerializationDelimiter( NULL );
|
||||
if ( pAttribute->GetType() != AT_STRING )
|
||||
{
|
||||
buf.Printf( "\"" );
|
||||
}
|
||||
buf.Printf( "\n" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bElementArrays )
|
||||
{
|
||||
Assert( pAttribute->GetType() == AT_ELEMENT_ARRAY );
|
||||
if ( !SerializeOther( buf, pAttribute ) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out all everything other than entities
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMF::SerializeOther( CUtlBuffer &buf, CDmAttribute *pOther, const char **ppFilter )
|
||||
{
|
||||
CUtlVectorFixedGrowable< char, 256 > temp;
|
||||
|
||||
CDmrElementArray<> array( pOther );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pElement = array[i];
|
||||
const char *pElementName = pElement->GetName();
|
||||
if ( ppFilter )
|
||||
{
|
||||
int j;
|
||||
for ( j = 0; ppFilter[j]; ++j )
|
||||
{
|
||||
if ( !Q_stricmp( pElementName, ppFilter[j] ) )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !ppFilter[j] )
|
||||
continue;
|
||||
}
|
||||
|
||||
int nLen = Q_strlen( pElementName ) + 1;
|
||||
temp.EnsureCount( nLen );
|
||||
Q_strncpy( temp.Base(), pElementName, nLen );
|
||||
Q_strlower( temp.Base() );
|
||||
buf.Printf( "%s\n", temp.Base() );
|
||||
buf.Printf( "{\n" );
|
||||
buf.PushTab();
|
||||
|
||||
// Normal attributes first
|
||||
for( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( !SerializeAttribute( buf, pAttribute, false ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Subkeys later
|
||||
for( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( !SerializeAttribute( buf, pAttribute, true ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
buf.PopTab();
|
||||
buf.Printf( "}\n" );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes entity editor keys
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMF::SerializeEntityEditorKey( CUtlBuffer &buf, DmElementHandle_t hEditor )
|
||||
{
|
||||
CDmElement *pEditorElement = g_pDataModel->GetElement( hEditor );
|
||||
if ( !pEditorElement )
|
||||
return true;
|
||||
|
||||
buf.Printf( "editor\n" );
|
||||
buf.Printf( "{\n" );
|
||||
buf.PushTab();
|
||||
|
||||
CDmAttribute *pAttribute = pEditorElement->GetAttribute( "color" );
|
||||
if ( pAttribute )
|
||||
{
|
||||
Color c = pAttribute->GetValue<Color>( );
|
||||
buf.Printf( "\"color\" \"%d %d %d\"\n", c.r(), c.g(), c.b() );
|
||||
}
|
||||
|
||||
PrintIntAttribute( pEditorElement, buf, "id" );
|
||||
PrintStringAttribute( pEditorElement, buf, "comments" );
|
||||
PrintBoolAttribute( pEditorElement, buf, "visgroupshown" );
|
||||
PrintBoolAttribute( pEditorElement, buf, "visgroupautoshown" );
|
||||
|
||||
for ( CDmAttribute *pAttribute = pEditorElement->FirstAttribute(); pAttribute != NULL; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
if ( pAttribute->IsStandard() || pAttribute->IsFlagSet( FATTRIB_DONTSAVE ) )
|
||||
continue;
|
||||
|
||||
const char *pKeyName = pAttribute->GetName();
|
||||
if ( Q_stricmp( pKeyName, "color" ) && Q_stricmp( pKeyName, "id" ) &&
|
||||
Q_stricmp( pKeyName, "comments" ) && Q_stricmp( pKeyName, "visgroupshown" ) &&
|
||||
Q_stricmp( pKeyName, "visgroupautoshown" ) )
|
||||
{
|
||||
PrintStringAttribute( pEditorElement, buf, pKeyName );
|
||||
}
|
||||
}
|
||||
|
||||
buf.PopTab();
|
||||
buf.Printf( "}\n" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out all entities
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMF::SerializeEntities( CUtlBuffer &buf, CDmAttribute *pEntities )
|
||||
{
|
||||
// FIXME: Make this serialize in the order in which it appears in the FGD
|
||||
// to minimize diffs
|
||||
CDmrElementArray<> array( pEntities );
|
||||
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pElement = array[i];
|
||||
buf.Printf( "entity\n" );
|
||||
buf.Printf( "{\n" );
|
||||
buf.PushTab();
|
||||
buf.Printf( "\"id\" \"%s\"\n", pElement->GetName() );
|
||||
|
||||
for( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
// Do 'editor' at the end to preserve ordering and not make terrible diffs
|
||||
if ( !Q_stricmp( pAttribute->GetName(), "editor" ) )
|
||||
continue;
|
||||
|
||||
if ( !SerializeAttribute( buf, pAttribute, false ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
for( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
// Do 'editor' at the end to preserve ordering and not make terrible diffs
|
||||
if ( !Q_stricmp( pAttribute->GetName(), "editor" ) )
|
||||
continue;
|
||||
|
||||
if ( !SerializeAttribute( buf, pAttribute, true ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do the 'editor'
|
||||
CDmAttribute *pEditor = pElement->GetAttribute( "editor" );
|
||||
if ( pEditor )
|
||||
{
|
||||
SerializeEntityEditorKey( buf, pEditor->GetValue<DmElementHandle_t>() );
|
||||
}
|
||||
|
||||
buf.PopTab();
|
||||
buf.Printf( "}\n" );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out a new VMF file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMF::Serialize( CUtlBuffer &buf, CDmElement *pRoot )
|
||||
{
|
||||
// This is done in this strange way (namely, serializing other twice) to minimize diffs
|
||||
const char *pOtherFilter1[] =
|
||||
{
|
||||
"versioninfo", "visgroups", "viewsettings", "world", NULL
|
||||
};
|
||||
|
||||
const char *pOtherFilter2[] =
|
||||
{
|
||||
"cameras", "cordon", "hidden", NULL
|
||||
};
|
||||
|
||||
CDmAttribute *pOther = pRoot->GetAttribute( "other" );
|
||||
if ( pOther && pOther->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
if ( !SerializeOther( buf, pOther, pOtherFilter1 ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Serialize entities
|
||||
CDmAttribute *pEntities = pRoot->GetAttribute( "entities" );
|
||||
if ( pEntities && pEntities->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
if ( !SerializeEntities( buf, pEntities ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( pOther && pOther->GetType() == AT_ELEMENT_ARRAY )
|
||||
{
|
||||
if ( !SerializeOther( buf, pOther, pOtherFilter2 ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Updates the max hammer id
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportVMF::UpdateMaxHammerId( KeyValues *pField )
|
||||
{
|
||||
if ( !Q_stricmp( pField->GetName(), "id" ) )
|
||||
{
|
||||
int nId = atoi( pField->GetString() );
|
||||
if ( nId > m_nMaxHammerId )
|
||||
{
|
||||
m_nMaxHammerId = nId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads entity editor keys
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMF::UnserializeEntityEditorKey( CDmAttribute *pEditorAttribute, KeyValues *pKeyValues )
|
||||
{
|
||||
CDmElement *pEditor;
|
||||
DmElementHandle_t hEditor = pEditorAttribute->GetValue<DmElementHandle_t>();
|
||||
if ( hEditor == DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
pEditor = CreateDmElement( "DmElement", "editor", NULL );;
|
||||
if ( !pEditor )
|
||||
return false;
|
||||
hEditor = pEditor->GetHandle();
|
||||
pEditorAttribute->SetValue( hEditor );
|
||||
}
|
||||
else
|
||||
{
|
||||
pEditor = g_pDataModel->GetElement( hEditor );
|
||||
}
|
||||
|
||||
int r, g, b;
|
||||
if ( sscanf( pKeyValues->GetString( "color", "" ), "%d %d %d", &r, &g, &b ) == 3 )
|
||||
{
|
||||
Color c( r, g, b, 255 );
|
||||
if ( !pEditor->SetValue( "color", c ) )
|
||||
return false;
|
||||
}
|
||||
KeyValues *pIdKey = pKeyValues->FindKey( "id" );
|
||||
if ( pIdKey )
|
||||
{
|
||||
UpdateMaxHammerId( pIdKey );
|
||||
}
|
||||
AddIntAttribute( pEditor, pKeyValues, "id" );
|
||||
AddStringAttribute( pEditor, pKeyValues, "comments" );
|
||||
AddBoolAttribute( pEditor, pKeyValues, "visgroupshown" );
|
||||
AddBoolAttribute( pEditor, pKeyValues, "visgroupautoshown" );
|
||||
|
||||
for ( KeyValues *pUserKey = pKeyValues->GetFirstValue(); pUserKey != NULL; pUserKey = pUserKey->GetNextValue() )
|
||||
{
|
||||
const char *pKeyName = pUserKey->GetName();
|
||||
if ( Q_stricmp( pKeyName, "color" ) && Q_stricmp( pKeyName, "id" ) &&
|
||||
Q_stricmp( pKeyName, "comments" ) && Q_stricmp( pKeyName, "visgroupshown" ) &&
|
||||
Q_stricmp( pKeyName, "visgroupautoshown" ) )
|
||||
{
|
||||
AddStringAttribute( pEditor, pKeyValues, pKeyName );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads a single entity
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMF::UnserializeEntityKey( CDmAttribute *pEntities, KeyValues *pKeyValues )
|
||||
{
|
||||
CDmElement *pEntity = CreateDmElement( "DmeVMFEntity", pKeyValues->GetString( "id", "-1" ), NULL );
|
||||
if ( !pEntity )
|
||||
return false;
|
||||
|
||||
CDmrElementArray<> array( pEntities );
|
||||
array.AddToTail( pEntity );
|
||||
|
||||
// Each act busy needs to have an editortype associated with it so it displays nicely in editors
|
||||
pEntity->SetValue( "editorType", "vmfEntity" );
|
||||
|
||||
const char *pClassName = pKeyValues->GetString( "classname", NULL );
|
||||
if ( !pClassName )
|
||||
return false;
|
||||
|
||||
// Read the actual fields
|
||||
for ( KeyValues *pField = pKeyValues->GetFirstValue(); pField != NULL; pField = pField->GetNextValue() )
|
||||
{
|
||||
// FIXME: Knowing the FGD here would be useful for type determination.
|
||||
// Look up the field by name based on class name
|
||||
// In the meantime, just use the keyvalues type?
|
||||
char pFieldName[512];
|
||||
Q_strncpy( pFieldName, pField->GetName(), sizeof(pFieldName) );
|
||||
Q_strlower( pFieldName );
|
||||
|
||||
// Don't do id: it's used as the name
|
||||
// Not to mention it's a protected name
|
||||
if ( !Q_stricmp( pFieldName, "id" ) )
|
||||
{
|
||||
UpdateMaxHammerId( pField );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Type, name, and editortype are protected names
|
||||
Assert( Q_stricmp( pFieldName, "type" ) && Q_stricmp( pFieldName, "name" ) && Q_stricmp( pFieldName, "editortype" ) );
|
||||
|
||||
switch( pField->GetDataType() )
|
||||
{
|
||||
case KeyValues::TYPE_INT:
|
||||
if ( !AddIntAttributeFlags( pEntity, pKeyValues, pFieldName, FATTRIB_USERDEFINED ) )
|
||||
return false;
|
||||
break;
|
||||
|
||||
case KeyValues::TYPE_FLOAT:
|
||||
if ( !AddFloatAttributeFlags( pEntity, pKeyValues, pFieldName, FATTRIB_USERDEFINED ) )
|
||||
return false;
|
||||
break;
|
||||
|
||||
case KeyValues::TYPE_STRING:
|
||||
{
|
||||
const char* pString = pField->GetString();
|
||||
if (!pString || !pString[0])
|
||||
return false;
|
||||
|
||||
// Look for vectors
|
||||
Vector4D v;
|
||||
if ( sscanf( pString, "%f %f %f %f", &v.x, &v.y, &v.z, &v.w ) == 4 )
|
||||
{
|
||||
if ( !pEntity->SetValue( pFieldName, v ) )
|
||||
return false;
|
||||
CDmAttribute *pAttribute = pEntity->GetAttribute( pFieldName );
|
||||
pAttribute->AddFlag( FATTRIB_USERDEFINED );
|
||||
}
|
||||
else if ( sscanf( pString, "%f %f %f", &v.x, &v.y, &v.z ) == 3 )
|
||||
{
|
||||
if ( !pEntity->SetValue( pFieldName, v.AsVector3D() ) )
|
||||
{
|
||||
QAngle ang( v.x, v.y, v.z );
|
||||
if ( !pEntity->SetValue( pFieldName, ang ) )
|
||||
return false;
|
||||
}
|
||||
CDmAttribute *pAttribute = pEntity->GetAttribute( pFieldName );
|
||||
pAttribute->AddFlag( FATTRIB_USERDEFINED );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !AddStringAttributeFlags( pEntity, pKeyValues, pFieldName, FATTRIB_USERDEFINED ) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the subkeys
|
||||
CDmAttribute *pEditor = pEntity->AddAttribute( "editor", AT_ELEMENT );
|
||||
CDmrElementArray<> otherKeys( pEntity->AddAttribute( "other", AT_ELEMENT_ARRAY ) );
|
||||
for ( KeyValues *pSubKey = pKeyValues->GetFirstTrueSubKey(); pSubKey != NULL; pSubKey = pSubKey->GetNextTrueSubKey() )
|
||||
{
|
||||
bool bOk = false;
|
||||
if ( !Q_stricmp( pSubKey->GetName(), "editor" ) )
|
||||
{
|
||||
bOk = UnserializeEntityEditorKey( pEditor, pSubKey );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't currently do anything with the other keys
|
||||
CDmElement *pOther = CreateDmElement( "DmElement", pSubKey->GetName(), NULL );
|
||||
otherKeys.AddToTail( pOther );
|
||||
bOk = UnserializeUnusedKeys( pOther->GetHandle(), pSubKey );
|
||||
}
|
||||
|
||||
if ( !bOk )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads keys that we currently do nothing with
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMF::UnserializeUnusedKeys( DmElementHandle_t hOther, KeyValues *pKeyValues )
|
||||
{
|
||||
CDmElement *pOther = g_pDataModel->GetElement( hOther );
|
||||
|
||||
// Read the actual fields
|
||||
for ( KeyValues *pField = pKeyValues->GetFirstValue(); pField != NULL; pField = pField->GetNextValue() )
|
||||
{
|
||||
UpdateMaxHammerId( pField );
|
||||
const char *pFieldName = GetRemapName( pField->GetName(), false );
|
||||
pOther->SetValue( pFieldName, pField->GetString() );
|
||||
}
|
||||
|
||||
// Read the subkeys
|
||||
CDmrElementArray<> subKeys( pOther->AddAttribute( "subkeys", AT_ELEMENT_ARRAY ) );
|
||||
for ( KeyValues *pSubKey = pKeyValues->GetFirstTrueSubKey(); pSubKey != NULL; pSubKey = pSubKey->GetNextTrueSubKey() )
|
||||
{
|
||||
CDmElement *pSubElement = CreateDmElement( "DmElement", pSubKey->GetName(), NULL );
|
||||
subKeys.AddToTail( pSubElement );
|
||||
if ( !UnserializeUnusedKeys( pSubElement->GetHandle(), pSubKey ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reads the cordon data
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMF::UnserializeCordonKey( IDmAttributeElement *pCordon, KeyValues *pKeyValues )
|
||||
{
|
||||
DmElementHandle_t hCordon = pCordon->GetValue().Get();
|
||||
if ( hCordon == DMELEMENT_HANDLE_INVALID )
|
||||
{
|
||||
hCordon = CreateDmElement( "DmElement", "cordon", NULL );
|
||||
if ( hCordon == DMELEMENT_HANDLE_INVALID )
|
||||
return false;
|
||||
pCordon->SetValue( hCordon );
|
||||
}
|
||||
|
||||
AddBoolAttribute( hCordon, pKeyValues, "active" );
|
||||
|
||||
Vector v;
|
||||
if ( sscanf( pKeyValues->GetString( "mins", "" ), "(%f %f %f)", &v.x, &v.y, &v.z ) == 3 )
|
||||
{
|
||||
if ( !DmElementAddAttribute( hCordon, "mins", v ) )
|
||||
return false;
|
||||
}
|
||||
if ( sscanf( pKeyValues->GetString( "maxs", "" ), "(%f %f %f)", &v.x, &v.y, &v.z ) == 3 )
|
||||
{
|
||||
if ( !DmElementAddAttribute( hCordon, "maxs", v ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main entry point for the unserialization
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement* CImportVMF::UnserializeFromKeyValues( KeyValues *pKeyValues )
|
||||
{
|
||||
m_nMaxHammerId = 0;
|
||||
|
||||
// Create the main element
|
||||
CDmElement *pElement = CreateDmElement( "DmElement", "VMF", NULL );
|
||||
if ( !pElement )
|
||||
return NULL;
|
||||
|
||||
// Each vmf needs to have an editortype associated with it so it displays nicely in editors
|
||||
pElement->SetValue( "editorType", "VMF" );
|
||||
|
||||
// The VMF is a series of keyvalue blocks; either
|
||||
// 'entity', 'cameras', 'cordon', 'world', 'versioninfo', or 'viewsettings'
|
||||
CDmAttribute *pEntityArray = pElement->AddAttribute( "entities", AT_ELEMENT_ARRAY );
|
||||
|
||||
// All main keys are root keys
|
||||
CDmrElementArray<> otherKeys( pElement->AddAttribute( "other", AT_ELEMENT_ARRAY ) );
|
||||
for ( ; pKeyValues != NULL; pKeyValues = pKeyValues->GetNextKey() )
|
||||
{
|
||||
bool bOk = false;
|
||||
if ( !Q_stricmp( pKeyValues->GetName(), "entity" ) )
|
||||
{
|
||||
bOk = UnserializeEntityKey( pEntityArray, pKeyValues );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't currently do anything with
|
||||
CDmElement *pOther = CreateDmElement( "DmElement", pKeyValues->GetName(), NULL );
|
||||
otherKeys.AddToTail( pOther );
|
||||
bOk = UnserializeUnusedKeys( pOther->GetHandle(), pKeyValues );
|
||||
}
|
||||
|
||||
if ( !bOk )
|
||||
{
|
||||
Warning( "Error importing VMF element %s\n", pKeyValues->GetName() );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve all element references recursively
|
||||
RecursivelyResolveElement( pElement );
|
||||
|
||||
// Add the max id read in from the file to the root entity
|
||||
pElement->SetValue( "maxHammerId", m_nMaxHammerId );
|
||||
|
||||
return pElement;
|
||||
}
|
||||
745
dmserializers/importvmt.cpp
Normal file
745
dmserializers/importvmt.cpp
Normal file
@@ -0,0 +1,745 @@
|
||||
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "importkeyvaluebase.h"
|
||||
#include "dmserializers.h"
|
||||
#include "datamodel/idatamodel.h"
|
||||
#include "datamodel/dmelement.h"
|
||||
#include "datamodel/dmattributevar.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "tier1/UtlBuffer.h"
|
||||
#include "datamodel/dmattribute.h"
|
||||
#include "filesystem.h"
|
||||
#include "tier2/tier2.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Serialization class for Key Values
|
||||
//-----------------------------------------------------------------------------
|
||||
class CImportVMT : public CImportKeyValueBase
|
||||
{
|
||||
public:
|
||||
virtual const char *GetName() const { return "vmt"; }
|
||||
virtual const char *GetDescription() const { return "Valve Material File"; }
|
||||
virtual int GetCurrentVersion() const { return 0; } // doesn't store a version
|
||||
virtual const char *GetImportedFormat() const { return "vmt"; }
|
||||
virtual int GetImportedVersion() const { return 1; }
|
||||
|
||||
bool Serialize( CUtlBuffer &outBuf, CDmElement *pRoot );
|
||||
CDmElement* UnserializeFromKeyValues( KeyValues *pKeyValues );
|
||||
|
||||
private:
|
||||
// Unserialize fallbacks
|
||||
bool UnserializeFallbacks( CDmElement *pRoot, KeyValues *pFallbackKeyValues );
|
||||
|
||||
// Unserialize proxies
|
||||
bool UnserializeProxies( CDmElement *pRoot, KeyValues *pKeyValues );
|
||||
|
||||
// Creates a shader parameter from a key value
|
||||
bool UnserializeShaderParam( CDmElement *pRoot, KeyValues* pKeyValue );
|
||||
|
||||
// Creates a matrix material var
|
||||
bool CreateMatrixMaterialVarFromKeyValue( CDmElement *pRoot, const char *pParamName, const char *pString );
|
||||
|
||||
// Creates a vector shader parameter
|
||||
bool CreateVectorMaterialVarFromKeyValue( CDmElement *pRoot, const char *pParamName, const char *pString );
|
||||
|
||||
// Writes out a single shader parameter
|
||||
bool SerializeShaderParameter( CUtlBuffer &buf, CDmAttribute *pAttribute );
|
||||
|
||||
// Writes out all shader parameters
|
||||
bool SerializeShaderParameters( CUtlBuffer &buf, CDmElement *pRoot );
|
||||
|
||||
// Writes out all shader fallbacks
|
||||
bool SerializeFallbacks( CUtlBuffer &buf, CDmElement *pRoot );
|
||||
|
||||
// Writes out all material proxies
|
||||
bool SerializeProxies( CUtlBuffer &buf, CDmElement *pRoot );
|
||||
|
||||
// Handle patch files
|
||||
void ExpandPatchFile( KeyValues *pKeyValues );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Singleton instance
|
||||
//-----------------------------------------------------------------------------
|
||||
static CImportVMT s_ImportVMT;
|
||||
|
||||
void InstallVMTImporter( IDataModel *pFactory )
|
||||
{
|
||||
pFactory->AddSerializer( &s_ImportVMT );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out a single shader parameter
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::SerializeShaderParameter( CUtlBuffer &buf, CDmAttribute *pAttribute )
|
||||
{
|
||||
// We have a shader parameter at this point.
|
||||
switch ( pAttribute->GetType() )
|
||||
{
|
||||
case AT_INT:
|
||||
buf.Printf( "\"%s\" \"%d\"\n", pAttribute->GetName(), pAttribute->GetValue<int>( ) );
|
||||
break;
|
||||
|
||||
case AT_BOOL:
|
||||
buf.Printf( "\"%s\" \"%d\"\n", pAttribute->GetName(), pAttribute->GetValue<bool>( ) );
|
||||
break;
|
||||
|
||||
case AT_FLOAT:
|
||||
buf.Printf( "\"%s\" \"%f\"\n", pAttribute->GetName(), pAttribute->GetValue<float>( ) );
|
||||
break;
|
||||
|
||||
case AT_STRING:
|
||||
{
|
||||
CUtlSymbolLarge symbol = pAttribute->GetValue<CUtlSymbolLarge>();
|
||||
const char *pString = symbol.String();
|
||||
buf.Printf( "\"%s\" \"%s\"\n", pAttribute->GetName(), pString );
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_VECTOR2:
|
||||
{
|
||||
const Vector2D &vec = pAttribute->GetValue<Vector2D>( );
|
||||
buf.Printf( "\"%s\" \"[ %f %f ]\"\n", pAttribute->GetName(), vec.x, vec.y );
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_VECTOR3:
|
||||
{
|
||||
const Vector &vec = pAttribute->GetValue<Vector>( );
|
||||
buf.Printf( "\"%s\" \"[ %f %f %f ]\"\n", pAttribute->GetName(), vec.x, vec.y, vec.z );
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_VECTOR4:
|
||||
{
|
||||
const Vector4D &vec = pAttribute->GetValue<Vector4D>( );
|
||||
buf.Printf( "\"%s\" \"[ %f %f %f %f ]\"\n", pAttribute->GetName(), vec.x, vec.y, vec.z, vec.w );
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_COLOR:
|
||||
{
|
||||
// NOTE: VMTs only support 3 component color (no alpha)
|
||||
const Color &color = pAttribute->GetValue<Color>( );
|
||||
buf.Printf( "\"%s\" \"{ %d %d %d }\"\n", pAttribute->GetName(), color.r(), color.g(), color.b() );
|
||||
}
|
||||
break;
|
||||
|
||||
case AT_VMATRIX:
|
||||
{
|
||||
const VMatrix &mat = pAttribute->GetValue<VMatrix>( );
|
||||
buf.Printf( "\"%s\" \"[ %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f ]\"\n", pAttribute->GetName(),
|
||||
mat[0][0], mat[0][1], mat[0][2], mat[0][3],
|
||||
mat[1][0], mat[1][1], mat[1][2], mat[1][3],
|
||||
mat[2][0], mat[2][1], mat[2][2], mat[2][3],
|
||||
mat[3][0], mat[3][1], mat[3][2], mat[3][3] );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Warning( "Attempted to serialize an unsupported shader parameter type %s (%s)\n",
|
||||
pAttribute->GetName(), g_pDataModel->GetAttributeNameForType( pAttribute->GetType() ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out all shader parameters
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::SerializeShaderParameters( CUtlBuffer &buf, CDmElement *pRoot )
|
||||
{
|
||||
for ( CDmAttribute *pAttribute = pRoot->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
||||
{
|
||||
// Skip the standard attributes
|
||||
if ( pAttribute->IsStandard() )
|
||||
continue;
|
||||
|
||||
// Skip the shader name
|
||||
const char *pName = pAttribute->GetName();
|
||||
if ( !Q_stricmp( pAttribute->GetName(), "shader" ) )
|
||||
continue;
|
||||
|
||||
// Names that don't start with a $ or a % are not shader parameters
|
||||
if ( pName[0] != '$' && pName[0] != '%' )
|
||||
continue;
|
||||
|
||||
// Skip element array children; we'll handle them separately.
|
||||
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
||||
continue;
|
||||
|
||||
// Write out the shader parameter
|
||||
if ( !SerializeShaderParameter( buf, pAttribute ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out all shader fallbacks
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::SerializeFallbacks( CUtlBuffer &buf, CDmElement *pRoot )
|
||||
{
|
||||
if ( !pRoot->HasAttribute( "fallbacks" ) )
|
||||
return true;
|
||||
|
||||
CDmAttribute *pFallbacks = pRoot->GetAttribute( "fallbacks" );
|
||||
if ( pFallbacks->GetType() != AT_ELEMENT_ARRAY )
|
||||
return false;
|
||||
|
||||
CDmrElementArray<> array( pFallbacks );
|
||||
int nCount = array.Count();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pFallback = array[i];
|
||||
Assert( pFallback );
|
||||
|
||||
PrintStringAttribute( pFallback, buf, "shader", false, true );
|
||||
buf.Printf( "{\n" );
|
||||
buf.PushTab();
|
||||
if ( !SerializeShaderParameters( buf, pFallback ) )
|
||||
return false;
|
||||
buf.PopTab();
|
||||
buf.Printf( "}\n" );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out all material proxies
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::SerializeProxies( CUtlBuffer &buf, CDmElement *pRoot )
|
||||
{
|
||||
if ( !pRoot->HasAttribute( "proxies" ) )
|
||||
return true;
|
||||
|
||||
CDmAttribute *pProxies = pRoot->GetAttribute( "proxies" );
|
||||
if ( pProxies->GetType() != AT_ELEMENT_ARRAY )
|
||||
return false;
|
||||
|
||||
CDmrElementArray<> array( pProxies );
|
||||
int nCount = array.Count();
|
||||
if ( nCount == 0 )
|
||||
return true;
|
||||
|
||||
buf.Printf( "\"Proxies\"\n" );
|
||||
buf.Printf( "{\n" );
|
||||
buf.PushTab();
|
||||
for ( int i = 0; i < nCount; ++i )
|
||||
{
|
||||
CDmElement *pProxy = array[i];
|
||||
Assert( pProxy );
|
||||
|
||||
PrintStringAttribute( pProxy, buf, "proxyType", false, true );
|
||||
buf.Printf( "{\n" );
|
||||
buf.PushTab();
|
||||
if ( !SerializeShaderParameters( buf, pProxy ) )
|
||||
return false;
|
||||
buf.PopTab();
|
||||
buf.Printf( "}\n" );
|
||||
}
|
||||
buf.PopTab();
|
||||
buf.Printf( "}\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Writes out a new vmt file
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::Serialize( CUtlBuffer &buf, CDmElement *pRoot )
|
||||
{
|
||||
PrintStringAttribute( pRoot, buf, "shader", false, true );
|
||||
buf.Printf( "{\n" );
|
||||
buf.PushTab();
|
||||
|
||||
if ( !SerializeShaderParameters( buf, pRoot ) )
|
||||
return false;
|
||||
|
||||
if ( !SerializeFallbacks( buf, pRoot ) )
|
||||
return false;
|
||||
|
||||
if ( !SerializeProxies( buf, pRoot ) )
|
||||
return false;
|
||||
|
||||
buf.PopTab();
|
||||
buf.Printf( "}\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Parser utilities
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline bool IsWhitespace( char c )
|
||||
{
|
||||
return c == ' ' || c == '\t';
|
||||
}
|
||||
|
||||
static inline bool IsEndline( char c )
|
||||
{
|
||||
return c == '\n' || c == '\0';
|
||||
}
|
||||
|
||||
static inline bool IsVector( char const* v )
|
||||
{
|
||||
while (IsWhitespace(*v))
|
||||
{
|
||||
++v;
|
||||
if (IsEndline(*v))
|
||||
return false;
|
||||
}
|
||||
return *v == '[' || *v == '{';
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates a vector material var
|
||||
//-----------------------------------------------------------------------------
|
||||
int ParseVectorFromKeyValueString( const char *pParamName, const char* pScan, const char *pMaterialName, float vecVal[4] )
|
||||
{
|
||||
bool divideBy255 = false;
|
||||
|
||||
// skip whitespace
|
||||
while( IsWhitespace(*pScan) )
|
||||
{
|
||||
++pScan;
|
||||
}
|
||||
|
||||
if( *pScan == '{' )
|
||||
{
|
||||
divideBy255 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( *pScan == '[' );
|
||||
}
|
||||
|
||||
// skip the '['
|
||||
++pScan;
|
||||
int i;
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
// skip whitespace
|
||||
while( IsWhitespace(*pScan) )
|
||||
{
|
||||
++pScan;
|
||||
}
|
||||
|
||||
if( IsEndline(*pScan) || *pScan == ']' || *pScan == '}' )
|
||||
{
|
||||
if (*pScan != ']' && *pScan != '}')
|
||||
{
|
||||
Warning( "Warning in .VMT file (%s): no ']' or '}' found in vector key \"%s\".\n"
|
||||
"Did you forget to surround the vector with \"s?\n", pMaterialName, pParamName );
|
||||
}
|
||||
|
||||
// allow for vec2's, etc.
|
||||
vecVal[i] = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
char* pEnd;
|
||||
|
||||
vecVal[i] = strtod( pScan, &pEnd );
|
||||
if (pScan == pEnd)
|
||||
{
|
||||
Warning( "Error in .VMT file: error parsing vector element \"%s\" in \"%s\"\n", pParamName, pMaterialName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
pScan = pEnd;
|
||||
}
|
||||
|
||||
if( divideBy255 )
|
||||
{
|
||||
vecVal[0] *= ( 1.0f / 255.0f );
|
||||
vecVal[1] *= ( 1.0f / 255.0f );
|
||||
vecVal[2] *= ( 1.0f / 255.0f );
|
||||
vecVal[3] *= ( 1.0f / 255.0f );
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets shader parameter attributes
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T >
|
||||
inline bool SetShaderParamAttribute( CDmElement *pElement, const char *pAttributeName, const T &value )
|
||||
{
|
||||
if ( !pElement )
|
||||
return false;
|
||||
|
||||
if ( !pElement->SetValue( pAttributeName, value ) )
|
||||
return false;
|
||||
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pAttributeName );
|
||||
pAttribute->AddFlag( FATTRIB_USERDEFINED );
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool SetShaderParamAttribute( CDmElement *pElement, const char *pAttributeName, const char *value )
|
||||
{
|
||||
if ( !pElement )
|
||||
return false;
|
||||
|
||||
if ( !pElement->SetValue( pAttributeName, value ) )
|
||||
return false;
|
||||
|
||||
CDmAttribute *pAttribute = pElement->GetAttribute( pAttributeName );
|
||||
pAttribute->AddFlag( FATTRIB_USERDEFINED );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates a vector shader parameter
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::CreateVectorMaterialVarFromKeyValue( CDmElement *pElement, const char *pParamName, const char *pString )
|
||||
{
|
||||
Vector4D vecVal;
|
||||
int nDim = ParseVectorFromKeyValueString( pParamName, pString, FileName(), vecVal.Base() );
|
||||
if ( nDim == 0 )
|
||||
return false;
|
||||
|
||||
// Create the variable!
|
||||
switch ( nDim )
|
||||
{
|
||||
case 1:
|
||||
return SetShaderParamAttribute( pElement, pParamName, vecVal[0] );
|
||||
case 2:
|
||||
return SetShaderParamAttribute( pElement, pParamName, vecVal.AsVector2D() );
|
||||
case 3:
|
||||
return SetShaderParamAttribute( pElement, pParamName, vecVal.AsVector3D() );
|
||||
case 4:
|
||||
return SetShaderParamAttribute( pElement, pParamName, vecVal );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates a matrix shader parameter
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::CreateMatrixMaterialVarFromKeyValue( CDmElement *pElement, const char *pParamName, const char *pScan )
|
||||
{
|
||||
// Matrices can be specified one of two ways:
|
||||
// [ # # # # # # # # # # # # # # # # ]
|
||||
// or
|
||||
// center # # scale # # rotate # translate # #
|
||||
|
||||
VMatrix mat;
|
||||
int count = sscanf( pScan, " [ %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f ]",
|
||||
&mat.m[0][0], &mat.m[0][1], &mat.m[0][2], &mat.m[0][3],
|
||||
&mat.m[1][0], &mat.m[1][1], &mat.m[1][2], &mat.m[1][3],
|
||||
&mat.m[2][0], &mat.m[2][1], &mat.m[2][2], &mat.m[2][3],
|
||||
&mat.m[3][0], &mat.m[3][1], &mat.m[3][2], &mat.m[3][3] );
|
||||
if (count == 16)
|
||||
{
|
||||
return SetShaderParamAttribute( pElement, pParamName, mat );
|
||||
}
|
||||
|
||||
Vector2D scale, center;
|
||||
float angle;
|
||||
Vector2D translation;
|
||||
count = sscanf( pScan, " center %f %f scale %f %f rotate %f translate %f %f",
|
||||
¢er.x, ¢er.y, &scale.x, &scale.y, &angle, &translation.x, &translation.y );
|
||||
if (count != 7)
|
||||
return false;
|
||||
|
||||
VMatrix temp;
|
||||
MatrixBuildTranslation( mat, -center.x, -center.y, 0.0f );
|
||||
MatrixBuildScale( temp, scale.x, scale.y, 1.0f );
|
||||
MatrixMultiply( temp, mat, mat );
|
||||
MatrixBuildRotateZ( temp, angle );
|
||||
MatrixMultiply( temp, mat, mat );
|
||||
MatrixBuildTranslation( temp, center.x + translation.x, center.y + translation.y, 0.0f );
|
||||
MatrixMultiply( temp, mat, mat );
|
||||
|
||||
// Create the variable!
|
||||
return SetShaderParamAttribute( pElement, pParamName, mat );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates a shader parameter from a key value
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::UnserializeShaderParam( CDmElement *pRoot, KeyValues* pKeyValues )
|
||||
{
|
||||
char pParamName[512];
|
||||
Q_strncpy( pParamName, pKeyValues->GetName(), sizeof(pParamName) );
|
||||
Q_strlower( pParamName );
|
||||
|
||||
switch( pKeyValues->GetDataType() )
|
||||
{
|
||||
case KeyValues::TYPE_INT:
|
||||
return SetShaderParamAttribute( pRoot, pParamName, pKeyValues->GetInt() );
|
||||
|
||||
case KeyValues::TYPE_FLOAT:
|
||||
return SetShaderParamAttribute( pRoot, pParamName, pKeyValues->GetFloat() );
|
||||
|
||||
case KeyValues::TYPE_STRING:
|
||||
{
|
||||
char const* pString = pKeyValues->GetString();
|
||||
|
||||
// Only valid if it's a texture attribute
|
||||
if ( !pString || !pString[0] )
|
||||
return SetShaderParamAttribute( pRoot, pParamName, pString );
|
||||
|
||||
// Look for matrices
|
||||
if ( CreateMatrixMaterialVarFromKeyValue( pRoot, pParamName, pString ) )
|
||||
return true;
|
||||
|
||||
// Look for vectors
|
||||
if ( !IsVector( pString ) )
|
||||
return SetShaderParamAttribute( pRoot, pParamName, pString );
|
||||
|
||||
// Parse the string as a vector...
|
||||
return CreateVectorMaterialVarFromKeyValue( pRoot, pParamName, pString );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Unserialize proxies
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::UnserializeProxies( CDmElement *pElement, KeyValues *pKeyValues )
|
||||
{
|
||||
// Create a child element array to contain all material proxies
|
||||
CDmAttribute *pProxies = pElement->AddAttribute( "proxies", AT_ELEMENT_ARRAY );
|
||||
if ( !pProxies )
|
||||
return false;
|
||||
|
||||
CDmrElementArray<> array( pProxies );
|
||||
|
||||
// Proxies are a list of sub-keys, the name is the proxy name, subkeys are values
|
||||
for ( KeyValues *pProxy = pKeyValues->GetFirstTrueSubKey(); pProxy != NULL; pProxy = pProxy->GetNextTrueSubKey() )
|
||||
{
|
||||
CDmElement *pProxyElement = CreateDmElement( "DmElement", pProxy->GetName(), NULL );
|
||||
array.AddToTail( pProxyElement );
|
||||
pProxyElement->SetValue( "proxyType", pKeyValues->GetName() );
|
||||
pProxyElement->SetValue( "editorType", "vmtProxy" );
|
||||
|
||||
// Normal keys are proxy parameters
|
||||
for ( KeyValues *pProxyParam = pProxy->GetFirstValue(); pProxyParam != NULL; pProxyParam = pProxyParam->GetNextValue() )
|
||||
{
|
||||
switch( pProxyParam->GetDataType() )
|
||||
{
|
||||
case KeyValues::TYPE_INT:
|
||||
pProxyElement->SetValue( pProxyParam->GetName(), pProxyParam->GetInt() );
|
||||
return true;
|
||||
|
||||
case KeyValues::TYPE_FLOAT:
|
||||
pProxyElement->SetValue( pProxyParam->GetName(), pProxyParam->GetFloat() );
|
||||
return true;
|
||||
|
||||
case KeyValues::TYPE_STRING:
|
||||
pProxyElement->SetValue( pProxyParam->GetName(), pProxyParam->GetString() );
|
||||
return true;
|
||||
|
||||
default:
|
||||
Warning( "Unhandled proxy keyvalues type (proxy %s var %s)\n", pProxy->GetName(), pProxyParam->GetName() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Unserialize fallbacks
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CImportVMT::UnserializeFallbacks( CDmElement *pElement, KeyValues *pFallbackKeyValues )
|
||||
{
|
||||
// Create a child element array to contain all material proxies
|
||||
CDmAttribute *pFallbacks = pElement->AddAttribute( "fallbacks", AT_ELEMENT_ARRAY );
|
||||
if ( !pFallbacks )
|
||||
return false;
|
||||
|
||||
CDmrElementArray<> array( pFallbacks );
|
||||
|
||||
CDmElement *pFallback = CreateDmElement( "DmElement", pFallbackKeyValues->GetName(), NULL );
|
||||
array.AddToTail( pFallback );
|
||||
pFallback->SetValue( "editorType", "vmtFallback" );
|
||||
|
||||
// Normal keys are shader parameters
|
||||
for ( KeyValues *pShaderParam = pFallbackKeyValues->GetFirstValue(); pShaderParam != NULL; pShaderParam = pShaderParam->GetNextValue() )
|
||||
{
|
||||
if ( !UnserializeShaderParam( pFallback, pShaderParam ) )
|
||||
{
|
||||
Warning( "Error importing vmt shader parameter %s\n", pShaderParam->GetName() );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// VMT parser
|
||||
//-----------------------------------------------------------------------------
|
||||
void InsertKeyValues( KeyValues& dst, KeyValues& src, bool bCheckForExistence )
|
||||
{
|
||||
KeyValues *pSrcVar = src.GetFirstSubKey();
|
||||
while( pSrcVar )
|
||||
{
|
||||
if ( !bCheckForExistence || dst.FindKey( pSrcVar->GetName() ) )
|
||||
{
|
||||
switch( pSrcVar->GetDataType() )
|
||||
{
|
||||
case KeyValues::TYPE_STRING:
|
||||
dst.SetString( pSrcVar->GetName(), pSrcVar->GetString() );
|
||||
break;
|
||||
case KeyValues::TYPE_INT:
|
||||
dst.SetInt( pSrcVar->GetName(), pSrcVar->GetInt() );
|
||||
break;
|
||||
case KeyValues::TYPE_FLOAT:
|
||||
dst.SetFloat( pSrcVar->GetName(), pSrcVar->GetFloat() );
|
||||
break;
|
||||
case KeyValues::TYPE_PTR:
|
||||
dst.SetPtr( pSrcVar->GetName(), pSrcVar->GetPtr() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
pSrcVar = pSrcVar->GetNextKey();
|
||||
}
|
||||
|
||||
if( bCheckForExistence )
|
||||
{
|
||||
for( KeyValues *pScan = dst.GetFirstTrueSubKey(); pScan; pScan = pScan->GetNextTrueSubKey() )
|
||||
{
|
||||
KeyValues *pTmp = src.FindKey( pScan->GetName() );
|
||||
if( !pTmp )
|
||||
continue;
|
||||
// make sure that this is a subkey.
|
||||
if( pTmp->GetDataType() != KeyValues::TYPE_NONE )
|
||||
continue;
|
||||
InsertKeyValues( *pScan, *pTmp, bCheckForExistence );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle patch files
|
||||
//-----------------------------------------------------------------------------
|
||||
void CImportVMT::ExpandPatchFile( KeyValues *pKeyValues )
|
||||
{
|
||||
int count = 0;
|
||||
while( count < 10 && stricmp( pKeyValues->GetName(), "patch" ) == 0 )
|
||||
{
|
||||
// WriteKeyValuesToFile( "patch.txt", keyValues );
|
||||
const char *pIncludeFileName = pKeyValues->GetString( "include" );
|
||||
if( pIncludeFileName )
|
||||
{
|
||||
KeyValues * includeKeyValues = new KeyValues( "vmt" );
|
||||
bool success = includeKeyValues->LoadFromFile( g_pFullFileSystem, pIncludeFileName, IsX360() ? "GAME" : NULL );
|
||||
if( success )
|
||||
{
|
||||
KeyValues *pInsertSection = pKeyValues->FindKey( "insert" );
|
||||
if( pInsertSection )
|
||||
{
|
||||
InsertKeyValues( *includeKeyValues, *pInsertSection, false );
|
||||
}
|
||||
|
||||
KeyValues *pReplaceSection = pKeyValues->FindKey( "replace" );
|
||||
if( pReplaceSection )
|
||||
{
|
||||
InsertKeyValues( *includeKeyValues, *pReplaceSection, true );
|
||||
}
|
||||
|
||||
*pKeyValues = *includeKeyValues;
|
||||
includeKeyValues->deleteThis();
|
||||
// Could add other commands here, like "delete", "rename", etc.
|
||||
}
|
||||
else
|
||||
{
|
||||
includeKeyValues->deleteThis();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if( count >= 10 )
|
||||
{
|
||||
Warning( "Infinite recursion in patch file?\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main entry point for the unserialization
|
||||
//-----------------------------------------------------------------------------
|
||||
CDmElement* CImportVMT::UnserializeFromKeyValues( KeyValues *pKeyValues )
|
||||
{
|
||||
ExpandPatchFile( pKeyValues );
|
||||
|
||||
// Create the main element
|
||||
CDmElement *pRoot = CreateDmElement( "DmElement", "VMT", NULL );
|
||||
if ( !pRoot )
|
||||
return NULL;
|
||||
|
||||
// Each material needs to have an editortype associated with it so it displays nicely in editors
|
||||
pRoot->SetValue( "editorType", "vmt" );
|
||||
|
||||
// Each material needs a proxy list and a fallback list
|
||||
if ( !pRoot->AddAttribute( "proxies", AT_ELEMENT_ARRAY ) )
|
||||
return NULL;
|
||||
if ( !pRoot->AddAttribute( "fallbacks", AT_ELEMENT_ARRAY ) )
|
||||
return NULL;
|
||||
|
||||
// The keyvalues name is the shader name
|
||||
pRoot->SetValue( "shader", pKeyValues->GetName() );
|
||||
|
||||
// Normal keys are shader parameters
|
||||
for ( KeyValues *pShaderParam = pKeyValues->GetFirstValue(); pShaderParam != NULL; pShaderParam = pShaderParam->GetNextValue() )
|
||||
{
|
||||
if ( !UnserializeShaderParam( pRoot, pShaderParam ) )
|
||||
{
|
||||
Warning( "Error importing vmt shader parameter %s\n", pShaderParam->GetName() );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Subkeys are either proxies or fallbacks
|
||||
for ( KeyValues *pSubKey = pKeyValues->GetFirstTrueSubKey(); pSubKey != NULL; pSubKey = pSubKey->GetNextTrueSubKey() )
|
||||
{
|
||||
if ( !Q_stricmp( pSubKey->GetName(), "Proxies" ) )
|
||||
{
|
||||
UnserializeProxies( pRoot, pSubKey );
|
||||
}
|
||||
else
|
||||
{
|
||||
UnserializeFallbacks( pRoot, pSubKey );
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve all element references recursively
|
||||
RecursivelyResolveElement( pRoot );
|
||||
|
||||
return pRoot;
|
||||
}
|
||||
Reference in New Issue
Block a user