2015-09-10 20:30:35 +00:00
# include "SCLY.hpp"
# include "ScriptObjects/ScriptTypes.hpp"
2016-02-13 09:02:47 +00:00
namespace DataSpec
2015-09-10 20:30:35 +00:00
{
namespace DNAMP1
{
2016-03-04 23:04:53 +00:00
void SCLY : : read ( athena : : io : : IStreamReader & rs )
2015-09-10 20:30:35 +00:00
{
fourCC = rs . readUint32Little ( ) ;
version = rs . readUint32Big ( ) ;
layerCount = rs . readUint32Big ( ) ;
rs . enumerateBig ( layerSizes , layerCount ) ;
atUint32 i = 0 ;
2016-03-04 23:04:53 +00:00
rs . enumerate < ScriptLayer > ( layers , layerCount , [ & i , this ] ( athena : : io : : IStreamReader & rs , ScriptLayer & layer ) {
2015-09-10 20:30:35 +00:00
atUint64 start = rs . position ( ) ;
layer . read ( rs ) ;
2016-03-04 23:04:53 +00:00
rs . seek ( start + layerSizes [ i + + ] , athena : : Begin ) ;
2015-09-10 20:30:35 +00:00
} ) ;
}
2016-03-04 23:04:53 +00:00
void SCLY : : write ( athena : : io : : IStreamWriter & ws ) const
2015-09-10 20:30:35 +00:00
{
ws . writeUint32Big ( fourCC ) ;
ws . writeUint32Big ( version ) ;
ws . writeUint32Big ( layerCount ) ;
ws . enumerateBig ( layerSizes ) ;
ws . enumerate ( layers ) ;
}
2015-10-18 04:08:45 +00:00
size_t SCLY : : binarySize ( size_t __isz ) const
{
__isz + = 12 ;
__isz + = layerSizes . size ( ) * 4 ;
return __EnumerateSize ( __isz , layers ) ;
}
2016-08-10 02:52:00 +00:00
void SCLY : : exportToLayerDirectories ( const PAK : : Entry & entry , PAKRouter < PAKBridge > & pakRouter , bool force ) const
2015-09-10 20:30:35 +00:00
{
for ( atUint32 i = 0 ; i < layerCount ; i + + )
{
2016-08-10 02:52:00 +00:00
bool active ;
hecl : : ProjectPath layerPath = pakRouter . getAreaLayerWorking ( entry . id , i , active ) ;
2016-09-18 23:47:48 +00:00
if ( layerPath . isNone ( ) )
2015-09-10 20:30:35 +00:00
layerPath . makeDir ( ) ;
2016-08-10 02:52:00 +00:00
if ( active )
{
hecl : : ProjectPath activePath ( layerPath , " !defaultactive " ) ;
fclose ( hecl : : Fopen ( activePath . getAbsolutePath ( ) . c_str ( ) , _S ( " wb " ) ) ) ;
}
2016-10-01 23:20:20 +00:00
hecl : : ProjectPath yamlFile ( layerPath , _S ( " !objects.yaml " ) ) ;
2016-09-18 23:47:48 +00:00
if ( force | | yamlFile . isNone ( ) )
2015-09-10 20:30:35 +00:00
{
2016-08-22 03:47:48 +00:00
athena : : io : : FileWriter writer ( yamlFile . getAbsolutePath ( ) ) ;
layers [ i ] . toYAMLStream ( writer ) ;
2015-09-10 20:30:35 +00:00
}
}
}
2015-10-27 00:19:03 +00:00
void SCLY : : addCMDLRigPairs ( PAKRouter < PAKBridge > & pakRouter ,
std : : unordered_map < UniqueID32 , std : : pair < UniqueID32 , UniqueID32 > > & addTo ) const
{
for ( const ScriptLayer & layer : layers )
layer . addCMDLRigPairs ( pakRouter , addTo ) ;
}
void SCLY : : ScriptLayer : : addCMDLRigPairs ( PAKRouter < PAKBridge > & pakRouter ,
std : : unordered_map < UniqueID32 , std : : pair < UniqueID32 , UniqueID32 > > & addTo ) const
{
2015-11-29 05:59:34 +00:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
2015-10-27 00:19:03 +00:00
obj - > addCMDLRigPairs ( pakRouter , addTo ) ;
}
void SCLY : : nameIDs ( PAKRouter < PAKBridge > & pakRouter ) const
{
for ( const ScriptLayer & layer : layers )
layer . nameIDs ( pakRouter ) ;
}
void SCLY : : ScriptLayer : : nameIDs ( PAKRouter < PAKBridge > & pakRouter ) const
{
2015-11-29 05:59:34 +00:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
2015-10-27 00:19:03 +00:00
obj - > nameIDs ( pakRouter ) ;
}
2016-03-04 23:04:53 +00:00
void SCLY : : read ( athena : : io : : YAMLDocReader & docin )
2015-09-10 20:30:35 +00:00
{
fourCC = docin . readUint32 ( " fourCC " ) ;
version = docin . readUint32 ( " version " ) ;
2016-03-04 01:01:37 +00:00
layerCount = docin . enumerate ( " layerSizes " , layerSizes ) ;
docin . enumerate ( " layers " , layers ) ;
2015-09-10 20:30:35 +00:00
}
2016-03-04 23:04:53 +00:00
void SCLY : : write ( athena : : io : : YAMLDocWriter & docout ) const
2015-09-10 20:30:35 +00:00
{
docout . writeUint32 ( " fourCC " , fourCC ) ;
docout . writeUint32 ( " version " , version ) ;
docout . enumerate ( " layerSizes " , layerSizes ) ;
docout . enumerate ( " layers " , layers ) ;
}
2015-10-01 00:46:37 +00:00
const char * SCLY : : DNAType ( )
{
2016-03-04 23:04:53 +00:00
return " urde::DNAMP1::SCLY " ;
2015-10-01 00:46:37 +00:00
}
2016-03-04 23:04:53 +00:00
void SCLY : : ScriptLayer : : read ( athena : : io : : IStreamReader & rs )
2015-09-10 20:30:35 +00:00
{
unknown = rs . readUByte ( ) ;
objectCount = rs . readUint32Big ( ) ;
2016-03-04 23:04:53 +00:00
objects . clear ( ) ;
2015-09-10 20:30:35 +00:00
objects . reserve ( objectCount ) ;
for ( atUint32 i = 0 ; i < objectCount ; i + + )
{
atUint8 type = rs . readUByte ( ) ;
atUint32 len = rs . readUint32Big ( ) ;
atUint64 start = rs . position ( ) ;
auto iter = std : : find_if ( SCRIPT_OBJECT_DB . begin ( ) , SCRIPT_OBJECT_DB . end ( ) , [ & type ] ( const ScriptObjectSpec * obj ) - > bool
{ return obj - > type = = type ; } ) ;
if ( iter ! = SCRIPT_OBJECT_DB . end ( ) )
{
2015-11-29 05:59:34 +00:00
std : : unique_ptr < IScriptObject > obj ( ( * iter ) - > a ( ) ) ;
2015-09-10 20:30:35 +00:00
obj - > type = type ;
obj - > read ( rs ) ;
2015-11-29 05:59:34 +00:00
objects . push_back ( std : : move ( obj ) ) ;
2015-10-12 09:30:18 +00:00
size_t actualLen = rs . position ( ) - start ;
if ( actualLen ! = len )
2016-03-04 23:04:53 +00:00
Log . report ( logvisor : : Fatal , _S ( " Error while reading object of type 0x%.2X, did not read the expected amount of data, read 0x%x, expected 0x%x " ) , ( atUint32 ) type , actualLen , len ) ;
rs . seek ( start + len , athena : : Begin ) ;
2015-09-10 20:30:35 +00:00
}
else
2016-03-04 23:04:53 +00:00
Log . report ( logvisor : : Fatal , _S ( " Unable to find type 0x%X in object database " ) , ( atUint32 ) type ) ;
2015-09-10 20:30:35 +00:00
}
}
2016-03-04 23:04:53 +00:00
void SCLY : : ScriptLayer : : read ( athena : : io : : YAMLDocReader & rs )
2015-09-10 20:30:35 +00:00
{
unknown = rs . readUByte ( " unknown " ) ;
2016-03-04 01:01:37 +00:00
size_t objCount ;
objects . clear ( ) ;
if ( rs . enterSubVector ( " objects " , objCount ) )
2015-09-10 20:30:35 +00:00
{
2016-03-04 01:01:37 +00:00
objectCount = objCount ;
objects . reserve ( objCount ) ;
for ( atUint32 i = 0 ; i < objectCount ; i + + )
2015-09-10 20:30:35 +00:00
{
2016-03-04 01:01:37 +00:00
rs . enterSubRecord ( nullptr ) ;
atUint8 type = rs . readUByte ( " type " ) ;
auto iter = std : : find_if ( SCRIPT_OBJECT_DB . begin ( ) , SCRIPT_OBJECT_DB . end ( ) , [ & type ] ( const ScriptObjectSpec * obj ) - > bool
{ return obj - > type = = type ; } ) ;
if ( iter ! = SCRIPT_OBJECT_DB . end ( ) )
{
std : : unique_ptr < IScriptObject > obj ( ( * iter ) - > a ( ) ) ;
obj - > read ( rs ) ;
obj - > type = type ;
objects . push_back ( std : : move ( obj ) ) ;
}
else
2016-03-05 00:03:41 +00:00
Log . report ( logvisor : : Fatal , _S ( " Unable to find type 0x%X in object database " ) , ( atUint32 ) type ) ;
2016-03-04 01:01:37 +00:00
rs . leaveSubRecord ( ) ;
2015-09-10 20:30:35 +00:00
}
2016-03-04 01:01:37 +00:00
rs . leaveSubVector ( ) ;
2015-09-10 20:30:35 +00:00
}
2016-03-04 01:01:37 +00:00
else
objectCount = 0 ;
2015-09-10 20:30:35 +00:00
}
2016-03-04 23:04:53 +00:00
void SCLY : : ScriptLayer : : write ( athena : : io : : IStreamWriter & ws ) const
2015-09-10 20:30:35 +00:00
{
ws . writeUByte ( unknown ) ;
ws . writeUint32Big ( objectCount ) ;
2015-11-29 05:59:34 +00:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
2015-09-10 20:30:35 +00:00
{
ws . writeByte ( obj - > type ) ;
2016-08-13 01:23:27 +00:00
atUint32 expLen = obj - > binarySize ( 0 ) ;
ws . writeUint32Big ( expLen ) ;
auto start = ws . position ( ) ;
2015-09-10 20:30:35 +00:00
obj - > write ( ws ) ;
2016-08-13 01:23:27 +00:00
auto wrote = ws . position ( ) - start ;
if ( wrote ! = expLen )
Log . report ( logvisor : : Error , " expected writing %lu byte SCLY obj; wrote %llu " , expLen , wrote ) ;
2015-09-10 20:30:35 +00:00
}
}
2015-10-18 04:08:45 +00:00
size_t SCLY : : ScriptLayer : : binarySize ( size_t __isz ) const
{
__isz + = 5 ;
2015-11-29 05:59:34 +00:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
2015-10-18 04:08:45 +00:00
{
2016-08-13 01:23:27 +00:00
__isz + = 5 ;
2015-10-18 04:08:45 +00:00
__isz = obj - > binarySize ( __isz ) ;
}
return __isz ;
}
2016-03-04 23:04:53 +00:00
void SCLY : : ScriptLayer : : write ( athena : : io : : YAMLDocWriter & ws ) const
2015-09-10 20:30:35 +00:00
{
ws . writeUByte ( " unknown " , unknown ) ;
ws . enterSubVector ( " objects " ) ;
2015-11-29 05:59:34 +00:00
for ( const std : : unique_ptr < IScriptObject > & obj : objects )
2015-09-10 20:30:35 +00:00
{
ws . enterSubRecord ( nullptr ) ;
ws . writeUByte ( " type " , obj - > type ) ;
2016-01-04 05:31:02 +00:00
obj - > write ( ws ) ;
2015-09-10 20:30:35 +00:00
ws . leaveSubRecord ( ) ;
} ;
ws . leaveSubVector ( ) ;
}
2015-10-01 00:46:37 +00:00
const char * SCLY : : ScriptLayer : : DNAType ( )
{
2016-03-04 23:04:53 +00:00
return " urde::DNAMP1::SCLY::ScriptLayer " ;
2015-10-01 00:46:37 +00:00
}
2015-09-10 20:30:35 +00:00
}
}