# # # Author:: Mark Harrison-Ball # Date:: 15 September 2013 (AP3) # Purpose: # ~ Generic object to store Concat Info # Parses the concat file using the pargen parsers # path = File.expand_path $0 path = File.dirname(path) require "#{path}/../../Global/cutscene/shotInfo" CUTSCENEPART = 'RexRageCutscenePart' # This is our base Cutinfo file class CutFile attr_reader :name attr_reader :path attr_reader :relativePath attr_reader :duration attr_reader :frames attr_reader :shots attr_reader :isValid attr_reader :isConcat attr_reader :audio attr_reader :sectionTimeDuration attr_reader :sectionMethodIndex attr_reader :missionStrand attr_writer :missionStrand def initialize(filePath, metadataUtils, log=nil) dir, base = File.split(filePath) @name = File.basename(dir).upcase # name extracted from the filename @path = filePath @isValid = true @isConcat = false @duration = 0 @frames = 0 @shots = [] #store part list definitions @missionStrand = '' @errorMsg = '' # error log capture @audio = '' @sectionTimeDuration = 0 @sectionMethodIndex = 0 parse(filePath, metadataUtils, log) end def parse(filePath, metadataUtils, log) begin readCutMetafile(filePath, metadataUtils, log) @duration = (@frames/30.0) rescue => e @errorMsg = e.to_s.gsub("'"," ") if log log.error(@errorMsg) end end end private # Wrapper to make sure we return something if value not found def returnMetaValue(metadataUtils, key) result = nil prop = metadataUtils.FindFirstStructureNamed( @@concatDef, key ) if prop result = prop.value end result end # Lets parse our metafile def readCutMetafile(filePath, metadataUtils, log) @@concatDef = metadataUtils.ParseMetaFile( filePath ) # Functionality for a Datacut cutParts = metadataUtils.FindFirstStructureNamed( @@concatDef, "concatDataList" ) if cutParts.class == ARRAY_TUNABLE cutParts.each do | ent | if ent.class == STRUCT_TUNABLE ent.each do | partInfo | # Might need a better check for class type here if partInfo.key == 'cSceneName' _shotInfo_ = ShotInfo.new() _shotInfo_.shotName = partInfo.value.value _shotInfo_.shotPath = File.join(File.dirname(filePath),"#{partInfo.value.value}.cutxml") _shotInfo_.parse(metadataUtils, log) @frames += _shotInfo_.frames @shots.push(_shotInfo_) end end end end end end end # A concat has additional information if we read a concat file class ConcatFile < CutFile #alias_method :other_initialize, :initialize def initialize( filePath, metadataUtils, log=nil ) super( filePath, metadataUtils ) @isConcat = true init( filePath, metadataUtils ) end def init( filePath, metadataUtils ) readMetafile( filePath, metadataUtils ) @duration = (@frames/30.0) end private def readMetafile( filePath, metadataUtils ) @path = returnMetaValue(metadataUtils, "path").to_s # Absolute path @name = File.basename(@path).upcase @audio = returnMetaValue(metadataUtils, "audio" ).to_s @sectionTimeDuration = returnMetaValue(metadataUtils, "sectionTimeDuration" ).to_i @sectionMethodIndex = returnMetaValue(metadataUtils, "sectionMethodIndex" ).to_i # Functionality for a concat cutParts = metadataUtils.FindFirstStructureNamed( @@concatDef, "parts" ) if cutParts.class == ARRAY_TUNABLE cutParts.each do | ent | if ent.class == POINTER_TUNABLE if ent.value.name = CUTSCENEPART # define a new ShotInfo here _shotInfo_ = ShotInfo.new() ent.value.each do | partInfo | # Read Shot Name if partInfo.key == 'name' if partInfo.value.class == STRING_TUNABLE _shotInfo_.shotName = partInfo.value.value end # Read Shot file Path elsif partInfo.key == 'filename' if partInfo.value.class == STRING_TUNABLE _shotInfo_.shotPath = partInfo.value.value end end end # if we can't find a shot then the cutscene is invalid if not File.exists?(_shotInfo_.shotPath) puts "File Path not exists #{_shotInfo_.shotPath}" @isValid = false break end _shotInfo_.parse(metadataUtils) # put in own function, need to sort out duration correctly... mmmm @frames += _shotInfo_.frames # Add our Shot Info @shots.push(_shotInfo_) end end end end end end