# # File:: %RS_TOOLSROOT%/script/misc/data_mk_scaleform_rpf.rb # Description:: Make a scaleform ZIP file. It looks through the directory # art/UI/Swf and all of it's sub directories, and upon finding a # gfx file it searches for any DDS files located in the same # # Author:: David Evans # Author:: David Muir # Date:: 26 August 2010 (rewritten: 31 March 2011) # # The refactor on 31 March 2011 makes this script far more generic with the # new way the assets are layed out. There are no hard-coded paths here. # #----------------------------------------------------------------------------- # Uses #----------------------------------------------------------------------------- require 'pipeline/config/projects' require 'pipeline/config/project' require 'pipeline/os/file' require 'pipeline/os/getopt' require 'pipeline/os/path' require 'pipeline/util/environment' require 'pipeline/projectutil/data_convert' require 'pipeline/projectutil/data_texture' require 'pipeline/projectutil/data_zip' require 'pipeline/scm/perforce' include Pipeline include Pipeline::ProjectUtil #---------------------------------------------------------------------------- # Constants #---------------------------------------------------------------------------- OPTIONS = [ [ '--convert', '-c', OS::Getopt::BOOLEAN, 'specify if you want the output file to run through a platform converstion locally'], [ '--debug', '-d', OS::Getopt::BOOLEAN, 'display debug information.' ] ] EXPORT_GFX = '$(toolsbin)/SwfToGfx/gfxexport.exe' #EXPORT_GFX_ARGS = '-i DDS -qp -sd -rescale nearest -gradients -gi DDS' EXPORT_GFX_ARGS = '-i DDS -d0 -fc -fcm -sd -rescale nearest -gradients -gi DDS' ROOT_SWF = '$(root)/UI/NG/Swf' ROOT_GFX = '$(root)/UI/NG/Gfx' ROOT_EXPORT = '$(export)/data/cdimages' CL_DESCRIPTION = 'Automatic gfx export script for Next Gen' # List of SWF files that we do NOT want an ITD produced (probably because they # are produced in a different way, e.g. fonts). NO_TEXTURE_PACKING = [ 'gfxfontlib', 'font_lib_efigs', 'font_lib_korean', 'font_lib_japanese', 'font_lib_chinese', 'startup', 'pause_menu_pages_settings', 'pause_menu_store_content', 'introscrn', 'tattoo_buttons', 'yoga_buttons' ] # List of additional files to be packed into the generic zip file. ADDITIONAL_GENERIC_FILES = [ OS::Path::combine( ROOT_SWF, 'generic/ADDITIONAL_ITD/*.itd.zip' ) ] #---------------------------------------------------------------------------- # Functions #---------------------------------------------------------------------------- # Process a single SWF file. def process_swf( p4, cl, r, e, log, gfx_dir, swf_file ) log.info( "\tProcessing SWF: #{swf_file}..." ) swf_name = OS::Path::get_basename( swf_file ) gfx_texture_dir = gfx_dir FileUtils::mkdir_p( gfx_dir ) \ unless ( File::directory?( gfx_dir ) ) FileUtils::mkdir_p( gfx_texture_74dir ) \ unless ( File::directory?( gfx_texture_dir ) ) component_name = OS::Path::get_basename( swf_file ) gfx_filename = OS::Path::combine( gfx_dir, "#{component_name}.gfx" ) itd_filename = OS::Path::combine( gfx_dir, "#{component_name}.itd.zip" ) # Export GFX and DDS files from SWF. p4.run_edit( gfx_filename ) if ( File::exists?( gfx_filename ) ) p4.run_edit( itd_filename ) if ( File::exists?( itd_filename ) ) command = e.subst( "#{EXPORT_GFX} -o #{gfx_dir} -d #{gfx_texture_dir} #{EXPORT_GFX_ARGS} #{swf_file}" ) log.debug( command ) system( command ) p4.run_add( gfx_filename ) if ( File::exists?( gfx_filename ) ) p4.run_add( itd_filename ) if ( File::exists?( itd_filename ) ) p4.run_reopen( '-c', cl.to_s, gfx_filename ) if ( File::exists?( gfx_filename ) ) p4.run_reopen( '-c', cl.to_s, itd_filename ) if ( File::exists?( itd_filename ) ) # Package up TXD (if required). textures = OS::FindEx::find_files( OS::Path::combine( gfx_texture_dir, swf_name, '*.dds' ) ) if ( ( textures.size > 0 ) and ( not NO_TEXTURE_PACKING.include?( swf_name ) ) ) then itd_filename = OS::Path::combine( gfx_dir, swf_name + '.itd.zip' ) file_list = [] textures.each do |texture| filename = OS::Path::get_filename( texture ) filepath = OS::Path::get_directory( texture ) entry = {} entry[:src] = texture entry[:dst] = filename file_list << entry tcs_file = make_sure_scaleform_tcs_exists( p4, cl, texture ) tcl_file = make_sure_scaleform_tcl_exists( p4, cl, texture ) tcl_filename = OS::Path::get_filename( tcl_file ) tcl_entry = {} tcl_entry[:src] = tcl_file tcl_entry[:dst] = tcl_filename file_list << tcl_entry end ProjectUtil::data_zip_create( itd_filename, file_list, false ) end end def make_sure_scaleform_tcl_exists( p4, changelist, texture ) c = Pipeline::Config.instance( ) assets = c.project.assets tcl_file = OS::Path.remove_extension( texture ) tcs_file = tcl_file tcl_file.gsub!( c.project.root, "" ) tcs_file.gsub!( c.project.root, "" ) tcl_file = OS::Path::combine( assets, 'metadata/textures', tcl_file) + ".tcl" p4.run_sync( tcl_file ) if (not File::exists?( tcl_file ) ) then tcs_dir = OS::Path::get_directory( tcl_file ) FileUtils::mkdir_p( tcs_dir ) \ unless ( File::directory?( tcs_dir ) ) File.open( tcl_file, 'w+' ) do |file| file.write("\n") file.write("\n") file.write("${RS_ASSETS}/metadata/textures#{tcs_file}\n") # file.write("#{texture}\n") file.write("\n") end end tcl_file end # # == Description # Create an compressed texture pipeline TCS file for a specific texture. # The location for the TCS file is under $(assets)/metadata/textures # relative to the location in $(art). # def make_sure_scaleform_tcs_exists( p4, changelist, texture ) c = Pipeline::Config.instance( ) assets = c.project.assets tcs_file = OS::Path.remove_extension( texture ) tcs_file.gsub!( c.project.root, "" ) tcs_file = OS::Path::combine( assets, 'metadata/textures', tcs_file) + ".tcs" p4.run_sync( tcs_file ) if (not File::exists?( tcs_file ) ) then tcs_dir = OS::Path::get_directory( tcs_file ) FileUtils::mkdir_p( tcs_dir ) \ unless ( File::directory?( tcs_dir ) ) is_gradient = File::fnmatch?( "*_g*.tcs", tcs_file ) File.open( tcs_file, 'w+' ) do |file| file.write("\n") file.write("\n") file.write("${RS_ASSETS}/metadata/textures/templates/ui/UI_Default\n") unless ( is_gradient ) file.write("${RS_ASSETS}/metadata/textures/templates/ui/UI_Gradient\n") if ( is_gradient ) # file.write("#{texture}\n") file.write("\n") end end p4.run_edit_or_add( tcs_file ) p4.run_reopen( '-c', changelist, tcs_file ) tcs_file end # Process a single zip file. def process_zip( p4, cl, r, e, log, zip_dir, zip_file, zip_input_files, is_generic = false, is_platform = false ) log.info( "Checking out #{zip_file}..." ) p4.run_edit( zip_file ) log.info( "Creating #{zip_file}..." ) file_list = [] zip_input_files.each do |export_file| entry = {} entry[:src] = export_file entry[:dst] = OS::Path::get_filename( export_file ) file_list << entry end if ( is_generic ) then ADDITIONAL_GENERIC_FILES.each do |dependency_file| dependency_input = e.subst( dependency_file ) if ( ::File::file?( dependency_input ) ) then entry = {} entry[:src] = dependency_input entry[:dst] = OS::Path::get_filename( dependency_input ) file_list << entry else # Assume its a directory with wildcard. files = OS::FindEx::find_files( dependency_input ) files.each do |filename| filename_input = e.subst( filename ) entry = {} entry[:src] = filename_input entry[:dst] = OS::Path::get_filename( filename_input ) file_list << entry end end end else additional_itd_dir = OS::Path::combine( zip_dir, "ADDITIONAL_ITD" ) if ( ::File::directory?( additional_itd_dir ) ) then # Assume its a directory with wildcard. files = OS::FindEx::find_files( additional_itd_dir + "/*.itd.zip" ) files.each do |filename| filename_input = e.subst( filename ) entry = {} entry[:src] = filename_input entry[:dst] = OS::Path::get_filename( filename_input ) file_list << entry end end end ProjectUtil::data_zip_create( zip_file, file_list, true ) p4.run_add( zip_file ) log.info( "Moving #{zip_file} to Perforce CL ##{cl}..." ) p4.run_reopen( '-c', cl.to_s, zip_file ) end #---------------------------------------------------------------------------- # Entry-Point #---------------------------------------------------------------------------- if ( __FILE__ == $0 ) then begin g_AppName = OS::Path::get_basename( __FILE__ ) g_Config = Pipeline::Config.instance( ) g_Log = Log.new( g_AppName ) g_Debug = false g_Project = g_Config.project g_Project.load_config( ) #-------------------------------------------------------------------- # Parse Command Line #-------------------------------------------------------------------- g_Options, g_Trailing = OS::Getopt::getopts( OPTIONS ) g_Debug = g_Options['debug'].nil? ? false : true g_Convert = g_Options['convert'].nil? ? false : true #-------------------------------------------------------------------- # Create the RAGE utility #-------------------------------------------------------------------- r = RageUtils.new( g_Project, nil ) #-------------------------------------------------------------------- # Preforce creation and setup #-------------------------------------------------------------------- Dir::chdir( g_Project.root ) g_Perforce = Pipeline::SCM::Perforce.new( ) g_Perforce.connect( ) g_ChangelistNumber = g_Perforce.create_changelist( CL_DESCRIPTION ) g_Log.info( "Changelist Number: #{g_ChangelistNumber}" ) if ( g_Trailing.size() > 0 ) then #---------------------------------------------------------------- # Passed in a directory under SWF Root. #---------------------------------------------------------------- g_Project.in_env( ) do |e| swf_root = e.subst( OS::Path::normalise( ROOT_SWF ) ) gfx_root = e.subst( OS::Path::normalise( ROOT_GFX ) ) FileUtils::mkdir_p( gfx_root ) unless ( File::directory?( gfx_root ) ) # Fetch list of all resultant zip files to determine where this # one is going; after initial processing. zip_dirs = OS::FindEx::find_dirs( swf_root ) g_Trailing.each do |swf_file| if ( File::file?( swf_file ) ) then g_Log.info( "Processing SWF file: #{swf_file}..." ) zip_dir = OS::Path::get_directory( OS::Path::get_directory( swf_file ) ) gfx_dir = zip_dir.sub( swf_root, gfx_root ) process_swf( g_Perforce, g_ChangelistNumber, r, e, g_Log, gfx_dir, swf_file ) elsif ( File::directory?( swf_file ) ) g_Log.info( "Processing Scaleform ZIP #{swf_file}..." ) swf_file = OS::Path::normalise( swf_file ) gfx_dir = swf_file.sub( swf_root, gfx_root ) swf_files = OS::FindEx::find_files_recurse( OS::Path::combine( swf_file, '*.swf' ) ) swf_files.each do |swf_f| process_swf( g_Perforce, g_ChangelistNumber, r, e, g_Log, gfx_dir, swf_f ) end end end # Re-process the reconstructed SWF files by packing up the zips # again from all of the local content. g_Trailing.each do |swf_file| export_zip = '' if ( File::file?( swf_file ) ) zip_dir = OS::Path::get_directory( OS::Path::get_directory( swf_file ) ) gfx_dir = zip_dir.sub( swf_root, gfx_root ) export_zip = OS::Path::combine( ROOT_EXPORT, 'scaleform_' + OS::Path::get_filename( zip_dir ) + '.zip' ) export_zip = e.subst( export_zip ) export_files = OS::FindEx::find_files( OS::Path::combine( gfx_dir, '*.*' ) ) is_generic = ( 0 == "generic".casecmp( OS::Path::get_filename( zip_dir ) ) ) is_platform = ( OS::Path::get_filename( zip_dir ).starts_with( "platform" ) ) process_zip( g_Perforce, g_ChangelistNumber, r, e, g_Log, zip_dir, export_zip, export_files, is_generic, is_platform ) elsif ( File::directory?( swf_file ) ) swf_file = OS::Path::normalise( swf_file ) zip_dir = swf_file gfx_dir = swf_file.sub( swf_root, gfx_root ) export_zip = OS::Path::combine( ROOT_EXPORT, 'scaleform_' + OS::Path::get_filename( zip_dir ) + '.zip' ) export_zip = e.subst( export_zip ) export_files = OS::FindEx::find_files( OS::Path::combine( gfx_dir, '*.*' ) ) is_generic = ( 0 == "generic".casecmp( OS::Path::get_filename( zip_dir ) ) ) is_platform = ( OS::Path::get_filename( zip_dir ).starts_with( "platform" ) ) process_zip( g_Perforce, g_ChangelistNumber, r, e, g_Log, zip_dir, export_zip, export_files, is_generic, is_platform ) end #--------------------------------------------------------------------- # Do a platform conversation if required #--------------------------------------------------------------------- if ( g_Convert ) ProjectUtil::data_convert_file( export_zip, true ) end end end else #---------------------------------------------------------------- # Loop through Swf paths; creating intermediate Gfx data. #---------------------------------------------------------------- g_Project.in_env( ) do |e| swf_root = e.subst( OS::Path::normalise( ROOT_SWF ) ) gfx_root = e.subst( OS::Path::normalise( ROOT_GFX ) ) FileUtils::mkdir_p( gfx_root ) unless ( File::directory?( gfx_root ) ) zip_dirs = OS::FindEx::find_dirs( swf_root ) zip_dirs.each do |zip_dir| gfx_dir = zip_dir.sub( swf_root, gfx_root ) zip_swf_dirs = OS::FindEx::find_dirs( zip_dir ) zip_swf_dirs.each do |swf_dir| g_Log.info( "Processing Scaleform ZIP #{OS::Path::get_directory( swf_dir )}..." ) swf_files = OS::FindEx::find_files( OS::Path::combine( swf_dir, '*.swf' ) ) swf_files.each do |swf_file| process_swf( g_Perforce, g_ChangelistNumber, r, e, g_Log, gfx_dir, swf_file ) end end # Create resultant Scaleform ZIP file. export_zip = OS::Path::combine( ROOT_EXPORT, 'scaleform_' + OS::Path::get_filename( zip_dir ) + '.zip' ) export_zip = e.subst( export_zip ) export_files = OS::FindEx::find_files( OS::Path::combine( gfx_dir, '*.*' ) ) is_generic = ( 0 == "generic".casecmp( OS::Path::get_filename( zip_dir ) ) ) is_platform = ( OS::Path::get_filename( zip_dir ).starts_with( "platform" ) ) process_zip(g_Perforce, g_ChangelistNumber, r, e, g_Log, zip_dir, export_zip, export_files, is_generic, is_platform ) end end end # Revert unchanged files. g_Perforce.run_revert( '-a', '-c', g_ChangelistNumber.to_s ) # Clean up all automatically constructed changelists if they are empty. pending_list = g_Perforce.run_changes( '-l', '-s', 'pending', '-u', g_Perforce.user, '-c', g_Perforce.client ) description_list = [] pending_list.each do |changelist| next unless ( 0 == CL_DESCRIPTION.strip.casecmp( changelist['desc'].strip ) ) g_Perforce.run_change( '-d', changelist['change'] ) g_Log.info( "\nDeleting changelist #{changelist['change']} from pending list" ) end g_Perforce.disconnect( ) rescue Exception => ex puts "Unhandled exception: #{ex.message}" puts ex.backtrace().join("\n") end end # %RS_TOOLSROOT%/script/misc/data_mk_scaleform_rpf.rb